diff options
Diffstat (limited to 'hlsl/post.fx')
-rw-r--r-- | hlsl/post.fx | 247 |
1 files changed, 19 insertions, 228 deletions
diff --git a/hlsl/post.fx b/hlsl/post.fx index 57cf821071f..1a49ab55d4d 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -66,22 +66,16 @@ bool xor(bool a, bool b) //----------------------------------------------------------------------------- uniform float2 ScreenDims; // size of the window or fullscreen -uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3) - uniform float2 SourceDims; // size of the texture in power-of-two size -uniform float2 SourceRect; // size of the uv rectangle - -uniform float2 TargetDims; // size of target +uniform float2 TargetDims; // size of the target surface uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); -uniform float2 Prescale = float2(8.0f, 8.0f); - uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation -uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures +uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures uniform bool PrepareVector = false; VS_OUTPUT vs_main(VS_INPUT Input) @@ -93,12 +87,11 @@ VS_OUTPUT vs_main(VS_INPUT Input) ? shadowUVOffset.yx : shadowUVOffset.xy; - // todo: calculate offset - float2 ScreenCoordPrescaleOffset = 0.0f; - ScreenCoordPrescaleOffset += shadowUVOffset; + float2 ScreenCoordOffset = 0.0f; + ScreenCoordOffset += shadowUVOffset; Output.ScreenCoord = Input.Position.xy; - Output.ScreenCoord += ScreenCoordPrescaleOffset; + Output.ScreenCoord += ScreenCoordOffset; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -108,7 +101,8 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.TexCoord = PrepareVector ? Input.Position.xy / ScreenDims - : Input.TexCoord; // + 0.5f / TargetDims; + : Input.TexCoord; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.Color = Input.Color; @@ -126,11 +120,6 @@ uniform float ScanlineBrightOffset = 1.0f; uniform float ScanlineOffset = 1.0f; uniform float ScanlineHeight = 1.0f; -uniform float CurvatureAmount = 0.0f; -uniform float RoundCornerAmount = 0.0f; -uniform float VignettingAmount = 0.0f; -uniform float ReflectionAmount = 0.0f; - uniform float ShadowAlpha = 0.0f; uniform float2 ShadowCount = float2(6.0f, 6.0f); uniform float2 ShadowUV = float2(0.25f, 0.25f); @@ -138,198 +127,18 @@ uniform float2 ShadowUV = float2(0.25f, 0.25f); uniform float3 Power = float3(1.0f, 1.0f, 1.0f); uniform float3 Floor = float3(0.0f, 0.0f, 0.0f); -static const float Epsilon = 1.0e-7f; static const float PI = 3.1415927f; -static const float E = 2.7182817f; -static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) -static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) - -float nextPowerOfTwo(float n) -{ - return pow(2, floor(log2(n) / log2(2)) + 1); -} - -// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/ -float random(float2 seed) -{ - // irrationals for pseudo randomness - float2 i = float2(Gelfond, GelfondSchneider); - - return frac(cos(dot(seed, i)) * 123456.0f); -} - -// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/ -float normalizedSigmoid(float n, float k) -{ - // valid for n and k in range of -1.0 and 1.0 - return (n - n * k) / (k - abs(n) * 2.0f * k + 1); -} - -float GetNoiseFactor(float n, float random) -{ - // smaller n become more noisy - return 1.0f + random * max(0.0f, 0.25f * pow(E, -4 * n)); -} - -float GetVignetteFactor(float2 coord, float amount) -{ - float2 VignetteCoord = coord; - - float VignetteLength = length(VignetteCoord); - float VignetteBlur = (amount * 0.75f) + 0.25; - - // 0.5 full screen fitting circle - float VignetteRadius = 1.0f - (amount * 0.25f); - float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength); - - return saturate(Vignette); -} - -float GetSpotAddend(float2 coord, float amount) -{ - float2 SpotCoord = coord; - SpotCoord += OrientationSwapXY - ? float2(-0.25f, -0.25f) * ScreenRatio // upper right quadrant - : float2(-0.25f, 0.25f) * ScreenRatio; // upper right quadrant - - float SpotBlur = amount; - - // 0.5 full screen fitting circle - float SpotRadius = amount * 0.75f; - float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord)); - - float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount; - - // increase strength by 100% - SigmoidSpot = SigmoidSpot * 2.0f; - - return saturate(SigmoidSpot); -} - -// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm -float RoundBox(float2 p, float2 b, float r) -{ - return length(max(abs(p) - b + r, 0.0f)) - r; -} - -float GetRoundCornerFactor(float2 coord, float amount) -{ - // hint: vector target area is always quadratic - float2 UsedSourceRect = PrepareVector - ? float2(1.0f, 1.0f) - : SourceRect; - float2 SourceArea = 1.0f / UsedSourceRect; - float2 SourceDimsArea = SourceDims * UsedSourceRect; - float2 SourceRatio = float2(1.0f, SourceDimsArea.y / SourceDimsArea.x); - float2 SourceTexelDims = 1.0f / SourceDims; - - // base on the default ratio of 4:3 - float2 RoundCoordScale = (SourceDims / SourceArea / SourceRatio) * ScreenRatio; - - float2 RoundCoord = coord; - // hint: alignment correction - RoundCoord -= SourceTexelDims * SourceArea; - RoundCoord *= SourceTexelDims * SourceArea + 1.0f; - // hint: roundness correction - RoundCoord *= RoundCoordScale; - - float radius = amount * 50.0f; - - // compute box (base on the default ratio of 4:3) - float box = RoundBox(RoundCoord.xy, (RoundCoordScale * 0.5f), radius); - - // // apply blur - // float blurAmount = 1.0f / max(1.0f, amount * 25.0f); - // float blueOffset = 1.0f - pow(blurAmount * 0.5f, 0.5f); - // box *= blurAmount; - // box += blueOffset; - - float border = smoothstep(1.0f, 0.5f, box); - - return saturate(border); -} float4 ps_main(PS_INPUT Input) : COLOR { float2 ScreenTexelDims = 1.0f / ScreenDims; - float2 SourceTexelDims = 1.0f / SourceDims; - - // hint: vector target area is always quadratic - float2 UsedSourceRect = PrepareVector - ? float2(1.0f, 1.0f) - : SourceRect; - float UsedCurvatureAmount = CurvatureAmount * 0.25f; // reduced curvature - - float2 SourceArea = 1.0f / UsedSourceRect; - float2 DoubleSourceArea = SourceArea * 2.0f; - float SquareSourceAreaLength = pow(length(SourceArea), 2.0f); - float2 HalfSourceRect = UsedSourceRect * 0.5f; - - // Screen Curvature - float2 CurvatureUnitCoord = (Input.TexCoord * DoubleSourceArea) - 1.0f; - float2 CurvatureFactor = (1.0 / SquareSourceAreaLength) * UsedCurvatureAmount; - float2 CurvatureCurve = CurvatureUnitCoord * pow(length(CurvatureUnitCoord), 2.0f) * CurvatureFactor; - float2 CurvatureZoom = 1.0f - (DoubleSourceArea * CurvatureFactor); - - // todo: vector cuverture requires a correction on y-axis if screen and target size differ and y > x float2 ScreenCoord = Input.ScreenCoord / ScreenDims; - ScreenCoord -= HalfSourceRect; - ScreenCoord *= CurvatureZoom; // zoom - ScreenCoord += HalfSourceRect; - ScreenCoord += CurvatureCurve; // distortion - float2 BaseCoord = Input.TexCoord; - BaseCoord -= HalfSourceRect; - BaseCoord *= CurvatureZoom; // zoom - BaseCoord += HalfSourceRect; - BaseCoord += CurvatureCurve; // distortion - - float2 CurvatureCorrection = 1.0f; - - // vector cuverture correction - if (PrepareVector) - { - float ScreenRatio = ScreenDims.x / ScreenDims.y; - float TargetRatio = TargetDims.x / TargetDims.y; - - // hint: vector cuverture requires a correction on the x-axis by the amount that screen and target size differ - CurvatureCorrection.x += - (ScreenRatio / TargetRatio - 1.0f) - * (1.0f + SquareSourceAreaLength * UsedCurvatureAmount); - } - - // the floowing coordinates are used for effects - float2 BaseCoordCentered = Input.TexCoord; - BaseCoordCentered -= HalfSourceRect; - BaseCoordCentered *= CurvatureZoom * CurvatureCorrection; // zoom - BaseCoordCentered += CurvatureCurve * CurvatureCorrection; // distortion - - float2 BaseAreaCoord = BaseCoord; - BaseAreaCoord *= SourceArea; - - float2 BaseAreaCoordCentered = BaseCoordCentered; - BaseAreaCoordCentered *= SourceArea; - - float2 BaseAreaRatioCoord = BaseAreaCoord; - BaseAreaRatioCoord *= ScreenRatio; - - float2 BaseAreaRatioCoordCentered = BaseAreaCoordCentered; - BaseAreaRatioCoordCentered *= ScreenRatio; - - // // Alpha Clipping (round corners applies smoother clipping when screen is curved) - // clip((BaseCoord < SourceTexelDims) ? -1 : 1); - // clip((BaseCoord > SourceRect + SourceTexelDims) ? -1 : 1); + // Color float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); BaseColor.a = 1.0f; - // BaseColor.rgb = 1.0f; - - // Vignetting Simulation (may affect bloom) - float2 VignetteCoord = BaseAreaCoordCentered; - - float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); - BaseColor.rgb *= VignetteFactor; // Mask Simulation (may not affect bloom) if (!PrepareBloom) @@ -387,15 +196,16 @@ float4 ps_main(PS_INPUT Input) : COLOR // Scanline Simulation (may not affect bloom) if (!PrepareBloom) { - // todo: there is an offset which can be noticed at lower prescale in high-resolution - float2 ScanlinePrescaleOffset = 0.0f; - - float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y; - float ScanJitter = ScanlineOffset * SourceDims.y; - float ScanBrightMod = sin(InnerSine * PI + ScanJitter + ScanlinePrescaleOffset); - float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha); - - BaseColor.rgb *= ScanColor; + // Scanline Simulation (disabled for vector) + if (!PrepareVector) + { + float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y; + float ScanJitter = ScanlineOffset * SourceDims.y; + float ScanBrightMod = sin(InnerSine * PI + ScanJitter); + float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha); + + BaseColor.rgb *= ScanColor; + } } // Output @@ -404,25 +214,6 @@ float4 ps_main(PS_INPUT Input) : COLOR : BaseColor * Input.Color; Output.a = 1.0f; - // Light Reflection Simulation (may not affect bloom) - if (!PrepareBloom) - { - float3 LightColor = float3(1.0f, 0.90f, 0.80f); - - float2 SpotCoord = BaseAreaRatioCoordCentered; - float2 NoiseCoord = BaseAreaRatioCoordCentered; - - float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); - float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); - Output.rgb += SpotAddend * NoiseFactor * LightColor; - } - - // Round Corners Simulation (may affect bloom) - float2 RoundCornerCoord = BaseAreaCoordCentered; - - float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount); - Output.rgb *= roundCornerFactor; - return Output; } @@ -436,7 +227,7 @@ technique ScanMaskTechnique { Lighting = FALSE; - //Sampler[0] = <DiffuseSampler>; + Sampler[0] = <DiffuseSampler>; VertexShader = compile vs_3_0 vs_main(); PixelShader = compile ps_3_0 ps_main(); |