Browse Source

obs-transitions: Add 'Fade to Color' transition

Closes jp9000/obs-studio#521
hwdro 9 years ago
parent
commit
262599f0f2

+ 1 - 0
plugins/obs-transitions/CMakeLists.txt

@@ -6,6 +6,7 @@ set(obs-transitions_SOURCES
 	transition-swipe.c
 	transition-fade.c
 	transition-cut.c
+	transition-fade-to-color.c
 	)
 
 add_library(obs-transitions MODULE

+ 37 - 0
plugins/obs-transitions/data/fade_to_color_transition.effect

@@ -0,0 +1,37 @@
+uniform float4x4  ViewProj;
+uniform texture2d tex;
+uniform float     swp;
+uniform float4    color;
+
+sampler_state textureSampler {
+	Filter    = Linear;
+	AddressU  = Clamp;
+	AddressV  = Clamp;
+};
+
+struct VertData {
+	float4 pos : POSITION;
+	float2 uv  : TEXCOORD0;
+};
+
+VertData VSDefault(VertData v_in)
+{
+	VertData vert_out;
+	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
+	vert_out.uv  = v_in.uv;
+	return vert_out;
+}
+
+float4 PSFadeToColor(VertData v_in) : TARGET
+{
+	return lerp(tex.Sample(textureSampler, v_in.uv), color, swp);
+}
+
+technique FadeToColor
+{
+	pass
+	{
+		vertex_shader = VSDefault(v_in);
+		pixel_shader  = PSFadeToColor(v_in);
+	}
+}

+ 3 - 0
plugins/obs-transitions/data/locale/en-US.ini

@@ -2,9 +2,12 @@ FadeTransition="Fade"
 CutTransition="Cut"
 SwipeTransition="Swipe"
 SlideTransition="Slide"
+FadeToColorTransition="Fade to Color"
 Direction="Direction"
 Direction.Left="Left"
 Direction.Right="Right"
 Direction.Up="Up"
 Direction.Down="Down"
 SwipeIn="Swipe In"
+Color="Color"
+SwitchPoint="Peak Color Point (percentage)"

+ 2 - 0
plugins/obs-transitions/obs-transitions.c

@@ -8,6 +8,7 @@ extern struct obs_source_info cut_transition;
 extern struct obs_source_info fade_transition;
 extern struct obs_source_info swipe_transition;
 extern struct obs_source_info slide_transition;
+extern struct obs_source_info fade_to_color_transition;
 
 bool obs_module_load(void)
 {
@@ -15,5 +16,6 @@ bool obs_module_load(void)
 	obs_register_source(&fade_transition);
 	obs_register_source(&swipe_transition);
 	obs_register_source(&slide_transition);
+	obs_register_source(&fade_to_color_transition);
 	return true;
 }

+ 178 - 0
plugins/obs-transitions/transition-fade-to-color.c

@@ -0,0 +1,178 @@
+#include <obs-module.h>
+
+#define S_COLOR "color"
+#define S_SWITCH_POINT "switch_point"
+
+#define S_COLOR_TEXT obs_module_text("Color")
+#define S_SWITCH_POINT_TEXT obs_module_text("SwitchPoint")
+
+struct fade_to_color_info {
+	obs_source_t *source;
+
+	gs_effect_t *effect;
+	gs_eparam_t *ep_tex;
+	gs_eparam_t *ep_swp;
+	gs_eparam_t *ep_color;
+
+	struct vec4 color;
+	float switch_point;
+};
+
+static inline float lerp(float a, float b, float x)
+{
+	return (1.0f - x) * a + x * b;
+}
+
+static inline float clamp(float x, float min, float max)
+{
+	if (x < min)
+		return min;
+	else if (x > max)
+		return max;
+	return x;
+}
+
+static inline float smoothstep(float min, float max, float x)
+{
+	x = clamp((x - min) / (max - min), 0.0f, 1.0f);
+	return x*x*(3 - 2 * x);
+}
+
+static const char *fade_to_color_get_name(void *type_data)
+{
+	UNUSED_PARAMETER(type_data);
+	return obs_module_text("FadeToColorTransition");
+}
+
+static void fade_to_color_update(void *data, obs_data_t *settings)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	uint32_t color = (uint32_t)obs_data_get_int(settings, S_COLOR);
+	uint32_t swp   = (uint32_t)obs_data_get_int(settings, S_SWITCH_POINT);
+
+	color |= 0xFF000000;
+
+	vec4_from_rgba(&fade_to_color->color, color);
+
+	fade_to_color->switch_point = (float)swp / 100.0f;
+}
+
+static void *fade_to_color_create(obs_data_t *settings, obs_source_t *source)
+{
+	struct fade_to_color_info *fade_to_color;
+	char *file = obs_module_file("fade_to_color_transition.effect");
+	gs_effect_t *effect;
+
+	obs_enter_graphics();
+	effect = gs_effect_create_from_file(file, NULL);
+	obs_leave_graphics();
+
+	bfree(file);
+
+	if (!effect) {
+		blog(LOG_ERROR, "Could not find fade_to_color_transition.effect");
+		return NULL;
+	}
+
+	fade_to_color = bzalloc(sizeof(struct fade_to_color_info));
+
+	fade_to_color->source = source;
+	fade_to_color->effect = effect;
+
+	fade_to_color->ep_tex   = gs_effect_get_param_by_name(effect, "tex");
+	fade_to_color->ep_swp   = gs_effect_get_param_by_name(effect, "swp");
+	fade_to_color->ep_color = gs_effect_get_param_by_name(effect, "color");
+
+	obs_source_update(source, settings);
+
+	return fade_to_color;
+}
+
+static void fade_to_color_destroy(void *data)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	bfree(fade_to_color);
+}
+
+static void fade_to_color_callback(void *data, gs_texture_t *a, gs_texture_t *b,
+	float t, uint32_t cx, uint32_t cy)
+{
+	struct fade_to_color_info *fade_to_color = data;
+
+	float sa = smoothstep(0.0f, fade_to_color->switch_point, t);
+	float sb = smoothstep(fade_to_color->switch_point, 1.0f, t);
+
+	float swp = t < fade_to_color->switch_point ? sa : 1.0f - sb;
+
+	gs_effect_set_texture(fade_to_color->ep_tex,
+			      t < fade_to_color->switch_point ? a : b);
+	gs_effect_set_float(fade_to_color->ep_swp, swp);
+	gs_effect_set_vec4(fade_to_color->ep_color, &fade_to_color->color);
+
+	while (gs_effect_loop(fade_to_color->effect, "FadeToColor"))
+		gs_draw_sprite(NULL, 0, cx, cy);
+}
+
+static void fade_to_color_video_render(void *data, gs_effect_t *effect)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	obs_transition_video_render(fade_to_color->source,
+			fade_to_color_callback);
+	UNUSED_PARAMETER(effect);
+}
+
+static float mix_a(void *data, float t)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	float sp = fade_to_color->switch_point;
+
+	return lerp(1.0f - t , 0.0f, smoothstep(0.0f, sp, t));
+}
+
+static float mix_b(void *data, float t)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	float sp = fade_to_color->switch_point;
+
+	return lerp(0.0f, t, smoothstep(sp, 1.0f, t));
+}
+
+static bool fade_to_color_audio_render(void *data, uint64_t *ts_out,
+		struct obs_source_audio_mix *audio, uint32_t mixers,
+		size_t channels, size_t sample_rate)
+{
+	struct fade_to_color_info *fade_to_color = data;
+	return obs_transition_audio_render(fade_to_color->source, ts_out,
+		audio, mixers, channels, sample_rate, mix_a, mix_b);
+}
+
+static obs_properties_t *fade_to_color_properties(void *data)
+{
+	obs_properties_t *props = obs_properties_create();
+
+	obs_properties_add_color(props, S_COLOR, S_COLOR_TEXT);
+	obs_properties_add_int_slider(props, S_SWITCH_POINT,
+		S_SWITCH_POINT_TEXT, 0, 100, 1);
+
+	UNUSED_PARAMETER(data);
+	return props;
+}
+
+static void fade_to_color_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_int(settings, S_COLOR, 0xFF000000);
+	obs_data_set_default_int(settings, S_SWITCH_POINT, 50);
+}
+
+struct obs_source_info fade_to_color_transition = {
+	.id             = "fade_to_color_transition",
+	.type           = OBS_SOURCE_TYPE_TRANSITION,
+	.get_name       = fade_to_color_get_name,
+	.create         = fade_to_color_create,
+	.destroy        = fade_to_color_destroy,
+	.update         = fade_to_color_update,
+	.video_render   = fade_to_color_video_render,
+	.audio_render   = fade_to_color_audio_render,
+	.get_properties = fade_to_color_properties,
+	.get_defaults   = fade_to_color_defaults
+};