libobs: libobs-d3d11: obs-filters: No excess alpha

Currently SrcBlendAlpha and DestBlendAlpha are both ONE, and can
combine together to form two. This is not a noticeable problem for
UNORM targets because the channels are clamped, but it will likely
become a problem if FLOAT targets are more widely used.

This change switches DestBlendAlpha to INVSRCALPHA, and starts
backgrounds as opaque black instead of transparent black. The blending
behavior of stacked transparents is preserved without overflowing the
alpha channel.
This commit is contained in:
James Park
2019-03-26 21:38:42 -07:00
parent a0ead6f974
commit d91bd327d7
7 changed files with 10 additions and 10 deletions

View File

@@ -659,7 +659,7 @@ struct BlendState {
srcFactorC (GS_BLEND_SRCALPHA),
destFactorC (GS_BLEND_INVSRCALPHA),
srcFactorA (GS_BLEND_ONE),
destFactorA (GS_BLEND_ONE),
destFactorA (GS_BLEND_INVSRCALPHA),
redEnabled (true),
greenEnabled (true),
blueEnabled (true),

View File

@@ -160,12 +160,12 @@ static bool graphics_init(struct graphics_subsystem *graphics)
graphics->exports.device_blend_function_separate(graphics->device,
GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA,
GS_BLEND_ONE, GS_BLEND_ONE);
GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
graphics->cur_blend_state.enabled = true;
graphics->cur_blend_state.src_c = GS_BLEND_SRCALPHA;
graphics->cur_blend_state.dest_c = GS_BLEND_INVSRCALPHA;
graphics->cur_blend_state.src_a = GS_BLEND_ONE;
graphics->cur_blend_state.dest_a = GS_BLEND_ONE;
graphics->cur_blend_state.dest_a = GS_BLEND_INVSRCALPHA;
graphics->exports.device_leave_context(graphics->device);
@@ -1240,10 +1240,10 @@ void gs_reset_blend_state(void)
if (graphics->cur_blend_state.src_c != GS_BLEND_SRCALPHA ||
graphics->cur_blend_state.dest_c != GS_BLEND_INVSRCALPHA ||
graphics->cur_blend_state.src_a != GS_BLEND_ONE ||
graphics->cur_blend_state.dest_a != GS_BLEND_ONE)
graphics->cur_blend_state.dest_a != GS_BLEND_INVSRCALPHA)
gs_blend_function_separate(
GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA,
GS_BLEND_ONE, GS_BLEND_ONE);
GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
}
/* ------------------------------------------------------------------------- */

View File

@@ -524,7 +524,7 @@ static inline void render_item(struct obs_scene_item *item)
float cy_scale = (float)height / (float)cy;
struct vec4 clear_color;
vec4_zero(&clear_color);
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0);
gs_ortho(0.0f, (float)width, 0.0f, (float)height,
-100.0f, 100.0f);

View File

@@ -630,7 +630,7 @@ static inline void render_child(obs_source_t *transition,
return;
if (gs_texrender_begin(transition->transition_texrender[idx], cx, cy)) {
vec4_zero(&blank);
vec4_set(&blank, 0.0f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR, &blank, 0.0f, 0);
gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f);

View File

@@ -3013,7 +3013,7 @@ bool obs_source_process_filter_begin(obs_source_t *filter,
bool async = (parent_flags & OBS_SOURCE_ASYNC) != 0;
struct vec4 clear_color;
vec4_zero(&clear_color);
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0);
gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f);

View File

@@ -122,7 +122,7 @@ static inline void render_main_texture(struct obs_core_video *video,
profile_start(render_main_texture_name);
struct vec4 clear_color;
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f);
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f);
gs_set_render_target(video->render_textures[cur_texture], NULL);
gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0);

View File

@@ -230,7 +230,7 @@ static void gpu_delay_filter_render(void *data, gs_effect_t *effect)
bool async = (parent_flags & OBS_SOURCE_ASYNC) != 0;
struct vec4 clear_color;
vec4_zero(&clear_color);
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f);
gs_clear(GS_CLEAR_COLOR, &clear_color, 0.0f, 0);
gs_ortho(0.0f, (float)f->cx, 0.0f, (float)f->cy,
-100.0f, 100.0f);