From 6f4fe1f24e11201b36c9c166acb30ca2ca10ffa0 Mon Sep 17 00:00:00 2001 From: Brimson_ Date: Thu, 28 Oct 2021 23:55:10 -0700 Subject: [PATCH] Rewrite many shaders --- shaders/cBloom.fx | 3 +- shaders/cFrameDifference.fx | 9 +- shaders/cInterpolate.fx | 428 ------------------------------------ shaders/cInterpolation.fx | 380 ++++++++++++++++++++++++++++++++ shaders/cMosaic.fx | 11 +- shaders/cMotionBlur.fx | 110 ++++----- shaders/cOpticalFlow.fx | 45 ++-- shaders/cPureDepthAO.fx | 6 +- shaders/cShard.fx | 14 +- shaders/cTile.fx | 6 +- shaders/kContour.fx | 2 +- shaders/kDatamosh.fx | 100 ++++----- shaders/kMirror.fx | 4 +- 13 files changed, 526 insertions(+), 592 deletions(-) delete mode 100644 shaders/cInterpolate.fx create mode 100644 shaders/cInterpolation.fx diff --git a/shaders/cBloom.fx b/shaders/cBloom.fx index 217c954..7bb7f6c 100644 --- a/shaders/cBloom.fx +++ b/shaders/cBloom.fx @@ -143,7 +143,7 @@ float4 DownsamplePS(sampler2D Source, float4 TexCoord[4]) Output += (B0 + C0 + B1 + C1) * Weights.y; Output += (A1 + B1 + A2 + B2) * Weights.y; Output += (B1 + C1 + B2 + C2) * Weights.y; - return Output; + return float4(Output.rgb, 1.0); } float4 UpsamplePS(sampler2D Source, float4 TexCoord[3]) @@ -188,6 +188,7 @@ void PrefilterPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out Color = Color * max(ResponseCurve, Brightness - _Threshold) / max(Brightness, 1e-10); Brightness = max(max(Color.r, Color.g), Color.b); OutputColor0 = saturate(lerp(Brightness, Color.rgb, _Saturation)); + OutputColor0.a = 1.0; } // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT diff --git a/shaders/cFrameDifference.fx b/shaders/cFrameDifference.fx index dfe895a..0b87cb4 100644 --- a/shaders/cFrameDifference.fx +++ b/shaders/cFrameDifference.fx @@ -8,14 +8,7 @@ uniform float _Blend < uniform float _Weight < ui_type = "slider"; - ui_label = "Thresholding"; - ui_min = 0.0; - ui_max = 2.0; -> = 1.0; - -uniform float _Scale < - ui_type = "slider"; - ui_label = "Scaling"; + ui_label = "Weight"; ui_min = 0.0; ui_max = 2.0; > = 1.0; diff --git a/shaders/cInterpolate.fx b/shaders/cInterpolate.fx deleted file mode 100644 index 7507e50..0000000 --- a/shaders/cInterpolate.fx +++ /dev/null @@ -1,428 +0,0 @@ - -/* - This shader will NOT insert frames, just something I played around with - It's practically useless in games and media players - However, putting frame blending to 1 does do a weird paint effect LUL - - Optical flow motion blur using color by Brimson - Special Thanks to - - MartinBFFan and Pao on Discord for reporting bugs - - BSD for bug propaganda and helping to solve my issue - - Lord of Lunacy, KingEric1992, and Marty McFly for power of 2 function -*/ - -uniform float _Constraint < - ui_type = "drag"; - ui_label = "Constraint"; - ui_tooltip = "Higher = Smoother flow"; -> = 1.0; - -uniform float _Blend < - ui_type = "drag"; - ui_label = "Temporal Blending"; - ui_tooltip = "Higher = Less temporal noise"; - ui_max = 0.5; -> = 0.25; - -uniform float _Detail < - ui_type = "drag"; - ui_label = "Mipmap Bias"; - ui_tooltip = "Higher = Less spatial noise"; -> = 2.5; - -uniform float _Average < - ui_type = "drag"; - ui_label = "Frame average"; - ui_tooltip = "Higher = More past frame blend influence"; - ui_max = 1.0; -> = 0.0; - -uniform bool _Lerp < - ui_type = "radio"; - ui_label = "Lerp interpolation"; - ui_tooltip = "Lerp mix interpolated frames"; -> = false; - -#define _HALFSIZE uint2(BUFFER_WIDTH / 2, BUFFER_HEIGHT / 2) -#define _BUFFERSIZE uint2(_HALFSIZE / 8) - -texture2D _RenderColor : COLOR; - -sampler2D _SampleColor -{ - Texture = _RenderColor; - SRGBTexture = TRUE; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderBuffer -{ - Width = _HALFSIZE.x; - Height = _HALFSIZE.y; - Format = R16F; - MipLevels = 3; -}; - -sampler2D _SampleBuffer -{ - Texture = _RenderBuffer; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderData0 -{ - Width = _BUFFERSIZE.x; - Height = _BUFFERSIZE.y; - Format = RG16F; - MipLevels = 6; -}; - -sampler2D _SampleData0 -{ - Texture = _RenderData0; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderData1 -{ - Width = _BUFFERSIZE.x; - Height = _BUFFERSIZE.y; - Format = RG16F; - MipLevels = 6; -}; - -sampler2D _SampleData1 -{ - Texture = _RenderData1; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderCopy_Interpolate -{ - Width = _BUFFERSIZE.x; - Height = _BUFFERSIZE.y; - Format = R16F; -}; - -sampler2D _SampleCopy -{ - Texture = _RenderCopy_Interpolate; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderOpticalFlow_Interpolate -{ - Width = _BUFFERSIZE.x; - Height = _BUFFERSIZE.y; - Format = RG16F; -}; - -sampler2D _SampleOpticalFlow -{ - Texture = _RenderOpticalFlow_Interpolate; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -texture2D _RenderFrame_Interpolate -{ - Width = BUFFER_WIDTH; - Height = BUFFER_HEIGHT; -}; - -sampler2D _SampleFrame -{ - Texture = _RenderFrame_Interpolate; - SRGBTexture = TRUE; - AddressU = MIRROR; - AddressV = MIRROR; -}; - -/* [Vertex Shaders] */ - -void PostProcessVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0) -{ - TexCoord.x = (ID == 2) ? 2.0 : 0.0; - TexCoord.y = (ID == 1) ? 2.0 : 0.0; - Position = float4(TexCoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); -} - -static const float KernelSize = 14; - -float GaussianWeight(const int Position) -{ - const float Sigma = KernelSize / 3.0; - const float Pi = 3.1415926535897932384626433832795f; - float Output = rsqrt(2.0 * Pi * (Sigma * Sigma)); - return Output * exp(-(Position * Position) / (2.0 * (Sigma * Sigma))); -} - -float3 OutputWeights(const float Index) -{ - float Weight0 = GaussianWeight(Index); - float Weight1 = GaussianWeight(Index + 1.0); - float LinearWeight = Weight0 + Weight1; - return float3(Weight0, Weight1, LinearWeight); -} - -float2 OutputOffsets(const float Index) -{ - float3 Weights = OutputWeights(Index); - float Offset = dot(float2(Index, Index + 1.0), Weights.xy) / Weights.z; - return float2(Offset, -Offset); -} - -void HorizontalBlurVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets[7] : TEXCOORD1) -{ - PostProcessVS(ID, Position, TexCoord); - const float2 Direction = float2(1.0 / _BUFFERSIZE.x, 0.0); - - [unroll] for(int i = 0; i < 7; i++) - { - const float2 LinearOffset = OutputOffsets(i * 2 + 1); - Offsets[i] = TexCoord.xyxy + LinearOffset.xxyy * Direction.xyxy; - } -} - -void VerticalBlurVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets[7] : TEXCOORD1) -{ - PostProcessVS(ID, Position, TexCoord); - const float2 Direction = float2(0.0, 1.0 / _BUFFERSIZE.y); - - [unroll] for(int i = 0; i < 7; i++) - { - const float2 LinearOffset = OutputOffsets(i * 2 + 1); - Offsets[i] = TexCoord.xyxy + LinearOffset.xxyy * Direction.xyxy; - } -} - -void DerivativesVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float4 Offsets : TEXCOORD0) -{ - const float2 PixelSize = 0.5 / _BUFFERSIZE; - const float4 PixelOffset = float4(PixelSize, -PixelSize); - float2 TexCoord0; - PostProcessVS(ID, Position, TexCoord0); - Offsets = TexCoord0.xyxy + PixelOffset; -} - -/* [ Pixel Shaders ] */ - -float4 GaussianBlur(sampler2D Source, float2 TexCoord, float4 Offsets[7]) -{ - float Total = GaussianWeight(0.0); - float4 Output = tex2D(Source, TexCoord) * GaussianWeight(0.0); - - [unroll] for(int i = 0; i < 7; i ++) - { - const float LinearWeight = OutputWeights(i * 2 + 1).z; - Output += tex2D(Source, Offsets[i].xy) * LinearWeight; - Output += tex2D(Source, Offsets[i].zw) * LinearWeight; - Total += 2.0 * LinearWeight; - } - - return Output / Total; -} - -void NormalizePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float OutputColor0 : SV_TARGET0) -{ - float3 Color = max(1e-7, tex2D(_SampleColor, TexCoord).rgb); - Color /= dot(Color, 1.0); - Color /= max(max(Color.r, Color.g), Color.b); - OutputColor0 = dot(Color, 1.0 / 3.0); -} - -void BlitPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float2 OutputColor0 : SV_TARGET0) -{ - OutputColor0.x = tex2D(_SampleBuffer, TexCoord).x; - OutputColor0.y = tex2D(_SampleCopy, TexCoord).x; -} - -void HorizontalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float OutputColor0 : SV_TARGET0) -{ - OutputColor0 = GaussianBlur(_SampleData0, TexCoord, Offsets).x; -} - -void VerticalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float OutputColor0 : SV_TARGET0, out float OutputColor1 : SV_TARGET1) -{ - OutputColor0 = GaussianBlur(_SampleData1, TexCoord, Offsets).x; - OutputColor1 = OutputColor0; -} - -void DerivativesPS(float4 Position : SV_POSITION, float4 Offsets : TEXCOORD0, out float2 OutputColor0 : SV_TARGET0) -{ - float2 Sample0 = tex2D(_SampleData0, Offsets.zy).xy; // (-x, +y) - float2 Sample1 = tex2D(_SampleData0, Offsets.xy).xy; // (+x, +y) - float2 Sample2 = tex2D(_SampleData0, Offsets.zw).xy; // (-x, -y) - float2 Sample3 = tex2D(_SampleData0, Offsets.xw).xy; // (+x, -y) - float2 _ddx = (-Sample2 + -Sample0) + (Sample3 + Sample1); - float2 _ddy = (Sample2 + Sample3) + (-Sample0 + -Sample1); - OutputColor0.x = dot(_ddx, 0.5); - OutputColor0.y = dot(_ddy, 0.5); -} - -float2 GaussSeidel(float4 _I, float Levels, float2 InitialFlow) -{ - float2 Output = InitialFlow; - - while(Levels >= 0.0) - { - Output.x -= ((_I.x * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); - Output.y -= ((_I.y * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); - Levels = Levels - 1.0; - } - - return Output; -} - -void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) -{ - float MaxLevel = 5.0 - 0.5; - float2 OutputFlow = 0.0; - - for(float Level = MaxLevel; Level >= 0.0; Level--) - { - const float Lambda = (_Constraint * 1e-5) / pow(4.0, MaxLevel - Level); - float4 CalculateUV = float4(TexCoord, 0.0, Level); - float2 Frame = tex2Dlod(_SampleData0, CalculateUV).xy; - float4 _I; - _I.xy = tex2Dlod(_SampleData1, CalculateUV).xy; - _I.z = Frame.x - Frame.y; - _I.w = 1.0 / (dot(_I.xy, _I.xy) + Lambda); - OutputFlow.xy = GaussSeidel(_I, Level, OutputFlow.xy); - } - - OutputColor0.rgb = OutputFlow; - OutputColor0.a = _Blend; -} -void PPHorizontalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) -{ - OutputColor0 = GaussianBlur(_SampleOpticalFlow, TexCoord, Offsets).xy; -} - -void PPVerticalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) -{ - OutputColor0 = GaussianBlur(_SampleData0, TexCoord, Offsets).xy; -} - -// Median masking inspired by vs-mvtools -// https://github.com/dubhater/vapoursynth-mvtools - -float4 Median3(float4 A, float4 B, float4 C) -{ - return max(min(A, B), min(max(A, B), C)); -} - -void InterpolatePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) -{ - const float2 PixelSize = rcp(_BUFFERSIZE); - float2 MotionVectors = tex2Dlod(_SampleData1, float4(TexCoord, 0.0, _Detail)).xy; - float4 Reference = tex2D(_SampleColor, TexCoord); - float4 Source = tex2D(_SampleFrame, TexCoord); - float4 BCompensation, FCompensation; - - if(_Lerp) - { - BCompensation = tex2D(_SampleColor, TexCoord + MotionVectors * PixelSize); - FCompensation = tex2D(_SampleFrame, TexCoord - MotionVectors * PixelSize); - } - else - { - BCompensation = tex2D(_SampleColor, TexCoord - MotionVectors * PixelSize); - FCompensation = tex2D(_SampleFrame, TexCoord + MotionVectors * PixelSize); - } - - float4 Average = lerp(Reference, Source, _Average); - OutputColor0 = (_Lerp) ? lerp(FCompensation, BCompensation, Average) : Median3(FCompensation, BCompensation, Average); -} - -void CopyPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) -{ - OutputColor0 = tex2D(_SampleColor, TexCoord); -} - -technique cInterpolate -{ - pass - { - VertexShader = PostProcessVS; - PixelShader = NormalizePS; - RenderTarget0 = _RenderBuffer; - } - - pass - { - VertexShader = PostProcessVS; - PixelShader = BlitPS; - RenderTarget0 = _RenderData0; - } - - pass - { - VertexShader = HorizontalBlurVS; - PixelShader = HorizontalBlurPS; - RenderTarget0 = _RenderData1; - RenderTargetWriteMask = 1; - } - - pass - { - VertexShader = VerticalBlurVS; - PixelShader = VerticalBlurPS; - RenderTarget0 = _RenderData0; - RenderTarget1 = _RenderCopy_Interpolate; - RenderTargetWriteMask = 1; - } - - pass - { - VertexShader = DerivativesVS; - PixelShader = DerivativesPS; - RenderTarget0 = _RenderData1; - } - - pass - { - VertexShader = PostProcessVS; - PixelShader = OpticalFlowPS; - RenderTarget0 = _RenderOpticalFlow_Interpolate; - ClearRenderTargets = FALSE; - BlendEnable = TRUE; - BlendOp = ADD; - SrcBlend = INVSRCALPHA; - DestBlend = SRCALPHA; - } - - pass - { - VertexShader = HorizontalBlurVS; - PixelShader = PPHorizontalBlurPS; - RenderTarget0 = _RenderData0; - } - - pass - { - VertexShader = VerticalBlurVS; - PixelShader = PPVerticalBlurPS; - RenderTarget0 = _RenderData1; - } - - pass - { - VertexShader = PostProcessVS; - PixelShader = InterpolatePS; - SRGBWriteEnable = TRUE; - } - - pass - { - VertexShader = PostProcessVS; - PixelShader = CopyPS; - RenderTarget = _RenderFrame_Interpolate; - SRGBWriteEnable = TRUE; - } -} diff --git a/shaders/cInterpolation.fx b/shaders/cInterpolation.fx new file mode 100644 index 0000000..680c13f --- /dev/null +++ b/shaders/cInterpolation.fx @@ -0,0 +1,380 @@ + +uniform float _Blend < + ui_type = "drag"; + ui_label = "Temporal Blending"; + ui_tooltip = "Higher = Less temporal noise"; + ui_max = 0.5; +> = 0.25; + +uniform float _Constraint < + ui_type = "drag"; + ui_label = "Constraint"; + ui_tooltip = "Higher = Smoother flow"; +> = 0.5; + +uniform float _Detail < + ui_type = "drag"; + ui_label = "Mipmap Bias"; + ui_tooltip = "Higher = Less spatial noise"; + ui_max = 8.0; +> = 2.5; + +#define BUFFER_SIZE uint2(BUFFER_WIDTH / 16, BUFFER_HEIGHT / 16) + +texture2D _RenderColor : COLOR; + +sampler2D _SampleColor +{ + Texture = _RenderColor; + SRGBTexture = TRUE; +}; + +texture2D _RenderFrame0_Interpolation +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = RGBA8; + MipLevels = 4; +}; + +sampler2D _SampleFrame0 +{ + Texture = _RenderFrame0_Interpolation; + SRGBTexture = TRUE; +}; + +texture2D _RenderData0 +{ + Width = BUFFER_SIZE.x; + Height = BUFFER_SIZE.y; + Format = RG16F; + MipLevels = 6; +}; + +sampler2D _SampleData0 +{ + Texture = _RenderData0; +}; + +texture2D _RenderData1 +{ + Width = BUFFER_SIZE.x; + Height = BUFFER_SIZE.y; + Format = RG16F; + MipLevels = 6; +}; + +sampler2D _SampleData1 +{ + Texture = _RenderData1; +}; + +sampler2D _SampleVectors +{ + Texture = _RenderData1; + MinFilter = POINT; + MagFilter = POINT; +}; + +texture2D _RenderCopy_Interpolation +{ + Width = BUFFER_SIZE.x; + Height = BUFFER_SIZE.y; + Format = R16F; +}; + +sampler2D _SampleCopy +{ + Texture = _RenderCopy_Interpolation; +}; + +texture2D _RenderOpticalFlow +{ + Width = BUFFER_SIZE.x; + Height = BUFFER_SIZE.y; + Format = RG16F; +}; + +sampler2D _SampleOpticalFlow +{ + Texture = _RenderOpticalFlow; +}; + +texture2D _RenderFrame1_Interpolation +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = RGBA8; +}; + +sampler2D _SampleFrame1 +{ + Texture = _RenderFrame1_Interpolation; + SRGBTexture = TRUE; +}; + +/* [Vertex Shaders] */ + +void PostProcessVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0) +{ + TexCoord.x = (ID == 2) ? 2.0 : 0.0; + TexCoord.y = (ID == 1) ? 2.0 : 0.0; + Position = float4(TexCoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); +} + +static const float KernelSize = 14; + +float GaussianWeight(const int Position) +{ + const float Sigma = KernelSize / 3.0; + const float Pi = 3.1415926535897932384626433832795f; + float Output = rsqrt(2.0 * Pi * (Sigma * Sigma)); + return Output * exp(-(Position * Position) / (2.0 * (Sigma * Sigma))); +} + +float3 OutputWeights(const float Index) +{ + float Weight0 = GaussianWeight(Index); + float Weight1 = GaussianWeight(Index + 1.0); + float LinearWeight = Weight0 + Weight1; + return float3(Weight0, Weight1, LinearWeight); +} + +float2 OutputOffsets(const float Index) +{ + float3 Weights = OutputWeights(Index); + float Offset = dot(float2(Index, Index + 1.0), Weights.xy) / Weights.z; + return float2(Offset, -Offset); +} + +void HorizontalBlurVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets[7] : TEXCOORD1) +{ + PostProcessVS(ID, Position, TexCoord); + const float2 Direction = float2(1.0 / BUFFER_SIZE.x, 0.0); + + [unroll] for(int i = 0; i < 7; i++) + { + const float2 LinearOffset = OutputOffsets(i * 2 + 1); + Offsets[i] = TexCoord.xyxy + LinearOffset.xxyy * Direction.xyxy; + } +} + +void VerticalBlurVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets[7] : TEXCOORD1) +{ + PostProcessVS(ID, Position, TexCoord); + const float2 Direction = float2(0.0, 1.0 / BUFFER_SIZE.y); + + [unroll] for(int i = 0; i < 7; i++) + { + const float2 LinearOffset = OutputOffsets(i * 2 + 1); + Offsets[i] = TexCoord.xyxy + LinearOffset.xxyy * Direction.xyxy; + } +} + +void DerivativesVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets : TEXCOORD1) +{ + const float2 PixelSize = 0.5 / BUFFER_SIZE; + const float4 PixelOffset = float4(PixelSize, -PixelSize); + PostProcessVS(ID, Position, TexCoord); + Offsets = TexCoord.xyxy + PixelOffset; +} + +/* [Pixel Shaders] */ + +float4 GaussianBlur(sampler2D Source, float2 TexCoord, float4 Offsets[7]) +{ + float Total = GaussianWeight(0.0); + float4 Output = tex2D(Source, TexCoord) * GaussianWeight(0.0); + + [unroll] for(int i = 0; i < 7; i ++) + { + const float LinearWeight = OutputWeights(i * 2 + 1).z; + Output += tex2D(Source, Offsets[i].xy) * LinearWeight; + Output += tex2D(Source, Offsets[i].zw) * LinearWeight; + Total += 2.0 * LinearWeight; + } + + return Output / Total; +} + +void BlitPS0(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = tex2D(_SampleColor, TexCoord); +} + +void NormalizePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float OutputColor0 : SV_TARGET0) +{ + float3 Color = max(tex2D(_SampleFrame0, TexCoord).rgb, 1e-7); + Color /= dot(Color, 1.0); + Color /= max(max(Color.r, Color.g), Color.b); + OutputColor0 = dot(Color, 1.0 / 3.0); +} + +void HorizontalBlurPS0(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float OutputColor0 : SV_TARGET0) +{ + OutputColor0.x = GaussianBlur(_SampleData0, TexCoord, Offsets).x; +} + +void VerticalBlurPS0(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) +{ + OutputColor0.x = GaussianBlur(_SampleData1, TexCoord, Offsets).x; + OutputColor0.y = tex2D(_SampleCopy, TexCoord).x; // Store previous blurred image before it gets overwritten! +} + +void DerivativesPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0, out float OutputColor1 : SV_TARGET1) +{ + float2 Sample0 = tex2D(_SampleData0, Offsets.zy).xy; // (-x, +y) + float2 Sample1 = tex2D(_SampleData0, Offsets.xy).xy; // (+x, +y) + float2 Sample2 = tex2D(_SampleData0, Offsets.zw).xy; // (-x, -y) + float2 Sample3 = tex2D(_SampleData0, Offsets.xw).xy; // (+x, -y) + float2 Ix = (-Sample2 + -Sample0) + (Sample3 + Sample1); + float2 Iy = (Sample2 + Sample3) + (-Sample0 + -Sample1); + OutputColor0.x = dot(Ix, 0.5); + OutputColor0.y = dot(Iy, 0.5); + OutputColor1 = tex2D(_SampleData0, TexCoord).x; +} + +float2 OpticalFlow(float2 TexCoord, float Level, inout float2 OutputFlow) +{ + const float MaxLevel = 4.5; + const float Lambda = (_Constraint * 1e-5) * 1e+3 / pow(4.0, MaxLevel - Level); + const float BufferPixels = (BUFFER_WIDTH / 2) * (BUFFER_HEIGHT / 2); + const float Iterations = log2(BufferPixels / ldexp(BufferPixels, -Level)); + + float4 LevelCoord = float4(TexCoord, 0.0, Level); + float2 SampleFrame = tex2Dlod(_SampleData0, LevelCoord).xy; + float4 I; + I.xy = tex2Dlod(_SampleData1, LevelCoord).xy; + I.z = SampleFrame.x - SampleFrame.y; + I.w = 1.0 / (dot(I.xy, I.xy) + Lambda); + + [unroll] for(int i = 0; i <= Iterations; i++) + { + OutputFlow.x -= ((I.x * (dot(I.xy, OutputFlow.xy) + I.z)) * I.w); + OutputFlow.y -= ((I.y * (dot(I.xy, OutputFlow.xy) + I.z)) * I.w); + } + + return OutputFlow; +} + +void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = 0.0; + OutputColor0.xy += OpticalFlow(TexCoord, 4.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 3.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 2.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 1.5, OutputColor0.xy); + OutputColor0.xy = OpticalFlow(TexCoord, 0.5, OutputColor0.xy); + OutputColor0.a = _Blend; +} + +void HorizontalBlurPS1(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = GaussianBlur(_SampleOpticalFlow, TexCoord, Offsets).xy; +} +void VerticalBlurPS1(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = GaussianBlur(_SampleData0, TexCoord, Offsets).xy; +} + +float4 Median(float4 A, float4 B, float4 C) +{ + return max(min(A, B), min(max(A, B), C)); +} + +void InterpolatePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +{ + float2 MotionVectors = tex2Dlod(_SampleVectors, float4(TexCoord, 0.0, _Detail)).xy / (BUFFER_SIZE / exp2(_Detail)); + float4 FrameF = tex2D(_SampleFrame1, TexCoord + MotionVectors); + float4 FrameB = tex2D(_SampleFrame0, TexCoord - MotionVectors); + float4 FrameP = tex2D(_SampleFrame1, TexCoord); + float4 FrameC = tex2D(_SampleFrame0, TexCoord); + float4 FrameL = lerp(FrameC, FrameP, 0.5); + OutputColor0 = Median(FrameL, FrameF, FrameB); +} + +void BlitPS1(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = tex2D(_SampleFrame0, TexCoord); +} + +technique cInterpolation +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = BlitPS0; + RenderTarget0 = _RenderFrame0_Interpolation; + SRGBWriteEnable = TRUE; + } + + pass + { + VertexShader = PostProcessVS; + PixelShader = NormalizePS; + RenderTarget0 = _RenderData0; + } + + pass + { + VertexShader = HorizontalBlurVS; + PixelShader = HorizontalBlurPS0; + RenderTarget0 = _RenderData1; + } + + pass + { + VertexShader = VerticalBlurVS; + PixelShader = VerticalBlurPS0; + RenderTarget0 = _RenderData0; + } + + pass + { + VertexShader = DerivativesVS; + PixelShader = DerivativesPS; + RenderTarget0 = _RenderData1; + RenderTarget1 = _RenderCopy_Interpolation; + } + + pass + { + VertexShader = PostProcessVS; + PixelShader = OpticalFlowPS; + RenderTarget0 = _RenderOpticalFlow; + ClearRenderTargets = FALSE; + BlendEnable = TRUE; + BlendOp = ADD; + SrcBlend = INVSRCALPHA; + DestBlend = SRCALPHA; + } + + pass + { + VertexShader = HorizontalBlurVS; + PixelShader = HorizontalBlurPS1; + RenderTarget0 = _RenderData0; + } + + pass + { + VertexShader = VerticalBlurVS; + PixelShader = VerticalBlurPS1; + RenderTarget0 = _RenderData1; + } + + pass + { + VertexShader = PostProcessVS; + PixelShader = InterpolatePS; + SRGBWriteEnable = TRUE; + } + + pass + { + VertexShader = PostProcessVS; + PixelShader = BlitPS1; + RenderTarget = _RenderFrame1_Interpolation; + SRGBWriteEnable = TRUE; + } +} diff --git a/shaders/cMosaic.fx b/shaders/cMosaic.fx index fa647a3..e4be0e7 100644 --- a/shaders/cMosaic.fx +++ b/shaders/cMosaic.fx @@ -70,7 +70,7 @@ void BlitPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out floa void MosaicPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) { - float2 FragCoord = TexCoord * float2(BUFFER_WIDTH, BUFFER_HEIGHT); + float2 PixelPosition = TexCoord * float2(BUFFER_WIDTH, BUFFER_HEIGHT); const float2 ScreenSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT); float2 PixelSize = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); float2 BlockCoord, MosaicCoord; @@ -80,19 +80,20 @@ void MosaicPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out fl { // Circle https://www.shadertoy.com/view/4d2SWy case 0: - BlockCoord = floor(FragCoord / MaxRadius) * MaxRadius; + BlockCoord = floor(PixelPosition / MaxRadius) * MaxRadius; MosaicCoord = BlockCoord * PixelSize; float4 Color = tex2Dlod(_SampleMosaicLOD, float4(MosaicCoord, 0.0, log2(MaxRadius) - 1.0)); - float2 Offset = FragCoord - BlockCoord; + float2 Offset = PixelPosition - BlockCoord; float2 Center = MaxRadius / 2.0; float Length = distance(Center, Offset); float Circle = 1.0 - smoothstep(-2.0 , 0.0, Length - Center.x); OutputColor0 = Color * Circle; + //OutputColor0 = MosaicCoord; break; // Triangle https://www.shadertoy.com/view/4d2SWy case 1: - const float MaxLODLevel = log2(sqrt((BUFFER_WIDTH * BUFFER_HEIGHT) / (_Radius.x * _Radius.y))); + const float MaxLODLevel = log2(sqrt((BUFFER_WIDTH * BUFFER_HEIGHT) / (_Radius.x * _Radius.y))); const float2 Divisor = 1.0 / (2.0 * _Radius); BlockCoord = floor(TexCoord * _Radius) / _Radius; TexCoord -= BlockCoord; @@ -103,7 +104,7 @@ void MosaicPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out fl OutputColor0 = tex2Dlod(_SampleMosaicLOD, float4(BlockCoord + Composite * Divisor, 0.0, MaxLODLevel - 1.0)); break; default: - BlockCoord = round(FragCoord / MaxRadius) * MaxRadius; + BlockCoord = round(PixelPosition / MaxRadius) * MaxRadius; MosaicCoord = BlockCoord * PixelSize; OutputColor0 = tex2Dlod(_SampleMosaicLOD, float4(MosaicCoord, 0.0, log2(MaxRadius) - 1.0)); break; diff --git a/shaders/cMotionBlur.fx b/shaders/cMotionBlur.fx index e95a94f..870129c 100644 --- a/shaders/cMotionBlur.fx +++ b/shaders/cMotionBlur.fx @@ -11,13 +11,13 @@ uniform float _Scale < ui_type = "drag"; ui_label = "Flow Scale"; ui_tooltip = "Higher = More motion blur"; -> = 4.0; +> = 0.5; uniform float _Constraint < ui_type = "drag"; ui_label = "Constraint"; ui_tooltip = "Higher = Smoother flow"; -> = 1.0; +> = 0.25; uniform float _Blend < ui_type = "drag"; @@ -174,13 +174,12 @@ void VerticalBlurVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITIO } } -void DerivativesVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float4 Offsets : TEXCOORD0) +void DerivativesVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout float2 TexCoord : TEXCOORD0, inout float4 Offsets : TEXCOORD1) { const float2 PixelSize = 0.5 / _BUFFERSIZE; const float4 PixelOffset = float4(PixelSize, -PixelSize); - float2 TexCoord0; - PostProcessVS(ID, Position, TexCoord0); - Offsets = TexCoord0.xyxy + PixelOffset; + PostProcessVS(ID, Position, TexCoord); + Offsets = TexCoord.xyxy + PixelOffset; } /* [ Pixel Shaders ] */ @@ -209,67 +208,61 @@ void NormalizePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out OutputColor0 = dot(Color, 1.0 / 3.0); } -void BlitPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float2 OutputColor0 : SV_TARGET0) -{ - OutputColor0.x = tex2D(_SampleBuffer, TexCoord).x; - OutputColor0.y = tex2D(_SampleCopy, TexCoord).x; -} - void HorizontalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float OutputColor0 : SV_TARGET0) { - OutputColor0 = GaussianBlur(_SampleData0, TexCoord, Offsets).x; + OutputColor0.x = GaussianBlur(_SampleBuffer, TexCoord, Offsets).x; } -void VerticalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float OutputColor0 : SV_TARGET0, out float OutputColor1 : SV_TARGET1) +void VerticalBlurPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets[7] : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0) { - OutputColor0 = GaussianBlur(_SampleData1, TexCoord, Offsets).x; - OutputColor1 = OutputColor0; + OutputColor0.x = GaussianBlur(_SampleData0, TexCoord, Offsets).x; + OutputColor0.y = tex2D(_SampleCopy, TexCoord).x; // Store previous blurred image before it gets overwritten! } -void DerivativesPS(float4 Position : SV_POSITION, float4 Offsets : TEXCOORD0, out float2 OutputColor0 : SV_TARGET0) +void DerivativesPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offsets : TEXCOORD1, out float2 OutputColor0 : SV_TARGET0, out float OutputColor1 : SV_TARGET1) { - float2 Sample0 = tex2D(_SampleData0, Offsets.zy).xy; // (-x, +y) - float2 Sample1 = tex2D(_SampleData0, Offsets.xy).xy; // (+x, +y) - float2 Sample2 = tex2D(_SampleData0, Offsets.zw).xy; // (-x, -y) - float2 Sample3 = tex2D(_SampleData0, Offsets.xw).xy; // (+x, -y) - float2 _ddx = (-Sample2 + -Sample0) + (Sample3 + Sample1); - float2 _ddy = (Sample2 + Sample3) + (-Sample0 + -Sample1); - OutputColor0.x = dot(_ddx, 0.5); - OutputColor0.y = dot(_ddy, 0.5); + float2 Sample0 = tex2D(_SampleData1, Offsets.zy).xy; // (-x, +y) + float2 Sample1 = tex2D(_SampleData1, Offsets.xy).xy; // (+x, +y) + float2 Sample2 = tex2D(_SampleData1, Offsets.zw).xy; // (-x, -y) + float2 Sample3 = tex2D(_SampleData1, Offsets.xw).xy; // (+x, -y) + float2 Ix = (-Sample2 + -Sample0) + (Sample3 + Sample1); + float2 Iy = (Sample2 + Sample3) + (-Sample0 + -Sample1); + OutputColor0.x = dot(Ix, 0.5); + OutputColor0.y = dot(Iy, 0.5); + OutputColor1 = tex2D(_SampleData1, TexCoord).x; } -float2 GaussSeidel(float4 _I, float Levels, float2 InitialFlow) +float2 OpticalFlow(float2 TexCoord, float Level, inout float2 OutputFlow) { - float2 Output = InitialFlow; - - while(Levels >= 0.0) + const float MaxLevel = 4.5; + const float Lambda = (_Constraint * 1e-5) * 1e+3 / pow(4.0, MaxLevel - Level); + const float BufferPixels = (BUFFER_WIDTH / 2) * (BUFFER_HEIGHT / 2); + const float Iterations = log2(BufferPixels / ldexp(BufferPixels, -Level)); + + float4 LevelCoord = float4(TexCoord, 0.0, Level); + float2 SampleFrame = tex2Dlod(_SampleData1, LevelCoord).xy; + float4 I; + I.xy = tex2Dlod(_SampleData0, LevelCoord).xy; + I.z = SampleFrame.x - SampleFrame.y; + I.w = 1.0 / (dot(I.xy, I.xy) + Lambda); + + [unroll] for(int i = 0; i <= Iterations; i++); { - Output.x -= ((_I.x * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); - Output.y -= ((_I.y * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); - Levels = Levels - 1.0; + OutputFlow.x -= ((I.x * (dot(I.xy, OutputFlow.xy) + I.z)) * I.w); + OutputFlow.y -= ((I.y * (dot(I.xy, OutputFlow.xy) + I.z)) * I.w); } - return Output; + return OutputFlow; } void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) { - float MaxLevel = 5.0 - 0.5; - float2 OutputFlow = 0.0; - - for(float Level = MaxLevel; Level >= 0.0; Level--) - { - const float Lambda = (_Constraint * 1e-5) / pow(4.0, MaxLevel - Level); - float4 CalculateUV = float4(TexCoord, 0.0, Level); - float2 Frame = tex2Dlod(_SampleData0, CalculateUV).xy; - float4 _I; - _I.xy = tex2Dlod(_SampleData1, CalculateUV).xy; - _I.z = Frame.x - Frame.y; - _I.w = 1.0 / (dot(_I.xy, _I.xy) + Lambda); - OutputFlow.xy = GaussSeidel(_I, Level, OutputFlow.xy); - } - - OutputColor0.rgb = OutputFlow; + OutputColor0 = 0.0; + OutputColor0.xy += OpticalFlow(TexCoord, 4.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 3.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 2.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 1.5, OutputColor0.xy); + OutputColor0.xy = OpticalFlow(TexCoord, 0.5, OutputColor0.xy); OutputColor0.a = _Blend; } @@ -296,7 +289,7 @@ void OutputPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out fl OutputColor0 += tex2D(_SampleColor, (TexCoord - Offset)); } - OutputColor0 /= (Samples * 2); + OutputColor0 /= (Samples * 2.0); } technique cMotionBlur @@ -308,35 +301,26 @@ technique cMotionBlur RenderTarget0 = _RenderBuffer; } - pass - { - VertexShader = PostProcessVS; - PixelShader = BlitPS; - RenderTarget0 = _RenderData0; - } - pass { VertexShader = HorizontalBlurVS; PixelShader = HorizontalBlurPS; - RenderTarget0 = _RenderData1; - RenderTargetWriteMask = 1; + RenderTarget0 = _RenderData0; } pass { VertexShader = VerticalBlurVS; PixelShader = VerticalBlurPS; - RenderTarget0 = _RenderData0; - RenderTarget1 = _RenderCopy_MotionBlur; - RenderTargetWriteMask = 1; + RenderTarget0 = _RenderData1; } pass { VertexShader = DerivativesVS; PixelShader = DerivativesPS; - RenderTarget0 = _RenderData1; + RenderTarget0 = _RenderData0; + RenderTarget1 = _RenderCopy_MotionBlur; } pass diff --git a/shaders/cOpticalFlow.fx b/shaders/cOpticalFlow.fx index 84f7fca..290d984 100644 --- a/shaders/cOpticalFlow.fx +++ b/shaders/cOpticalFlow.fx @@ -245,7 +245,7 @@ float4 GaussianBlur(sampler2D Source, float2 TexCoord, float4 Offsets[7]) void BlitPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float2 OutputColor0 : SV_TARGET0) { - float3 Color = tex2D(_SampleColor, TexCoord).rgb; + float3 Color = max(tex2D(_SampleColor, TexCoord).rgb, 1e-7); float3 NColor = Color / dot(Color, 1.0); NColor /= max(max(NColor.r, NColor.g), NColor.b); OutputColor0.x = dot(NColor, 1.0 / 3.0); @@ -273,34 +273,39 @@ void DerivativesPS(float4 Position : SV_POSITION, float4 Offsets : TEXCOORD0, ou OutputColor0.y = dot((Sample2 + Sample3) + (-Sample0 + -Sample1), 0.5); } -void GaussSeidel(float4 I, float Levels, inout float2 OpticalFlow) +float2 OpticalFlow(float2 TexCoord, float Level, inout float2 OpticalFlow) { - while(Levels >= 0.0) + const float MaxLevel = 6.5; + const float Lambda = (_Constraint * 1e-5) * 1e+3 / pow(4.0, MaxLevel - Level); + const float BufferPixels = (BUFFER_WIDTH / 2) * (BUFFER_HEIGHT / 2); + float Iterations = log2(BufferPixels / ldexp(BufferPixels, -Level)); + + float4 LevelCoord = float4(TexCoord, 0.0, Level); + float2 SampleFrame = tex2Dlod(_SampleData0, LevelCoord).xy; + float4 I; + I.xy = tex2Dlod(_SampleData1, LevelCoord).xy; + I.z = SampleFrame.x - SampleFrame.y; + I.w = 1.0 / (dot(I.xy, I.xy) + Lambda); + + [unroll] for(int i = 0; i <= Iterations; i++) { OpticalFlow.x -= ((I.x * (dot(I.xy, OpticalFlow.xy) + I.z)) * I.w); OpticalFlow.y -= ((I.y * (dot(I.xy, OpticalFlow.xy) + I.z)) * I.w); - Levels = Levels - 1.0; } + + return OpticalFlow; } void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) { - float MaxLevel = 7.0 - 0.5; - float2 OutputFlow = 0.0; - - [unroll] for(float Level = MaxLevel; Level > 0.0; Level--) - { - const float Lambda = (_Constraint * 1e-3) / pow(4.0, MaxLevel - Level); - float4 LevelCoord = float4(TexCoord, 0.0, Level); - float2 Frame = tex2Dlod(_SampleData0, LevelCoord).xy; - float4 I; - I.xy = tex2Dlod(_SampleData1, LevelCoord).xy; - I.z = Frame.x - Frame.y; - I.w = 1.0 / (dot(I.xy, I.xy) + Lambda); - GaussSeidel(I, Level, OutputFlow.xy); - } - - OutputColor0.rgb = OutputFlow; + OutputColor0 = 0.0; + OutputColor0.xy += OpticalFlow(TexCoord, 6.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 5.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 4.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 3.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 2.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 1.5, OutputColor0.xy); + OutputColor0.xy = OpticalFlow(TexCoord, 0.5, OutputColor0.xy); OutputColor0.a = _Blend; } diff --git a/shaders/cPureDepthAO.fx b/shaders/cPureDepthAO.fx index dbb0657..9da9f00 100644 --- a/shaders/cPureDepthAO.fx +++ b/shaders/cPureDepthAO.fx @@ -159,8 +159,8 @@ void GradientNoise(float2 Position, float Seed, inout float Noise) float2 Rotate2D( float2 r, float l ) { float2 Directions; - sincos(l,Directions[0],Directions[1]);//same as float2(cos(l),sin(l)) - return float2( dot( r, float2(Directions[1], -Directions[0]) ), dot( r, Directions.xy ) ); + sincos(l,Directions[0],Directions[1]); + return float2(dot(r, float2(Directions[1], -Directions[0])), dot(r, Directions.xy)); } void OcclusionPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) @@ -189,7 +189,7 @@ void OcclusionPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out for(int i = 0; i < Samples; i++) { - float3 Ray = 0.03 * RadiusDepth * reflect(Sample_Sphere[i], normalize(Rotate2D(Sample_Sphere[i], Random).xyy)) / RadiusDepth; + float3 Ray = 0.03 * RadiusDepth * reflect(Sample_Sphere[i], normalize(Rotate2D(Sample_Sphere[i].xy, Random).xyy)) / RadiusDepth; float3 Hemi_Ray = ScreenPosition + sign(dot(Ray, Normal)) * Ray; float OcclusionDepth = DepthMap(saturate(Hemi_Ray.xy)).x; float Difference = Depth - OcclusionDepth; diff --git a/shaders/cShard.fx b/shaders/cShard.fx index e34999b..b127870 100644 --- a/shaders/cShard.fx +++ b/shaders/cShard.fx @@ -28,13 +28,13 @@ void ShardVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inou void ShardPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, float4 Offset : TEXCOORD1, out float4 OutputColor0 : SV_TARGET0) { - float4 uOriginal = tex2D(_SampleColor, TexCoord); - float4 uBlur; - uBlur += tex2D(_SampleColor, Offset.xw) * 0.25; - uBlur += tex2D(_SampleColor, Offset.zw) * 0.25; - uBlur += tex2D(_SampleColor, Offset.xy) * 0.25; - uBlur += tex2D(_SampleColor, Offset.zy) * 0.25; - OutputColor0 = uOriginal + (uOriginal - uBlur) * _Weight; + float4 OriginalSample = tex2D(_SampleColor, TexCoord); + float4 BlurSample; + BlurSample += tex2D(_SampleColor, Offset.xw) * 0.25; + BlurSample += tex2D(_SampleColor, Offset.zw) * 0.25; + BlurSample += tex2D(_SampleColor, Offset.xy) * 0.25; + BlurSample += tex2D(_SampleColor, Offset.zy) * 0.25; + OutputColor0 = OriginalSample + (OriginalSample - BlurSample) * _Weight; } technique cShard diff --git a/shaders/cTile.fx b/shaders/cTile.fx index 7506feb..14da9bc 100644 --- a/shaders/cTile.fx +++ b/shaders/cTile.fx @@ -27,11 +27,11 @@ void TileVS(in uint ID : SV_VERTEXID, inout float4 Position : SV_POSITION, inout TexCoord.y = (ID == 1) ? 2.0 : 0.0; Position = float4(TexCoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); - const float2 screensize = float2(BUFFER_WIDTH, BUFFER_HEIGHT); + const float2 ScreeSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT); TexCoord -= 0.5; TexCoord += TexCoord + float2(_Center.x, -_Center.y); - float2 Scaling = TexCoord * screensize * (_Scale * 0.01); - TexCoord = floor(Scaling) / screensize; + float2 Scaling = TexCoord * ScreeSize * (_Scale * 1e-2); + TexCoord = floor(Scaling) / ScreeSize; TexCoord += 0.5; } diff --git a/shaders/kContour.fx b/shaders/kContour.fx index f7a1695..58c5bde 100644 --- a/shaders/kContour.fx +++ b/shaders/kContour.fx @@ -184,7 +184,7 @@ void ContourPS(float4 Position : SV_POSITION, float4 TexCoord[4] : TEXCOORD0, ou _Iy += C2 * -17.0; Edge = Magnitude(_Ix, _Iy); break; - case 8: // FastSobel + case 8: // Fast Sobel float3 Sample0 = NormalizeColor(tex2D(_SampleColor, TexCoord[3].zy).rgb); // (-x, +y) float3 Sample1 = NormalizeColor(tex2D(_SampleColor, TexCoord[3].xy).rgb); // (+x, +y) float3 Sample2 = NormalizeColor(tex2D(_SampleColor, TexCoord[3].zw).rgb); // (-x, -y) diff --git a/shaders/kDatamosh.fx b/shaders/kDatamosh.fx index 0a173dd..1e85744 100644 --- a/shaders/kDatamosh.fx +++ b/shaders/kDatamosh.fx @@ -109,22 +109,7 @@ uniform float _BlendFactor < #define _FILTER POINT #endif -#define CONST_LOG2(x) (\ - (uint((x) & 0xAAAAAAAA) != 0) | \ - (uint(((x) & 0xFFFF0000) != 0) << 4) | \ - (uint(((x) & 0xFF00FF00) != 0) << 3) | \ - (uint(((x) & 0xF0F0F0F0) != 0) << 2) | \ - (uint(((x) & 0xCCCCCCCC) != 0) << 1)) - -#define BIT2_LOG2(x) ((x) | (x) >> 1) -#define BIT4_LOG2(x) (BIT2_LOG2(x) | BIT2_LOG2(x) >> 2) -#define BIT8_LOG2(x) (BIT4_LOG2(x) | BIT4_LOG2(x) >> 4) -#define BIT16_LOG2(x) (BIT8_LOG2(x) | BIT8_LOG2(x) >> 8) -#define LOG2(x) (CONST_LOG2((BIT16_LOG2(x) >> 1) + 1)) -#define RMAX(x, y) x ^ ((x ^ y) & -(x < y)) // max(x, y) - #define _HALFSIZE uint2(BUFFER_WIDTH / 2, BUFFER_HEIGHT / 2) -#define _MIPLEVELS LOG2(RMAX(_HALFSIZE.x, _HALFSIZE.y)) + 1 texture2D _RenderColor : COLOR; @@ -141,7 +126,7 @@ texture2D _RenderFrame0 Width = _HALFSIZE.x; Height = _HALFSIZE.y; Format = R16F; - MipLevels = _MIPLEVELS; + MipLevels = 8; }; sampler2D _SampleFrame0 @@ -156,7 +141,7 @@ texture2D _RenderDerivatives_Datamosh Width = _HALFSIZE.x; Height = _HALFSIZE.y; Format = RG16F; - MipLevels = _MIPLEVELS; + MipLevels = 8; }; sampler2D _SampleDerivatives @@ -171,7 +156,7 @@ texture2D _RenderOpticalFlow_Datamosh Width = _HALFSIZE.x; Height = _HALFSIZE.y; Format = RG16F; - MipLevels = _MIPLEVELS; + MipLevels = 8; }; sampler2D _SampleOpticalFlow @@ -204,7 +189,7 @@ texture2D _RenderFrame1 Width = _HALFSIZE.x; Height = _HALFSIZE.y; Format = R16F; - MipLevels = _MIPLEVELS; + MipLevels = 8; }; sampler2D _SampleFrame1 @@ -280,29 +265,57 @@ void DerivativesPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, f - Repeat until full resolution level of original frames is reached */ -void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +float2 GaussSeidel(float4 _I, float Levels, float2 InitialFlow) { - const float MaxLevel = (_MIPLEVELS - 1); - float Level = (_MIPLEVELS - 1); - float2 OutputFlow; + float2 Output = InitialFlow; - while(Level >= 0) + while(Levels >= 0.0) { - const float Lambda = 1e-1 * 1e+3 / pow(4.0, MaxLevel - Level); - float4 CalculateUV = float4(TexCoord, 0.0, Level); - float CurrentFrame = tex2Dlod(_SampleFrame0, CalculateUV).x; - float PreviousFrame = tex2Dlod(_SampleFrame1, CalculateUV).x; - float2 _Ixy = tex2Dlod(_SampleDerivatives, CalculateUV).xy; - float _It = CurrentFrame - PreviousFrame; - - float Linear = dot(_Ixy, OutputFlow.xy) + _It; - float Smoothness = rcp(dot(_Ixy, _Ixy) + Lambda); - float2 CurrentFlow = OutputFlow - ((_Ixy * Linear) * Smoothness); - OutputFlow = (Level != 0) ? CurrentFlow + OutputFlow : CurrentFlow; - Level = Level - 1.0; + Output.x -= ((_I.x * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); + Output.y -= ((_I.y * (dot(_I.xy, Output.xy) + _I.z)) * _I.w); + Levels = Levels - 1.0; } - OutputColor0 = float4(OutputFlow.xy, 0.0, _BlendFactor); + return Output; +} + +float2 OpticalFlow(float2 TexCoord, float Level, inout float2 OpticalFlow) +{ + const float MaxLevel = 7.5; + const float Lambda = (_Constraint * 1e-5) * 1e+3 / pow(4.0, MaxLevel - Level); + const float BufferPixels = (BUFFER_WIDTH / 2) * (BUFFER_HEIGHT / 2); + float Iterations = log2(BufferPixels / ldexp(BufferPixels, -Level)); + + float4 LevelCoord = float4(TexCoord, 0.0, Level); + float SampleFrameC = tex2Dlod(_SampleFrame0, LevelCoord).x; + float SampleFrameP = tex2Dlod(_SampleFrame1, LevelCoord).x; + + float4 I; + I.xy = tex2Dlod(_SampleDerivatives, LevelCoord).xy; + I.z = SampleFrameC - SampleFrameP; + I.w = 1.0 / (dot(I.xy, I.xy) + Lambda); + + [unroll] for(int i = 0; i <= Iterations; i++) + { + OpticalFlow.x -= ((I.x * (dot(I.xy, OpticalFlow.xy) + I.z)) * I.w); + OpticalFlow.y -= ((I.y * (dot(I.xy, OpticalFlow.xy) + I.z)) * I.w); + } + + return OpticalFlow; +} + +void OpticalFlowPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out float4 OutputColor0 : SV_TARGET0) +{ + OutputColor0 = 0.0; + OutputColor0.xy += OpticalFlow(TexCoord, 7.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 6.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 5.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 4.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 3.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 2.5, OutputColor0.xy); + OutputColor0.xy += OpticalFlow(TexCoord, 1.5, OutputColor0.xy); + OutputColor0.xy = OpticalFlow(TexCoord, 0.5, OutputColor0.xy); + OutputColor0.a = _BlendFactor; } float RandomNoise(float2 TexCoord) @@ -324,7 +337,6 @@ void AccumulatePS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, ou // Motion vector float2 MotionVectors = tex2Dlod(_SampleOpticalFlow, float4(TexCoord, 0.0, _Detail)).xy; - MotionVectors *= _Scale; // Normalized screen space -> Pixel coordinates MotionVectors = MotionVectors * _HALFSIZE; @@ -376,18 +388,6 @@ void OutputPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD0, out fl float2 MotionVectors = tex2Dlod(_SampleOpticalFlow, float4(TexCoord, 0.0, _Detail)).xy * DisplacementTexel; MotionVectors *= _Scale; - // Normalized screen space -> Pixel coordinates - MotionVectors = MotionVectors * float2(BUFFER_WIDTH, BUFFER_HEIGHT); - - // Small random displacement (diffusion) - MotionVectors += (Random.xy - 0.5) * _Diffusion; - - // Pixel perfect snapping - MotionVectors = round(MotionVectors); - - // Pixel coordinates -> Normalized screen space - MotionVectors *= (float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) - 1.0); - float4 Source = tex2D(_SampleColor, TexCoord); // Color from the original image float Displacement = tex2D(_SampleAccumulation, TexCoord).r; // Displacement vector float4 Working = tex2D(_SampleFeedback, TexCoord - MotionVectors); diff --git a/shaders/kMirror.fx b/shaders/kMirror.fx index f5e0bcd..26a87b0 100644 --- a/shaders/kMirror.fx +++ b/shaders/kMirror.fx @@ -66,8 +66,7 @@ void MirrorPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD, out flo // Angular repeating. Phi += _Offset; Phi = Phi - _Divisor * floor(Phi / _Divisor); - - if(_Symmetry) { Phi = min(Phi, _Divisor - Phi); } + Phi = (_Symmetry) ? min(Phi, _Divisor - Phi) : Phi; Phi += _Roll - _Offset; // Convert back to the texture coordinate. @@ -76,7 +75,6 @@ void MirrorPS(float4 Position : SV_POSITION, float2 TexCoord : TEXCOORD, out flo // Reflection at the border of the screen. TexCoord = max(min(TexCoord, 2.0 - TexCoord), -TexCoord); - OutputColor0 = tex2D(_SampleColor, TexCoord); }