Browse Source

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.
James Park 6 years ago
parent
commit
d91bd327d7

+ 1 - 1
libobs-d3d11/d3d11-subsystem.hpp

@@ -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),

+ 4 - 4
libobs/graphics/graphics.c

@@ -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);
 }
 
 /* ------------------------------------------------------------------------- */

+ 1 - 1
libobs/obs-scene.c

@@ -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);

+ 1 - 1
libobs/obs-source-transition.c

@@ -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);
 

+ 1 - 1
libobs/obs-source.c

@@ -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);
 

+ 1 - 1
libobs/obs-video.c

@@ -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);

+ 1 - 1
plugins/obs-filters/gpu-delay.c

@@ -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);