mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-11 06:15:05 +00:00
filter-transform: Fix discoloration issue
Previously a wrong blend state caused a slight discoloration on transparent sources, which was caused by assuming them to always be fully solid without transparency. By instead relying on OBS to do the rendering we do not have to deal with blend states as much and instead can simply enjoy the result. Fixes #104
This commit is contained in:
parent
f79846aa3b
commit
0b3ce10aff
1 changed files with 32 additions and 17 deletions
|
@ -265,14 +265,15 @@ void transform::transform_instance::video_tick(float)
|
|||
_source_rendered = false;
|
||||
}
|
||||
|
||||
void transform::transform_instance::video_render(gs_effect_t*)
|
||||
void transform::transform_instance::video_render(gs_effect_t* effect)
|
||||
{
|
||||
obs_source_t* parent = obs_filter_get_parent(_self);
|
||||
obs_source_t* target = obs_filter_get_target(_self);
|
||||
uint32_t base_width = obs_source_get_base_width(target);
|
||||
uint32_t base_height = obs_source_get_base_height(target);
|
||||
gs_effect_t* default_effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
|
||||
gs_effect_t* effect = default_effect;
|
||||
if (!effect)
|
||||
effect = default_effect;
|
||||
|
||||
if (!base_width || !base_height || !parent || !target) { // Skip if something is wrong.
|
||||
obs_source_skip_video_filter(_self);
|
||||
|
@ -306,22 +307,26 @@ void transform::transform_instance::video_render(gs_effect_t*)
|
|||
gs::debug_marker _marker_cache{gs::debug_color_cache, "Cache"};
|
||||
auto op = _cache_rt->render(cache_width, cache_height);
|
||||
|
||||
gs_reset_blend_state();
|
||||
gs_blend_function(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA);
|
||||
gs_enable_depth_test(false);
|
||||
gs_enable_stencil_test(false);
|
||||
gs_enable_stencil_write(false);
|
||||
gs_enable_color(true, true, true, true);
|
||||
gs_set_cull_mode(GS_NEITHER);
|
||||
|
||||
gs_ortho(0, static_cast<float_t>(base_width), 0, static_cast<float_t>(base_height), -1, 1);
|
||||
|
||||
vec4 clear_color = {0};
|
||||
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &clear_color, 0, 0);
|
||||
|
||||
/// Render original source
|
||||
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
obs_source_process_filter_end(_self, effect, base_width, base_height);
|
||||
if (obs_source_process_filter_begin(_self, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
|
||||
gs_blend_state_push();
|
||||
gs_reset_blend_state();
|
||||
gs_enable_blending(false);
|
||||
gs_blend_function_separate(GS_BLEND_ONE, GS_BLEND_ZERO, GS_BLEND_SRCALPHA, GS_BLEND_ZERO);
|
||||
gs_enable_depth_test(false);
|
||||
gs_enable_stencil_test(false);
|
||||
gs_enable_stencil_write(false);
|
||||
gs_enable_color(true, true, true, true);
|
||||
gs_set_cull_mode(GS_NEITHER);
|
||||
|
||||
obs_source_process_filter_end(_self, default_effect, base_width, base_height);
|
||||
|
||||
gs_blend_state_pop();
|
||||
} else {
|
||||
obs_source_skip_video_filter(_self);
|
||||
return;
|
||||
|
@ -361,7 +366,17 @@ void transform::transform_instance::video_render(gs_effect_t*)
|
|||
gs::debug_marker _marker_draw{gs::debug_color_cache_render, "Geometry"};
|
||||
auto op = _source_rt->render(base_width, base_height);
|
||||
|
||||
gs_matrix_push();
|
||||
gs_blend_state_push();
|
||||
gs_reset_blend_state();
|
||||
gs_enable_blending(false);
|
||||
gs_blend_function_separate(GS_BLEND_ONE, GS_BLEND_ZERO, GS_BLEND_ONE, GS_BLEND_ZERO);
|
||||
|
||||
gs_enable_depth_test(false);
|
||||
gs_enable_stencil_test(false);
|
||||
gs_enable_stencil_write(false);
|
||||
gs_enable_color(true, true, true, true);
|
||||
gs_set_cull_mode(GS_NEITHER);
|
||||
|
||||
if (_camera_orthographic) {
|
||||
gs_ortho(-1., 1., -1., 1., -farZ, farZ);
|
||||
} else {
|
||||
|
@ -382,7 +397,7 @@ void transform::transform_instance::video_render(gs_effect_t*)
|
|||
}
|
||||
gs_load_vertexbuffer(nullptr);
|
||||
|
||||
gs_matrix_pop();
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
_source_rt->get_texture(_source_texture);
|
||||
if (!_source_texture) {
|
||||
|
@ -391,9 +406,9 @@ void transform::transform_instance::video_render(gs_effect_t*)
|
|||
}
|
||||
|
||||
{
|
||||
gs::debug_marker _marker_draw{gs::debug_color_cache_render, "Geometry"};
|
||||
gs_effect_set_texture(gs_effect_get_param_by_name(default_effect, "image"), _source_texture->get_object());
|
||||
while (gs_effect_loop(default_effect, "Draw")) {
|
||||
gs::debug_marker _marker_draw{gs::debug_color_cache_render, "Final"};
|
||||
gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), _source_texture->get_object());
|
||||
while (gs_effect_loop(effect, "Draw")) {
|
||||
gs_draw_sprite(nullptr, 0, base_width, base_height);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue