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