diff options
Diffstat (limited to 'hlsl')
-rw-r--r-- | hlsl/artwork_support/distortion.fx | 101 | ||||
-rw-r--r-- | hlsl/artwork_support/post.fx | 535 | ||||
-rw-r--r-- | hlsl/bloom.fx | 22 | ||||
-rw-r--r-- | hlsl/deconverge.fx | 43 | ||||
-rw-r--r-- | hlsl/distortion.fx | 52 | ||||
-rw-r--r-- | hlsl/downsample.fx | 27 | ||||
-rw-r--r-- | hlsl/focus.fx | 33 | ||||
-rw-r--r-- | hlsl/ntsc.fx | 2 | ||||
-rw-r--r-- | hlsl/phosphor.fx | 2 | ||||
-rw-r--r-- | hlsl/post.fx | 110 | ||||
-rw-r--r-- | hlsl/prescale.fx | 42 | ||||
-rw-r--r-- | hlsl/primary.fx | 101 |
12 files changed, 265 insertions, 805 deletions
diff --git a/hlsl/artwork_support/distortion.fx b/hlsl/artwork_support/distortion.fx deleted file mode 100644 index 333363afeb8..00000000000 --- a/hlsl/artwork_support/distortion.fx +++ /dev/null @@ -1,101 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:ImJezze -//----------------------------------------------------------------------------- -// Distortion Effect -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Sampler Definitions -//----------------------------------------------------------------------------- - -texture DiffuseTexture; - -sampler DiffuseSampler = sampler_state -{ - Texture = <DiffuseTexture>; - MipFilter = LINEAR; - MinFilter = LINEAR; - MagFilter = LINEAR; - AddressU = CLAMP; - AddressV = CLAMP; - AddressW = CLAMP; -}; - -//----------------------------------------------------------------------------- -// Vertex Definitions -//----------------------------------------------------------------------------- - -struct VS_INPUT -{ - float4 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -struct PS_INPUT -{ - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -//----------------------------------------------------------------------------- -// Distortion Vertex Shader -//----------------------------------------------------------------------------- - -uniform float2 ScreenDims; // size of the window or fullscreen -uniform float2 TargetDims; - -VS_OUTPUT vs_main(VS_INPUT Input) -{ - VS_OUTPUT Output = (VS_OUTPUT)0; - - Output.Position = float4(Input.Position.xyz, 1.0f); - Output.Position.xy /= ScreenDims; - Output.Position.y = 1.0f - Output.Position.y; // flip y - Output.Position.xy -= 0.5f; // center - Output.Position.xy *= 2.0f; // zoom - - Output.Color = Input.Color; - - Output.TexCoord = Input.Position.xy / ScreenDims; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - - return Output; -} - -//----------------------------------------------------------------------------- -// Post-Processing Pixel Shader -//----------------------------------------------------------------------------- - -float4 ps_main(PS_INPUT Input) : COLOR -{ - float2 BaseCoord = Input.TexCoord; - - // Color - float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); - BaseColor.a = 1.0f; - - return BaseColor; -} - -//----------------------------------------------------------------------------- -// Distortion Effect -//----------------------------------------------------------------------------- - -technique DefaultTechnique -{ - pass Pass0 - { - Lighting = FALSE; - - VertexShader = compile vs_3_0 vs_main(); - PixelShader = compile ps_3_0 ps_main(); - } -}
\ No newline at end of file diff --git a/hlsl/artwork_support/post.fx b/hlsl/artwork_support/post.fx deleted file mode 100644 index 9a3b693cd61..00000000000 --- a/hlsl/artwork_support/post.fx +++ /dev/null @@ -1,535 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz,ImJezze -//----------------------------------------------------------------------------- -// Scanline, Shadowmask & Distortion Effect -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Sampler Definitions -//----------------------------------------------------------------------------- - -texture DiffuseTexture; - -sampler DiffuseSampler = sampler_state -{ - Texture = <DiffuseTexture>; - MipFilter = LINEAR; - MinFilter = LINEAR; - MagFilter = LINEAR; - AddressU = CLAMP; - AddressV = CLAMP; - AddressW = CLAMP; -}; - -texture ShadowTexture; - -sampler ShadowSampler = sampler_state -{ - Texture = <ShadowTexture>; - MipFilter = LINEAR; - MinFilter = LINEAR; - MagFilter = LINEAR; - AddressU = WRAP; - AddressV = WRAP; - AddressW = WRAP; -}; - -//----------------------------------------------------------------------------- -// Vertex Definitions -//----------------------------------------------------------------------------- - -struct VS_INPUT -{ - float4 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT -{ - float4 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; - float2 ScreenCoord : TEXCOORD1; -}; - -struct PS_INPUT -{ - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; - float2 ScreenCoord : TEXCOORD1; -}; - -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - -static const float Epsilon = 1.0e-7f; -static const float PI = 3.1415927f; -static const float PHI = 1.618034f; -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) - -//----------------------------------------------------------------------------- -// Functions -//----------------------------------------------------------------------------- - -// 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); -} - -// 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; -} - -//----------------------------------------------------------------------------- -// Scanline, Shadowmask & Distortion Vertex Shader -//----------------------------------------------------------------------------- - -uniform float2 ScreenDims; // size of the window or fullscreen -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 the target surface -uniform float2 QuadDims; // size of the screen quad - -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 bool SwapXY = false; - -uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° - -uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures -uniform bool PrepareVector = false; - -VS_OUTPUT vs_main(VS_INPUT Input) -{ - VS_OUTPUT Output = (VS_OUTPUT)0; - - float2 shadowUVOffset = ShadowUVOffset; - shadowUVOffset = SwapXY - ? shadowUVOffset.yx - : shadowUVOffset.xy; - - float2 ScreenCoordOffset = 0.0f; - ScreenCoordOffset += shadowUVOffset; - - Output.ScreenCoord = Input.Position.xy; - Output.ScreenCoord += ScreenCoordOffset; - - Output.Position = float4(Input.Position.xyz, 1.0f); - Output.Position.xy /= ScreenDims; - Output.Position.y = 1.0f - Output.Position.y; // flip y - Output.Position.xy -= 0.5f; // center - Output.Position.xy *= 2.0f; // zoom - - Output.TexCoord = PrepareVector - ? Input.Position.xy / ScreenDims - : Input.TexCoord; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - - Output.Color = Input.Color; - - return Output; -} - -//----------------------------------------------------------------------------- -// Scanline, Shadowmask & Distortion Pixel Shader -//----------------------------------------------------------------------------- - -uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC) -uniform float HumBarAlpha = 0.0f; - -uniform float TimeMilliseconds = 0.0f; - -uniform float2 ScreenScale = float2(1.0f, 1.0f); -uniform float2 ScreenOffset = float2(0.0f, 0.0f); - -uniform float ScanlineAlpha = 1.0f; -uniform float ScanlineScale = 1.0f; -uniform float ScanlineBrightScale = 1.0f; -uniform float ScanlineBrightOffset = 1.0f; -uniform float ScanlineOffset = 1.0f; -uniform float ScanlineHeight = 1.0f; - -uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f); - -uniform float CurvatureAmount = 1.0f; -uniform float RoundCornerAmount = 0.0f; -uniform float SmoothBorderAmount = 0.0f; -uniform float VignettingAmount = 0.0f; -uniform float ReflectionAmount = 0.0f; - -uniform int ShadowTileMode = 0; // 0 based on screen dimension, 1 based on source dimension -uniform float ShadowAlpha = 0.0f; -uniform float2 ShadowCount = float2(6.0f, 6.0f); -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); - -float2 GetRatioCorrection() -{ - if (PrepareVector) - { - float ScreenRatio = ScreenDims.x / ScreenDims.y; - float QuadRatio = QuadDims.x / QuadDims.y; - float ScreenQuadRatio = QuadRatio / ScreenRatio; - - return ScreenQuadRatio > 1.0f - ? float2(1.0, 1.0f / ScreenQuadRatio) - : float2(ScreenQuadRatio, 1.0); - } - else - { - return SourceRect; - } -} - -float GetNoiseFactor(float n, float random) -{ - // smaller n become more noisy - return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * 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 RatioCorrection = GetRatioCorrection(); - - // normalized screen canvas ratio - float2 CanvasRatio = PrepareVector - ? float2(1.0f, QuadDims.y / QuadDims.x) - : float2(1.0f, SwapXY - ? QuadDims.x / QuadDims.y - : QuadDims.y / QuadDims.x); - - // upper right quadrant - float2 spotOffset = PrepareVector - ? RotationType == 1 // 90° - ? float2(-0.25f, -0.25f) - : RotationType == 2 // 180° - ? float2(0.25f, -0.25f) - : RotationType == 3 // 270° - ? float2(0.25f, 0.25f) - : float2(-0.25f, 0.25f) - : SwapXY - ? float2(0.25f, 0.25f) - : float2(-0.25f, 0.25f); - - float2 SpotCoord = coord; - SpotCoord += spotOffset * RatioCorrection; - SpotCoord *= CanvasRatio; - SpotCoord /= RatioCorrection; - - float SpotBlur = amount; - - // 0.5 full screen fitting circle - float SpotRadius = amount * 0.75f; - float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord)); - - float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75); - - // increase strength by 100% - SigmoidSpot = SigmoidSpot * 2.0f; - - return saturate(SigmoidSpot); -} - -float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) -{ - float2 RatioCorrection = GetRatioCorrection(); - - // reduce smooth amount down to radius amount - smoothAmount = min(smoothAmount, radiusAmount); - - float2 CanvasDims = PrepareVector - ? ScreenDims - : SwapXY - ? QuadDims.yx / SourceRect - : QuadDims.xy / SourceRect; - - coord = PrepareVector - ? coord - : coord - 1.0f / SourceDims; // alignment correction (raster graphics) - - float range = min(QuadDims.x, QuadDims.y) * 0.5; - float radius = range * max(radiusAmount, 0.0025f); - float smooth = 1.0 / (range * max(smoothAmount, 0.0025f)); - - // compute box - float box = roundBox(CanvasDims * (coord * 2.0f), CanvasDims * RatioCorrection, radius); - - // apply smooth - box *= smooth; - box += 1.0f - pow(smooth * 0.5f, 0.5f); - - float border = smoothstep(1.0f, 0.0f, box); - - return saturate(border); -} - -// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/ -float2 GetDistortedCoords(float2 centerCoord, float amount) -{ - // lens distortion coefficient - float k = amount; - - // cubic distortion value - float kcube = amount * 2.0f; - - // compute cubic distortion factor - float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y; - float f = kcube == 0.0f - ? 1.0f + r2 * k - : 1.0f + r2 * (k + kcube * sqrt(r2)); - - // fit screen bounds - f /= 1.0f + amount * 0.5f; - - // apply cubic distortion factor - centerCoord *= f; - - return centerCoord; -} - -float2 GetCoords(float2 coord, float2 centerOffset, float distortionAmount) -{ - float2 RatioCorrection = GetRatioCorrection(); - - // center coordinates - coord -= centerOffset; - - // apply ratio difference between screen and quad - coord /= RatioCorrection; - - // distort coordinates - coord = GetDistortedCoords(coord, distortionAmount); - - // revert ratio difference between screen and quad - coord *= RatioCorrection; - - // un-center coordinates - coord += centerOffset; - - return coord; -} - -float2 GetAdjustedCoords(float2 coord, float2 centerOffset, float distortionAmount) -{ - float2 RatioCorrection = GetRatioCorrection(); - - // center coordinates - coord -= centerOffset; - - // apply ratio difference between screen and quad - coord /= RatioCorrection; - - // apply screen scale - coord /= ScreenScale; - - // distort coordinates - coord = GetDistortedCoords(coord, distortionAmount); - - // revert ratio difference between screen and quad - coord *= RatioCorrection; - - // un-center coordinates - coord += centerOffset; - - // apply screen offset - coord += (centerOffset * 2.0) * ScreenOffset; - - return coord; -} - -float4 ps_main(PS_INPUT Input) : COLOR -{ - float2 ScreenTexelDims = 1.0f / ScreenDims; - float2 SourceTexelDims = 1.0f / SourceDims; - - float2 HalfSourceRect = SourceRect * 0.5f; - - float2 ScreenCoord = Input.ScreenCoord / ScreenDims; - ScreenCoord = GetCoords(ScreenCoord, float2(0.5f, 0.5f), CurvatureAmount * 0.25f); // reduced amount - - float2 DistortionCoord = Input.TexCoord; - DistortionCoord = GetCoords(DistortionCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount - - float2 BaseCoord = Input.TexCoord; - BaseCoord = GetAdjustedCoords(BaseCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount - - float2 DistortionCoordCentered = DistortionCoord; - DistortionCoordCentered -= HalfSourceRect; - - float2 BaseCoordCentered = BaseCoord; - BaseCoordCentered -= HalfSourceRect; - - float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); - BaseColor.a = 1.0f; - - if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f) - { - BaseColor.rgb = 0.0f; - } - - // Mask Simulation (may not affect bloom) - if (!PrepareBloom && ShadowAlpha > 0.0f) - { - float2 shadowDims = ShadowDims; - shadowDims = SwapXY - ? shadowDims.yx - : shadowDims.xy; - - float2 shadowUV = ShadowUV; - // shadowUV = SwapXY - // ? shadowUV.yx - // : shadowUV.xy; - - float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord; - screenCoord = SwapXY - ? screenCoord.yx - : screenCoord.xy; - - float2 shadowCount = ShadowCount; - shadowCount = SwapXY - ? shadowCount.yx - : shadowCount.xy; - - float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount); - shadowTile = SwapXY - ? shadowTile.yx - : shadowTile.xy; - - float2 ShadowFrac = frac(screenCoord / shadowTile); - float2 ShadowCoord = (ShadowFrac * shadowUV); - ShadowCoord += 0.5f / shadowDims; // half texel offset - // ShadowCoord = SwapXY - // ? ShadowCoord.yx - // : ShadowCoord.xy; - - float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord); - float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha); - float ShadowMaskClear = (1.0f - ShadowColor.a) * ShadowAlpha; - - // apply shadow mask color - BaseColor.rgb *= ShadowMaskColor; - // clear shadow mask by background color - BaseColor.rgb = lerp(BaseColor.rgb, BackColor, ShadowMaskClear); - } - - // Color Compression (may not affect bloom) - if (!PrepareBloom) - { - // increasing the floor of the signal without affecting the ceiling - BaseColor.rgb = Floor + (1.0f - Floor) * BaseColor.rgb; - } - - // Color Power (may affect bloom) - BaseColor.r = pow(BaseColor.r, Power.r); - BaseColor.g = pow(BaseColor.g, Power.g); - BaseColor.b = pow(BaseColor.b, Power.b); - - // Scanline Simulation (may not affect bloom) - if (!PrepareBloom) - { - // Scanline Simulation (may not affect vector screen) - if (!PrepareVector && ScanlineAlpha > 0.0f) - { - float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI; - float ScanCoordJitter = ScanlineOffset * PHI; - float ScanSine = sin(ScanCoord + ScanCoordJitter); - float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight); - float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset; - - BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha); - } - - // Hum Bar Simulation (may not affect vector screen) - if (!PrepareVector && HumBarAlpha > 0.0f) - { - float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate); - float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha; - BaseColor.rgb *= HumBrightness; - } - } - - // Output - float4 Output = PrepareVector - ? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f)) - : BaseColor * Input.Color; - Output.a = 1.0f; - - // Vignetting Simulation (may not affect bloom) - if (!PrepareBloom) - { - float2 VignetteCoord = DistortionCoordCentered; - - float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); - Output.rgb *= VignetteFactor; - } - - // Light Reflection Simulation (may not affect bloom) - if (!PrepareBloom) - { - float3 LightColor = float3(1.0f, 0.90f, 0.80f); - - float2 SpotCoord = DistortionCoordCentered; - float2 NoiseCoord = DistortionCoordCentered; - - float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); - float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); - Output.rgb += SpotAddend * NoiseFactor * LightColor; - } - - // Round Corners Simulation (may affect bloom) - float2 RoundCornerCoord = DistortionCoordCentered; - - float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount); - Output.rgb *= roundCornerFactor; - - return Output; -} - -//----------------------------------------------------------------------------- -// Scanline & Shadowmask Effect -//----------------------------------------------------------------------------- - -technique DefaultTechnique -{ - pass Pass0 - { - Lighting = FALSE; - - VertexShader = compile vs_3_0 vs_main(); - PixelShader = compile ps_3_0 ps_main(); - } -}
\ No newline at end of file diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx index 1ee152adfec..47cc04c47ed 100644 --- a/hlsl/bloom.fx +++ b/hlsl/bloom.fx @@ -202,8 +202,9 @@ float random(float2 seed) uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 SourceRect; +uniform float2 SourceDims; +// level dimensions not necessary anymore? uniform float2 Level0Size; uniform float4 Level12Size; uniform float4 Level34Size; @@ -211,6 +212,8 @@ uniform float4 Level56Size; uniform float4 Level78Size; uniform float4 Level9ASize; +uniform bool VectorScreen = false; + VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; @@ -226,12 +229,17 @@ VS_OUTPUT vs_main(VS_INPUT Input) float2 TexCoord = Input.Position.xy / ScreenDims; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - Output.TexCoord0 = TexCoord; - Output.TexCoord12 = TexCoord.xyxy + (0.5f / Level12Size); - Output.TexCoord34 = TexCoord.xyxy + (0.5f / Level34Size); - Output.TexCoord56 = TexCoord.xyxy + (0.5f / Level56Size); - Output.TexCoord78 = TexCoord.xyxy + (0.5f / Level78Size); - Output.TexCoord9A = TexCoord.xyxy + (0.5f / Level9ASize); + Output.TexCoord0 = TexCoord.xy; // + (0.5f / Level0Size); + + TexCoord += VectorScreen + ? 0.5f / TargetDims.xy + : 0.5f / SourceDims.xy; + + Output.TexCoord12 = TexCoord.xyxy; // + (0.5f / Level12Size); + Output.TexCoord34 = TexCoord.xyxy; // + (0.5f / Level34Size); + Output.TexCoord56 = TexCoord.xyxy; // + (0.5f / Level56Size); + Output.TexCoord78 = TexCoord.xyxy; // + (0.5f / Level78Size); + Output.TexCoord9A = TexCoord.xyxy; // + (0.5f / Level9ASize); return Output; } diff --git a/hlsl/deconverge.fx b/hlsl/deconverge.fx index 3c1cbeeeb1f..df5bc2e6b49 100644 --- a/hlsl/deconverge.fx +++ b/hlsl/deconverge.fx @@ -68,48 +68,47 @@ VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 HalfSourceRect = SourceRect * 0.5f; - - float2 QuadRatio = - float2(1.0f, SwapXY - ? QuadDims.y / QuadDims.x - : QuadDims.x / QuadDims.y); - - // imaginary texel dimensions independed from quad dimensions, but dependend on quad ratio - float2 FixedTexelDims = (1.0f / 1024.0) * SourceRect * QuadRatio; - Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // toom - float2 TexCoord = Input.TexCoord; + float2 TexCoord = Input.Position.xy / ScreenDims; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - - Output.Color = Input.Color; + + // we have to handle the swap of the coordinates ourself, because we are using screen not texture coordinates + float3 convergeX = SwapXY ? ConvergeY : ConvergeX; + float3 convergeY = SwapXY ? ConvergeX : ConvergeY; + float3 radialConvergeX = SwapXY ? RadialConvergeY : RadialConvergeX; + float3 radialConvergeY = SwapXY ? RadialConvergeX : RadialConvergeY; + + // imaginary texel dimensions independed from screen dimension, but ratio + float2 TexelDims = (1.0f / 1024) * (QuadDims / ScreenDims); Output.TexCoordX = TexCoord.xxx; Output.TexCoordY = TexCoord.yyy; // center coordinates - Output.TexCoordX -= HalfSourceRect.xxx; - Output.TexCoordY -= HalfSourceRect.yyy; + Output.TexCoordX -= 0.5f * SourceRect.xxx; + Output.TexCoordY -= 0.5f * SourceRect.yyy; // radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount float2 radialConvergeOffset = 2.0f / SourceRect; // radial converge - Output.TexCoordX *= 1.0f + RadialConvergeX * FixedTexelDims.xxx * radialConvergeOffset.xxx; - Output.TexCoordY *= 1.0f + RadialConvergeY * FixedTexelDims.yyy * radialConvergeOffset.yyy; - + Output.TexCoordX *= 1.0f + radialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx; + Output.TexCoordY *= 1.0f + radialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy; + // un-center coordinates - Output.TexCoordX += HalfSourceRect.xxx; - Output.TexCoordY += HalfSourceRect.yyy; + Output.TexCoordX += 0.5f * SourceRect.xxx; + Output.TexCoordY += 0.5f * SourceRect.yyy; // linear converge - Output.TexCoordX += ConvergeX * FixedTexelDims.xxx; - Output.TexCoordY += ConvergeY * FixedTexelDims.yyy; + Output.TexCoordX += convergeX * TexelDims.xxx; + Output.TexCoordY += convergeY * TexelDims.yyy; + + Output.Color = Input.Color; return Output; } diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx index 63d35789393..6fd27a99795 100644 --- a/hlsl/distortion.fx +++ b/hlsl/distortion.fx @@ -119,7 +119,7 @@ uniform float ReflectionAmount = 0.0f; uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° -float2 GetRatioCorrection() +float2 GetScreenQuadRatio() { float ScreenRatio = ScreenDims.x / ScreenDims.y; float QuadRatio = QuadDims.x / QuadDims.y; @@ -130,6 +130,15 @@ float2 GetRatioCorrection() : float2(ScreenQuadRatio, 1.0); } +float2 GetQuadRatio() +{ + float QuadRatio = QuadDims.x / QuadDims.y; + + return QuadRatio > 1.0f + ? float2 (1.0f, 1.0f / QuadRatio) + : float2 (QuadRatio, 1.0f); +} + float GetNoiseFactor(float3 n, float random) { // smaller n become more noisy @@ -138,7 +147,7 @@ float GetNoiseFactor(float3 n, float random) float GetVignetteFactor(float2 coord, float amount) { - float2 VignetteCoord = coord; + float2 VignetteCoord = coord / (QuadDims / ScreenDims); float VignetteLength = length(VignetteCoord); float VignetteBlur = (amount * 0.75f) + 0.25; @@ -152,10 +161,7 @@ float GetVignetteFactor(float2 coord, float amount) float GetSpotAddend(float2 coord, float amount) { - float2 RatioCorrection = GetRatioCorrection(); - - // normalized screen quad ratio - float2 QuadRatio = float2 (1.0f, QuadDims.y / QuadDims.x); + float2 QuadRatio = GetQuadRatio(); // upper right quadrant float2 spotOffset = @@ -167,10 +173,9 @@ float GetSpotAddend(float2 coord, float amount) ? float2(0.25f, 0.25f) : float2(-0.25f, 0.25f); - float2 SpotCoord = coord; - SpotCoord += spotOffset * RatioCorrection; + float2 SpotCoord = coord / (QuadDims / ScreenDims); + SpotCoord += spotOffset * QuadRatio; SpotCoord *= QuadRatio; - SpotCoord /= RatioCorrection; float SpotBlur = amount; @@ -188,7 +193,7 @@ float GetSpotAddend(float2 coord, float amount) float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) { - float2 RatioCorrection = GetRatioCorrection(); + float2 ScreenQuadRatio = GetScreenQuadRatio(); // reduce smooth amount down to radius amount smoothAmount = min(smoothAmount, radiusAmount); @@ -198,7 +203,7 @@ float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) float smooth = 1.0 / (range * max(smoothAmount, 0.0025f)); // compute box - float box = roundBox(ScreenDims * (coord * 2.0f), ScreenDims * RatioCorrection, radius); + float box = roundBox(ScreenDims * (coord * 2.0f), ScreenDims * ScreenQuadRatio, radius); // apply smooth box *= smooth; @@ -235,19 +240,19 @@ float2 GetDistortedCoords(float2 centerCoord, float amount) float2 GetCoords(float2 coord, float distortionAmount) { - float2 RatioCorrection = GetRatioCorrection(); + float2 ScreenQuadRatio = GetScreenQuadRatio(); // center coordinates coord -= 0.5f; // apply ratio difference between screen and quad - coord /= RatioCorrection; + coord /= ScreenQuadRatio; // distort coordinates coord = GetDistortedCoords(coord, distortionAmount); // revert ratio difference between screen and quad - coord *= RatioCorrection; + coord *= ScreenQuadRatio; // un-center coordinates coord += 0.5f; @@ -257,21 +262,18 @@ float2 GetCoords(float2 coord, float distortionAmount) float4 ps_main(PS_INPUT Input) : COLOR { - float2 TexCoord = Input.TexCoord; - float2 BaseCoord = TexCoord; - // Screen Curvature - BaseCoord = GetCoords(BaseCoord, CurvatureAmount * 0.25f); // reduced amount + float2 TexCoord = GetCoords(Input.TexCoord, CurvatureAmount * 0.25f); // reduced amount - float2 BaseCoordCentered = BaseCoord; - BaseCoordCentered -= 0.5f; + float2 TexCoordCentered = TexCoord; + TexCoordCentered -= 0.5f; // Color - float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); + float4 BaseColor = tex2D(DiffuseSampler, TexCoord); BaseColor.a = 1.0f; // Vignetting Simulation - float2 VignetteCoord = BaseCoordCentered; + float2 VignetteCoord = TexCoordCentered; float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); BaseColor.rgb *= VignetteFactor; @@ -279,15 +281,15 @@ float4 ps_main(PS_INPUT Input) : COLOR // Light Reflection Simulation float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin - float2 SpotCoord = BaseCoordCentered; - float2 NoiseCoord = BaseCoordCentered; + float2 SpotCoord = TexCoordCentered; + float2 NoiseCoord = TexCoordCentered; float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); BaseColor.rgb += SpotAddend * NoiseFactor * LightColor; // Round Corners Simulation - float2 RoundCornerCoord = BaseCoordCentered; + float2 RoundCornerCoord = TexCoordCentered; float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount); BaseColor.rgb *= roundCornerFactor; diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx index 122172350f9..fad2ef8341f 100644 --- a/hlsl/downsample.fx +++ b/hlsl/downsample.fx @@ -53,15 +53,24 @@ struct PS_INPUT uniform float2 ScreenDims; uniform float2 TargetDims; +uniform float2 SourceDims; uniform float2 SourceRect; +uniform float2 QuadDims; -uniform bool PrepareVector; +uniform int BloomLevel; + +uniform bool VectorScreen; + +static const float2 Coord0Offset = float2(-0.5f, -0.5f); +static const float2 Coord1Offset = float2( 0.5f, -0.5f); +static const float2 Coord2Offset = float2(-0.5f, 0.5f); +static const float2 Coord3Offset = float2( 0.5f, 0.5f); VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 TargetTexelDims = 1.0f / TargetDims; + float2 HalfTargetTexelDims = 0.5f / TargetDims; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -72,14 +81,12 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; float2 TexCoord = Input.Position.xy / ScreenDims; - TexCoord += PrepareVector - ? 0.5f / TargetDims // half texel offset correction (DX9) - only for vector grpahics - : 0.0f; - - Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelDims; - Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelDims; - Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelDims; - Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelDims; + TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + + Output.TexCoord01.xy = TexCoord + Coord0Offset * HalfTargetTexelDims; + Output.TexCoord01.zw = TexCoord + Coord1Offset * HalfTargetTexelDims; + Output.TexCoord23.xy = TexCoord + Coord2Offset * HalfTargetTexelDims; + Output.TexCoord23.zw = TexCoord + Coord3Offset * HalfTargetTexelDims; return Output; } diff --git a/hlsl/focus.fx b/hlsl/focus.fx index c5e5262fedd..1e2e668911b 100644 --- a/hlsl/focus.fx +++ b/hlsl/focus.fx @@ -51,7 +51,6 @@ struct PS_INPUT uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 SourceRect; uniform float2 QuadDims; VS_OUTPUT vs_main(VS_INPUT Input) @@ -64,7 +63,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - float2 TexCoord = Input.TexCoord; + float2 TexCoord = Input.Position.xy / ScreenDims; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord = TexCoord; @@ -78,30 +77,28 @@ VS_OUTPUT vs_main(VS_INPUT Input) // Defocus Pixel Shader //----------------------------------------------------------------------------- -float2 Coord1Offset = float2( 0.75f, 0.50f); -float2 Coord2Offset = float2( 0.25f, 1.00f); -float2 Coord3Offset = float2(-0.50f, 0.75f); -float2 Coord4Offset = float2(-1.00f, 0.25f); -float2 Coord5Offset = float2(-0.75f, -0.50f); -float2 Coord6Offset = float2(-0.25f, -1.00f); -float2 Coord7Offset = float2( 0.50f, -0.75f); -float2 Coord8Offset = float2( 1.00f, -0.25f); - uniform float2 Defocus = float2(0.0f, 0.0f); uniform bool SwapXY = false; +static const float2 Coord1Offset = float2( 0.75f, 0.50f); +static const float2 Coord2Offset = float2( 0.25f, 1.00f); +static const float2 Coord3Offset = float2(-0.50f, 0.75f); +static const float2 Coord4Offset = float2(-1.00f, 0.25f); +static const float2 Coord5Offset = float2(-0.75f, -0.50f); +static const float2 Coord6Offset = float2(-0.25f, -1.00f); +static const float2 Coord7Offset = float2( 0.50f, -0.75f); +static const float2 Coord8Offset = float2( 1.00f, -0.25f); + float4 ps_main(PS_INPUT Input) : COLOR { - float2 QuadRatio = - float2(1.0f, SwapXY - ? QuadDims.y / QuadDims.x - : QuadDims.x / QuadDims.y); + // we have to handle the swap of the coordinates ourself, because we are using screen not texture coordinates + float2 defocus = SwapXY ? Defocus.yx : Defocus.xy; - // imaginary texel dimensions independed from quad dimensions, but dependend on quad ratio - float2 TexelDims = (1.0f / 1024.0) * SourceRect * QuadRatio; + // imaginary texel dimensions independed from screen dimension, but ratio + float2 TexelDims = (1.0f / 1024) * (QuadDims / ScreenDims); - float2 DefocusTexelDims = Defocus * TexelDims; + float2 DefocusTexelDims = defocus * TexelDims; float4 d = tex2D(DiffuseSampler, Input.TexCoord); float3 d1 = tex2D(DiffuseSampler, Input.TexCoord + Coord1Offset * DefocusTexelDims).rgb; diff --git a/hlsl/ntsc.fx b/hlsl/ntsc.fx index 107be16af16..94460ea6be0 100644 --- a/hlsl/ntsc.fx +++ b/hlsl/ntsc.fx @@ -44,7 +44,7 @@ struct PS_INPUT }; //----------------------------------------------------------------------------- -// YIQ Decode Vertex Shader +// YIQ Vertex Shader //----------------------------------------------------------------------------- uniform float2 ScreenDims; diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx index 7d665b44749..97defea0205 100644 --- a/hlsl/phosphor.fx +++ b/hlsl/phosphor.fx @@ -79,7 +79,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.TexCoord; + Output.TexCoord = Input.Position.xy / ScreenDims; Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.PrevCoord = Output.TexCoord; diff --git a/hlsl/post.fx b/hlsl/post.fx index deec349e2fc..01d83d435ff 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -49,15 +49,17 @@ struct VS_OUTPUT { float4 Position : POSITION; float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; - float2 ScreenCoord : TEXCOORD1; + float2 SourceCoord : TEXCOORD0; + float2 TexCoord : TEXCOORD1; + float2 ScreenCoord : TEXCOORD2; }; struct PS_INPUT { float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; - float2 ScreenCoord : TEXCOORD1; + float2 SourceCoord : TEXCOORD0; + float2 TexCoord : TEXCOORD1; + float2 ScreenCoord : TEXCOORD2; }; //----------------------------------------------------------------------------- @@ -82,33 +84,27 @@ uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); uniform bool SwapXY = false; uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures -uniform bool PrepareVector = false; +uniform bool VectorScreen = false; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 shadowUVOffset = ShadowUVOffset; - shadowUVOffset = SwapXY - ? shadowUVOffset.yx - : shadowUVOffset.xy; - - float2 ScreenCoordOffset = 0.0f; - ScreenCoordOffset += shadowUVOffset; - - Output.ScreenCoord = Input.Position.xy; - Output.ScreenCoord += ScreenCoordOffset; - Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = PrepareVector - ? Input.Position.xy / ScreenDims - : Input.TexCoord; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + Output.TexCoord = Input.Position.xy / ScreenDims; + + Output.TexCoord += PrepareBloom + ? 0.0f / TargetDims // use half texel offset (DX9) to do the blur for first bloom layer + : 0.5f / TargetDims; // fix half texel offset correction (DX9) + + Output.SourceCoord = Input.TexCoord; + + Output.ScreenCoord = Input.Position.xy / ScreenDims; Output.Color = Input.Color; @@ -119,7 +115,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) // Scanline & Shadowmask Pixel Shader //----------------------------------------------------------------------------- -uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC) +uniform float HumBarDesync = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC) uniform float HumBarAlpha = 0.0f; uniform float TimeMilliseconds = 0.0f; @@ -165,36 +161,40 @@ float4 ps_main(PS_INPUT Input) : COLOR { float2 ScreenTexelDims = 1.0f / ScreenDims; float2 SourceTexelDims = 1.0f / SourceDims; - float2 SourceRes = SourceDims * SourceRect; - float2 HalfSourceRect = SourceRect * 0.5f; - - float2 ScreenCoord = Input.ScreenCoord / ScreenDims; - float2 BaseCoord = GetAdjustedCoords(Input.TexCoord, HalfSourceRect); + float2 ScreenCoord = Input.ScreenCoord; + float2 TexCoord = GetAdjustedCoords(Input.TexCoord, 0.5f); + float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord, 0.5f * SourceRect); // Color - float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); + float4 BaseColor = tex2D(DiffuseSampler, TexCoord); BaseColor.a = 1.0f; - if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f) + // keep border + if (!PrepareBloom) { - BaseColor.rgb = 0.0f; + // clip border + clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1); } // Mask Simulation (may not affect bloom) if (!PrepareBloom && ShadowAlpha > 0.0f) { + float2 shadowUVOffset = ShadowUVOffset; + shadowUVOffset = SwapXY + ? ShadowUVOffset.yx + : ShadowUVOffset.xy; + float2 shadowDims = ShadowDims; shadowDims = SwapXY ? shadowDims.yx : shadowDims.xy; float2 shadowUV = ShadowUV; - // shadowUV = SwapXY - // ? shadowUV.yx - // : shadowUV.xy; - float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord; + float2 screenCoord = ShadowTileMode == 0 + ? ScreenCoord + shadowUVOffset / ScreenDims + : SourceCoord + shadowUVOffset / SourceDims; screenCoord = SwapXY ? screenCoord.yx : screenCoord.xy; @@ -204,17 +204,17 @@ float4 ps_main(PS_INPUT Input) : COLOR ? shadowCount.yx : shadowCount.xy; - float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount); + float2 shadowTile = ShadowTileMode == 0 + ? ScreenTexelDims * shadowCount + : SourceTexelDims * shadowCount; shadowTile = SwapXY ? shadowTile.yx : shadowTile.xy; float2 ShadowFrac = frac(screenCoord / shadowTile); + float2 ShadowCoord = (ShadowFrac * shadowUV); ShadowCoord += 0.5f / shadowDims; // half texel offset - // ShadowCoord = SwapXY - // ? ShadowCoord.yx - // : ShadowCoord.xy; float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord); float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha); @@ -242,33 +242,33 @@ float4 ps_main(PS_INPUT Input) : COLOR if (!PrepareBloom) { // Scanline Simulation (may not affect vector screen) - if (!PrepareVector && ScanlineAlpha > 0.0f) + if (!VectorScreen && ScanlineAlpha > 0.0f) { - float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI; - float ScanCoordJitter = ScanlineOffset * PHI; - float ScanSine = sin(ScanCoord + ScanCoordJitter); - float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight); - float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset; + float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha); + float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0f - ScanlineAlpha); - BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha); + float ColorBrightness = 0.299f * BaseColor.r + 0.587f * BaseColor.g + 0.114 * BaseColor.b; + + float ScanlineCoord = SourceCoord.y * SourceDims.y * ScanlineScale * PI; + float ScanlineCoordJitter = ScanlineOffset * PHI; + float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter); + float ScanlineWide = ScanlineHeight + max(1.0f, ScanlineHeight) * (1.0f - ColorBrightness); + float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide); + float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale; + + BaseColor.rgb *= lerp(1.0f, ScanlineBrightness, ScanlineAlpha); } // Hum Bar Simulation (may not affect vector screen) - if (!PrepareVector && HumBarAlpha > 0.0f) + if (!VectorScreen && HumBarAlpha > 0.0f) { - float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate); - float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha; - BaseColor.rgb *= HumBrightness; + float HumBarStep = frac(TimeMilliseconds * HumBarDesync); + float HumBarBrightness = 1.0 - frac(SourceCoord.y / SourceRect.y + HumBarStep) * HumBarAlpha; + BaseColor.rgb *= HumBarBrightness; } } - // Output - float4 Output = PrepareVector - ? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f)) - : BaseColor * Input.Color; - Output.a = 1.0f; - - return Output; + return BaseColor; } //----------------------------------------------------------------------------- diff --git a/hlsl/prescale.fx b/hlsl/prescale.fx index 846c02577ce..419254acd07 100644 --- a/hlsl/prescale.fx +++ b/hlsl/prescale.fx @@ -1,7 +1,11 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Ryan Holtz,Themaister,ImJezze //----------------------------------------------------------------------------- -// Prescale Effect +// Pre-scale Effect +// +// Uses the hardware bilinear interpolator to avoid having to sample 4 times manually. +// +// https://github.com/libretro/common-shaders/blob/master/retro/shaders/sharp-bilinear.cg //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -13,9 +17,9 @@ texture Diffuse; sampler DiffuseSampler = sampler_state { Texture = <Diffuse>; - MipFilter = NONE; - MinFilter = NONE; - MagFilter = NONE; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; @@ -45,39 +49,53 @@ struct PS_INPUT }; //----------------------------------------------------------------------------- -// Prescale Vertex Shader +// Pre-scale Vertex Shader //----------------------------------------------------------------------------- uniform float2 ScreenDims; uniform float2 TargetDims; +uniform float2 SourceDims; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - + Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - + Output.TexCoord = Input.TexCoord; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + // Output.TexCoord += 0.5f / targetDims; // half texel offset correction (DX9) return Output; } //----------------------------------------------------------------------------- -// Prescale Pixel Shader +// Pre-scale Pixel Shader //----------------------------------------------------------------------------- float4 ps_main(PS_INPUT Input) : COLOR { - return tex2D(DiffuseSampler, Input.TexCoord); + float2 Scale = TargetDims / SourceDims; + + float2 TexelDims = Input.TexCoord * SourceDims; + float2 i = floor(TexelDims); + float2 s = frac(TexelDims); + + // Figure out where in the texel to sample to get the correct pre-scaled bilinear. + float2 CenterDistance = s - 0.5f; + float2 RegionRange = 0.5f - 0.5f / Scale; + float2 f = (CenterDistance - clamp(CenterDistance, -RegionRange, RegionRange)) * Scale + 0.5f; + + float2 TexCoord = (i + f) / SourceDims; + + return tex2D(DiffuseSampler, TexCoord); } //----------------------------------------------------------------------------- -// Prescale Technique +// Pre-scale Technique //----------------------------------------------------------------------------- technique DefaultTechnique diff --git a/hlsl/primary.fx b/hlsl/primary.fx index f0a1c1da0e7..2086132a0e7 100644 --- a/hlsl/primary.fx +++ b/hlsl/primary.fx @@ -46,19 +46,36 @@ struct PS_INPUT }; //----------------------------------------------------------------------------- -// Primary Vertex Shader +// Primary Vertex Shaders //----------------------------------------------------------------------------- static const float Epsilon = 1.0e-7f; uniform float2 ScreenDims; uniform float2 TargetDims; +uniform float2 QuadDims; -uniform bool PostPass; +uniform bool VectorScreen; -uniform float Brighten; +VS_OUTPUT vs_screen_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.xy /= ScreenDims; + Output.Position.y = 1.0f - Output.Position.y; // flip y + Output.Position.xy -= 0.5f; // center + Output.Position.xy *= 2.0f; // zoom + + Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + + Output.Color = Input.Color; + + return Output; +} -VS_OUTPUT vs_main(VS_INPUT Input) +VS_OUTPUT vs_vector_buffer_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; @@ -68,14 +85,25 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - float2 targetDims = TargetDims + Epsilon; // bug: with exact target dimensions the font disappears + Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + + Output.Color = Input.Color; + + return Output; +} + +VS_OUTPUT vs_ui_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.xy /= ScreenDims; + Output.Position.y = 1.0f - Output.Position.y; // flip y + Output.Position.xy -= 0.5f; // center + Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = PostPass - ? Input.Position.xy / ScreenDims - : Input.TexCoord; - Output.TexCoord += PostPass - ? 0.5f / targetDims // half texel offset correction (DX9) - : 0.0f; + Output.TexCoord = Input.TexCoord; Output.Color = Input.Color; @@ -83,28 +111,65 @@ VS_OUTPUT vs_main(VS_INPUT Input) } //----------------------------------------------------------------------------- -// Primary Pixel Shader +// Primary Pixel Shaders //----------------------------------------------------------------------------- -float4 ps_main(PS_INPUT Input) : COLOR +float4 ps_screen_main(PS_INPUT Input) : COLOR { float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); - BaseTexel *= Input.Color + float4(Brighten, Brighten, Brighten, 0.0f); + + return BaseTexel; +} + +float4 ps_vector_buffer_main(PS_INPUT Input) : COLOR +{ + float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); + BaseTexel *= Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f); + + return BaseTexel; +} + +float4 ps_ui_main(PS_INPUT Input) : COLOR +{ + float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); + BaseTexel *= Input.Color; return BaseTexel; } //----------------------------------------------------------------------------- -// Primary Technique +// Primary Techniques //----------------------------------------------------------------------------- -technique DefaultTechnique +technique ScreenTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_2_0 vs_screen_main(); + PixelShader = compile ps_2_0 ps_screen_main(); + } +} + +technique VectorBufferTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_2_0 vs_vector_buffer_main(); + PixelShader = compile ps_2_0 ps_vector_buffer_main(); + } +} + +technique UiTechnique { pass Pass0 { Lighting = FALSE; - VertexShader = compile vs_2_0 vs_main(); - PixelShader = compile ps_2_0 ps_main(); + VertexShader = compile vs_2_0 vs_ui_main(); + PixelShader = compile ps_2_0 ps_ui_main(); } } |