diff --git a/data/examples/shaders/transition/color-shift.effect b/data/examples/shaders/transition/color-shift.effect new file mode 100644 index 0000000..4b25f1c --- /dev/null +++ b/data/examples/shaders/transition/color-shift.effect @@ -0,0 +1,135 @@ +// Always provided by OBS +uniform float4x4 ViewProj< + bool automatic = true; + string name = "View Projection Matrix"; +>; + +// Provided by Stream Effects +uniform float4 Time< + bool automatic = true; + string name = "Time Array"; + string description = "A float4 value containing the total time, rendering time and the time since the last tick. The last value is a random number between 0 and 1."; +>; +uniform float4x4 Random< + bool automatic = true; + string name = "Random Array"; + string description = "A float4x4 value containing random values between 0 and 1"; +>; +uniform texture2d InputA< + bool automatic = true; +>; +uniform texture2d InputB< + bool automatic = true; +>; +uniform float TransitionTime< + bool automatic = true; +>; +uniform int2 TransitionSize< + bool automatic = true; +>; + +uniform float Sharpness< + string field_type = "slider"; + string suffix = " %"; + float minimum = 8.0; + float maximum = 128.0; + float step = 0.01; + float scale = 1.0; +> = 10.0; + +// ---------- Shader Code +sampler_state def_sampler { + AddressU = Clamp; + AddressV = Clamp; + Filter = Linear; +}; + +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 HSLtoRGB(float4 HSLA) { + float3 rgb = clamp( + abs( + fmod( + HSLA.x * 6.0 + float3(0.0, 4.0, 2.0), + 6.0 + ) - 3.0 + ) - 1.0, + 0.0, + 1.0 + ); + return float4(HSLA.z + HSLA.y * (rgb - 0.5) * (1.0 - abs(2.0 * HSLA.z - 1.0)), HSLA.a); +} + +float4 RGBtoHSL(float4 RGBA) { + float h = 0.0; + float s = 0.0; + float l = 0.0; + float r = RGBA.r; + float g = RGBA.g; + float b = RGBA.b; + float cMin = min( r, min( g, b ) ); + float cMax = max( r, max( g, b ) ); + + l = ( cMax + cMin ) / 2.0; + if ( cMax > cMin ) { + float cDelta = cMax - cMin; + + //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original + s = l < .0 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); + + if ( r == cMax ) { + h = ( g - b ) / cDelta; + } else if ( g == cMax ) { + h = 2.0 + ( b - r ) / cDelta; + } else { + h = 4.0 + ( r - g ) / cDelta; + } + + if ( h < 0.0) { + h += 6.0; + } + h = h / 6.0; + } + return float4( h, s, l, RGBA.a ); +} + +float4 PSDefault(VertData v_in) : TARGET { + float4 sampleA = InputA.Sample(def_sampler, v_in.uv); + float4 sampleB = InputB.Sample(def_sampler, v_in.uv); + + float4 hslA = RGBtoHSL(sampleA); + float4 hslB = RGBtoHSL(sampleB); + float4 hslT = hslB - hslA; + if (hslT.r > 0.5) { + hslB.r = 1.0 + (-1.0 + hslB.r); + } + if (hslT.g > 0.5) { + hslB.g = 1.0 + (-1.0 + hslB.g); + } + if (hslT.b > 0.5) { + hslB.b = 1.0 + (-1.0 + hslB.b); + } + + float4 rgb = HSLtoRGB(lerp(hslA, hslB, TransitionTime)); + + return rgb; +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDefault(v_in); + } +} diff --git a/data/examples/shaders/transition/luma-burn.effect b/data/examples/shaders/transition/luma-burn.effect new file mode 100644 index 0000000..4ce8fdd --- /dev/null +++ b/data/examples/shaders/transition/luma-burn.effect @@ -0,0 +1,99 @@ +// Always provided by OBS +uniform float4x4 ViewProj< + bool automatic = true; + string name = "View Projection Matrix"; +>; + +// Provided by Stream Effects +uniform float4 Time< + bool automatic = true; + string name = "Time Array"; + string description = "A float4 value containing the total time, rendering time and the time since the last tick. The last value is a random number between 0 and 1."; +>; +uniform float4x4 Random< + bool automatic = true; + string name = "Random Array"; + string description = "A float4x4 value containing random values between 0 and 1"; +>; +uniform texture2d InputA< + bool automatic = true; +>; +uniform texture2d InputB< + bool automatic = true; +>; +uniform float TransitionTime< + bool automatic = true; +>; +uniform int2 TransitionSize< + bool automatic = true; +>; + +uniform float Sharpness< + string field_type = "slider"; + string suffix = " %"; + float minimum = 8.0; + float maximum = 128.0; + float step = 0.01; + float scale = 1.0; +> = 10.0; + +// ---------- Shader Code +sampler_state def_sampler { + AddressU = Clamp; + AddressV = Clamp; + Filter = Linear; +}; + +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 RGBtoYUV(float4 rgba, float3x3 yuv) { + return float4( + rgba.r * yuv._m00 + rgba.g * yuv._m01 + rgba.b * yuv._m02, + rgba.r * yuv._m10 + rgba.g * yuv._m11 + rgba.b * yuv._m12, + rgba.r * yuv._m20 + rgba.g * yuv._m21 + rgba.b * yuv._m22, + rgba.a + ) + float4(0,0.5,0.5,0); +} + +float4 PSDefault(VertData v_in) : TARGET { + const float3x3 mYUV709n = { // Normalized + 0.2126, 0.7152, 0.0722, + -0.1145721060573399, -0.3854278939426601, 0.5, + 0.5, -0.4541529083058166, -0.0458470916941834 + }; + + float4 sampleA = InputA.Sample(def_sampler, v_in.uv); + float4 sampleB = InputB.Sample(def_sampler, v_in.uv); + + float4 sampleAYUV = RGBtoYUV(sampleA, mYUV709n); + float4 sampleBYUV = RGBtoYUV(sampleB, mYUV709n); + + float sharpinv = 1.0 / Sharpness; + float transition = sharpinv + sampleAYUV.r * (1.0 - sharpinv); + transition -= TransitionTime; + transition *= Sharpness; + transition += 0.5; + transition = clamp(transition, 0., 1.); + + return sampleB * (1.0 - transition) + sampleA * (transition); + //return transition; +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDefault(v_in); + } +} diff --git a/data/examples/shaders/transition/pixelator.effect b/data/examples/shaders/transition/pixelator.effect new file mode 100644 index 0000000..4ae8b0a --- /dev/null +++ b/data/examples/shaders/transition/pixelator.effect @@ -0,0 +1,119 @@ +// Always provided by OBS +uniform float4x4 ViewProj< + bool automatic = true; + string name = "View Projection Matrix"; +>; + +// Provided by Stream Effects +uniform float4 Time< + bool automatic = true; + string name = "Time Array"; + string description = "A float4 value containing the total time, rendering time and the time since the last tick. The last value is a random number between 0 and 1."; +>; +uniform float4x4 Random< + bool automatic = true; + string name = "Random Array"; + string description = "A float4x4 value containing random values between 0 and 1"; +>; +uniform float4 ViewSize< + bool automatic = true; +>; +uniform texture2d InputA< + bool automatic = true; +>; +uniform texture2d InputB< + bool automatic = true; +>; +uniform float TransitionTime< + bool automatic = true; +>; +uniform int2 TransitionSize< + bool automatic = true; +>; + +uniform bool _0_oldStyle< + string name = "Retro Style"; + +> = false; +uniform float2 _1_pixelateCenter< + string name = "Pixelation Center"; + string field_type = "slider"; + float2 minimum = {0., 0.}; + float2 maximum = {100., 100.}; + float2 scale = {0.01, 0.01}; +> = {50., 50.}; +uniform float _2_maximumBlockSize< + string name = "Maximum Pixelation"; + string field_type = "slider"; + float minimum = 1.0; + float maximum = 16.0; + float step = 1.0; +> = 12.; +uniform float2 _3_blockOffset< + string name = "Block Offset"; + string field_type = "slider"; + float2 minimum = {0., 0.}; + float2 maximum = {100., 100.}; + float2 scale = {0.01, 0.01}; +> = {50., 50.}; + +// ---------- Shader Code +sampler_state def_sampler { + AddressU = Clamp; + AddressV = Clamp; + Filter = Linear; +}; + +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 PSDefault(VertData v_in) : TARGET { + float animProgress = TransitionTime; + + // Progress as a bounce value (0..1..0) + float animStuff = 1.0 - (abs(animProgress - 0.5) * 2.0); + // There are two ways to calculate this, one is pixel aligned the other is block aligned. + float animBlockSize = 0; + if (_0_oldStyle) { + // Block Size, always a multiple of 2. (Block Aligned) + animBlockSize = pow(2.0, floor(_2_maximumBlockSize * animStuff)); + } else { + // Block Size, always a multiple of 2. (Pixel Aligned) + animBlockSize = floor(pow(2.0, _2_maximumBlockSize * animStuff)); + } + + // UV Calculations + float2 finalUV = v_in.uv; + finalUV -= _1_pixelateCenter; // Offset by the pixelation center. + finalUV *= ViewSize.xy; // Convert to 0..Resolution UVs for pixelation. + finalUV /= animBlockSize; // Divide by current block size. + finalUV = floor(finalUV) + _3_blockOffset; // Use floor() on it to get aligned pixels. + finalUV *= animBlockSize; // Multiply by current block size. + finalUV *= ViewSize.zw; // Convert back to 0..1 UVs for texture sampling. + finalUV += _1_pixelateCenter; // Revert the offset by the pixelation center again. + + float4 sampleA = InputA.Sample(def_sampler, finalUV); + float4 sampleB = InputB.Sample(def_sampler, finalUV); + + float4 rgb = lerp(sampleA, sampleB, clamp((TransitionTime - 0.45) * (1.0 / 0.45), 0., 1.)); + + return rgb; +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDefault(v_in); + } +}