Video Mixer

This works as an 8 channels video mixer. 

You can add a viewport texture to each channel, assign a blend mode and a mix value to get a video mixer effect.

 

 

Shader code
shader_type canvas_item;

uniform bool force_srgb = false;

uniform vec4 bg_color: source_color;

uniform bool use_screen_texture = false;

uniform sampler2D SCREEN_TEXTURE: hint_screen_texture, filter_linear_mipmap;

uniform bool source_a_enabled = false;
uniform sampler2D source_a: source_color, hint_default_black;
uniform float source_a_mix_value: hint_range(0, 1) = 0.0;
uniform int source_a_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_b_enabled = false;
uniform sampler2D source_b: source_color, hint_default_black;
uniform float source_b_mix_value: hint_range(0, 1) = 0.0;
uniform int source_b_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_c_enabled = false;
uniform sampler2D source_c: source_color, hint_default_black;
uniform float source_c_mix_value: hint_range(0, 1) = 0.0;
uniform int source_c_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_d_enabled = false;
uniform sampler2D source_d: source_color, hint_default_black;
uniform float source_d_mix_value: hint_range(0, 1) = 0.0;
uniform int source_d_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_e_enabled = false;
uniform sampler2D source_e: source_color, hint_default_black;
uniform float source_e_mix_value: hint_range(0, 1) = 0.0;
uniform int source_e_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_f_enabled = false;
uniform sampler2D source_f: source_color, hint_default_black;
uniform float source_f_mix_value: hint_range(0, 1) = 0.0;
uniform int source_f_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_g_enabled = false;
uniform sampler2D source_g: source_color, hint_default_black;
uniform float source_g_mix_value: hint_range(0, 1) = 0.0;
uniform int source_g_blend_mode: hint_range(0, 13, 1) = 0;

uniform bool source_h_enabled = false;
uniform sampler2D source_h: source_color, hint_default_black;
uniform float source_h_mix_value: hint_range(0, 1) = 0.0;
uniform int source_h_blend_mode: hint_range(0, 13, 1) = 0;

vec4 multiply(vec4 base, vec4 blend){
	return base * blend;
}

vec4 screen( vec4 base, vec4 blend ){
	return 1.0 - (1.0 - base) * (1.0 - blend);
}

vec4 darken(vec4 base, vec4 blend){
	return min(base, blend);
}

vec4 lighten(vec4 base, vec4 blend){
	return max(base, blend);
}

vec4 difference(vec4 base, vec4 blend){
	return abs(base - blend);
}

vec4 exclusion(vec4 base, vec4 blend){
	return base + blend - 2.0 * base * blend;
}

vec4 overlay(vec4 base, vec4 blend){
	vec4 limit = step(0.5, base);
	return mix(2.0 * base * blend, 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), limit);
}

vec4 hard_light(vec4 base, vec4 blend){
	vec4 limit = step(0.5, blend);
	return mix(2.0 * base * blend, 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), limit);
}

vec4 soft_light(vec4 base, vec4 blend){
	vec4 limit = step(0.5, blend);
	return mix(2.0 * base * blend + base * base * (1.0 - 2.0 * blend), sqrt(base) * (2.0 * blend - 1.0) + (2.0 * base) * (1.0 - blend), limit);
}

vec4 color_dodge(vec4 base, vec4 blend){
	return base / (1.0 - blend);
}

vec4 linear_dodge(vec4 base, vec4 blend){
	return base + blend;
}

vec4 color_burn(vec4 base, vec4 blend){
	return 1.0 - (1.0 - base) / blend;
}

vec4 linear_burn (vec4 base, vec4 blend){
	return base + blend - 1.0;
}

vec4 mixer(vec4 base, vec4 blend, int blend_mode, float intensity){
	blend_mode = blend_mode - 1;
	switch (blend_mode) {
		case -1:
			base.rgb = mix( base, blend, intensity ).rgb;
			return base;
		case 0:
			base.rgb = mix( base, multiply(base, blend), intensity ).rgb;
			return base;
		case 1:
			base.rgb = mix( base, screen(base, blend), intensity ).rgb;
			return base;
		case 2:
			base.rgb = mix( base, darken(base, blend), intensity ).rgb;
			return base;
		case 3:
			base.rgb = mix( base, lighten(base, blend), intensity ).rgb;
			return base;
		case 4:
			base.rgb = mix( base, difference(base, blend), intensity ).rgb;
			return base;
		case 5:
			base.rgb = mix( base, exclusion(base, blend), intensity ).rgb;
			return base;
		case 6:
			base.rgb = mix( base, overlay(base, blend), intensity ).rgb;
			return base;
		case 7:
			base.rgb = mix( base, hard_light(base, blend), intensity ).rgb;
			return base;
		case 8:
			base.rgb = mix( base, soft_light(base, blend), intensity ).rgb;
			return base;
		case 9:
			base.rgb = mix( base, color_dodge(base, blend), intensity ).rgb;
			return base;
		case 10:
			base.rgb = mix( base, linear_dodge(base, blend), intensity ).rgb;
			return base;
		case 11:
			base.rgb = mix( base, color_burn(base, blend), intensity ).rgb;
			return base;
		case 12:
			base.rgb = mix( base, linear_burn(base, blend), intensity ).rgb;
			return base;
	}
}

void fragment()
{
	if (use_screen_texture == true) {
		COLOR = texture(SCREEN_TEXTURE, SCREEN_UV);
	} else {
		COLOR = bg_color;
	}

	//COLOR = bg_color;

	if ((source_a_mix_value > 0.0) && (source_a_enabled)) {
		vec4 mix_1 = texture( source_a, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_a_blend_mode, source_a_mix_value);
	}

	if ((source_b_mix_value > 0.0) && (source_b_enabled)) {
		vec4 mix_1 = texture( source_b, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_b_blend_mode, source_b_mix_value);
	}

	if ((source_c_mix_value > 0.0) && (source_c_enabled)) {
		vec4 mix_1 = texture( source_c, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_c_blend_mode, source_c_mix_value);
	}

	if ((source_d_mix_value > 0.0) && (source_d_enabled)) {
		vec4 mix_1 = texture( source_d, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_d_blend_mode, source_d_mix_value);
	}

	if ((source_e_mix_value > 0.0) && (source_e_enabled)) {
		vec4 mix_1 = texture( source_e, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_e_blend_mode, source_e_mix_value);
	}

	if ((source_f_mix_value > 0.0) && (source_f_enabled)) {
		vec4 mix_1 = texture( source_f, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_f_blend_mode, source_f_mix_value);
	}

	if ((source_g_mix_value > 0.0) && (source_g_enabled)) {
		vec4 mix_1 = texture( source_g, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_g_blend_mode, source_g_mix_value);
	}

	if ((source_h_mix_value > 0.0) && (source_h_enabled)) {
		vec4 mix_1 = texture( source_h, SCREEN_UV );
		COLOR = mixer(COLOR, mix_1, source_h_blend_mode, source_h_mix_value);
	}

	if (force_srgb == true) {
		COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),COLOR.rgb.rgb * (1.0 / 12.92),lessThan(COLOR.rgb,vec3(0.04045)));
	}
}
Live Preview
Tags
blend, blend modes, mixer
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from asturnazari

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments