obs-studio/plugins/obs-transitions/data/luma_wipe_transition.effect
jpark37 9d7330ca44 obs-transitions: Blend in linear space
Color mismatch is apparent when using source transitions, which lerps
against transparent black and blends into the canvas nonlinearly. When
the transition is done, the blend switches to linear, leading to a pop.

Fix the issue by blending into the canvas in linear space. The lerp is
still nonlinear by design.
2021-05-08 20:53:44 -07:00

75 lines
1.6 KiB
Plaintext

// Based rendermix wipe shader
// https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/Wipe/Wipe.frag
uniform float4x4 ViewProj;
uniform texture2d a_tex;
uniform texture2d b_tex;
uniform texture2d l_tex;
uniform float progress;
uniform bool invert;
uniform float softness;
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;
}
float srgb_nonlinear_to_linear_channel(float u)
{
return (u <= 0.04045) ? (u / 12.92) : pow((u + 0.055) / 1.055, 2.4);
}
float3 srgb_nonlinear_to_linear(float3 v)
{
return float3(srgb_nonlinear_to_linear_channel(v.r), srgb_nonlinear_to_linear_channel(v.g), srgb_nonlinear_to_linear_channel(v.b));
}
float4 PSLumaWipe(VertData v_in) : TARGET
{
float2 uv = v_in.uv;
float4 a_color = a_tex.Sample(textureSampler, uv);
float4 b_color = b_tex.Sample(textureSampler, uv);
float luma = l_tex.Sample(textureSampler, uv).x;
if (invert)
luma = 1.0f - luma;
float time = lerp(0.0f, 1.0f + softness, progress);
float4 rgba;
if (luma <= time - softness) {
rgba = b_color;
} else if (luma >= time) {
rgba = a_color;
} else {
float alpha = (time - luma) / softness;
rgba = lerp(a_color, b_color, alpha);
}
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
return rgba;
}
technique LumaWipe
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSLumaWipe(v_in);
}
}