summaryrefslogtreecommitdiffstatshomepage
path: root/hlsl
diff options
context:
space:
mode:
Diffstat (limited to 'hlsl')
-rw-r--r--hlsl/bloom.fx72
-rw-r--r--hlsl/distortion.fx330
-rw-r--r--hlsl/downsample.fx19
-rw-r--r--hlsl/focus.fx7
-rw-r--r--hlsl/phosphor.fx14
-rw-r--r--hlsl/post.fx247
-rw-r--r--hlsl/primary.fx17
7 files changed, 437 insertions, 269 deletions
diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx
index e41a663b204..0b3a230bf5b 100644
--- a/hlsl/bloom.fx
+++ b/hlsl/bloom.fx
@@ -172,12 +172,32 @@ struct PS_INPUT
};
//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+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)
+
+//-----------------------------------------------------------------------------
+// Funcions
+//-----------------------------------------------------------------------------
+
+// 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);
+}
+
+//-----------------------------------------------------------------------------
// Bloom Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
-
-uniform float2 Prescale = float2(1.0f, 1.0f);
+uniform float2 TargetDims;
uniform float4 Level01Size;
uniform float4 Level23Size;
@@ -199,15 +219,16 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Color = Input.Color;
float2 TexCoord = Input.Position.xy / ScreenDims;
+ TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord01.xy = TexCoord.xy;
- Output.TexCoord01.zw = TexCoord.xy + Prescale.xy / Level01Size.zw;
- Output.TexCoord23 = TexCoord.xyxy + Prescale.xyxy / Level23Size;
- Output.TexCoord45 = TexCoord.xyxy + Prescale.xyxy / Level45Size;
- Output.TexCoord67 = TexCoord.xyxy + Prescale.xyxy / Level67Size;
- Output.TexCoord89 = TexCoord.xyxy + Prescale.xyxy / Level89Size;
- Output.TexCoordA = TexCoord.xy + Prescale.xy / LevelASize;
-
+ Output.TexCoord01.zw = TexCoord.xy + 0.5f / Level01Size.zw;
+ Output.TexCoord23 = TexCoord.xyxy + 0.5f / Level23Size;
+ Output.TexCoord45 = TexCoord.xyxy + 0.5f / Level45Size;
+ Output.TexCoord67 = TexCoord.xyxy + 0.5f / Level67Size;
+ Output.TexCoord89 = TexCoord.xyxy + 0.5f / Level89Size;
+ Output.TexCoordA = TexCoord.xy + 0.5f / LevelASize;
+
return Output;
}
@@ -219,6 +240,12 @@ uniform float4 Level0123Weight;
uniform float4 Level4567Weight;
uniform float3 Level89AWeight;
+float3 GetNoiseFactor(float3 n, float random)
+{
+ // smaller n become more noisy
+ return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n));
+}
+
float4 ps_main(PS_INPUT Input) : COLOR
{
float3 texel0 = tex2D(DiffuseSampler0, Input.TexCoord01.xy).rgb;
@@ -245,19 +272,22 @@ float4 ps_main(PS_INPUT Input) : COLOR
texel9 = texel9 * Level89AWeight.y;
texelA = texelA * Level89AWeight.z;
- float4 sum = float4(
- texel0 +
- texel1 +
- texel2 +
- texel3 +
+ float3 bloom = float3(
+ texel1 +
+ texel2 +
+ texel3 +
texel4 +
- texel5 +
- texel6 +
- texel7 +
- texel8 +
- texel9 +
- texelA, 1.0f);
- return sum;
+ texel5 +
+ texel6 +
+ texel7 +
+ texel8 +
+ texel9 +
+ texelA);
+
+ float2 NoiseCoord = Input.TexCoord01.xy;
+ float3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
+
+ return float4(texel0 + bloom * NoiseFactor, 1.0f);
}
//-----------------------------------------------------------------------------
diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx
new file mode 100644
index 00000000000..9db6edd4fb5
--- /dev/null
+++ b/hlsl/distortion.fx
@@ -0,0 +1,330 @@
+// license:BSD-3-Clause
+// copyright-holders:ImJezze
+//-----------------------------------------------------------------------------
+// Distortion Effect
+//-----------------------------------------------------------------------------
+
+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;
+};
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+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)
+
+//-----------------------------------------------------------------------------
+// Functions
+//-----------------------------------------------------------------------------
+
+bool xor(bool a, bool b)
+{
+ return (a || b) && !(a && b);
+}
+
+// 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;
+}
+
+//-----------------------------------------------------------------------------
+// Distortion Vertex Shader
+//-----------------------------------------------------------------------------
+
+uniform float2 ScreenDims; // size of the window or fullscreen
+uniform float2 TargetDims;
+uniform float2 QuadDims; // size of the screen quad
+
+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
+//-----------------------------------------------------------------------------
+
+uniform float2 DefaultScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3)
+
+uniform float CurvatureAmount = 0.0f;
+uniform float RoundCornerAmount = 0.0f;
+uniform float SmoothBorderAmount = 0.5f;
+uniform float VignettingAmount = 0.0f;
+uniform float ReflectionAmount = 0.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 int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270°
+
+float2 GetRatioCorrecton()
+{
+ 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);
+}
+
+float GetNoiseFactor(float3 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 = GetRatioCorrecton();
+
+ float2 defaultScreenRatio = xor(OrientationSwapXY, RotationSwapXY)
+ ? DefaultScreenRatio.yx
+ : DefaultScreenRatio.xy;
+
+ // upper right quadrant
+ float2 spotOffset =
+ 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);
+
+ float2 SpotCoord = coord;
+ SpotCoord += spotOffset * defaultScreenRatio * 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 = normalizedSigmoid(Spot, 0.75) * amount;
+
+ // increase strength by 100%
+ SigmoidSpot = SigmoidSpot * 2.0f;
+
+ return saturate(SigmoidSpot);
+}
+
+float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
+{
+ float2 RatioCorrection = GetRatioCorrecton();
+
+ smoothAmount = min(smoothAmount, radiusAmount);
+
+ float2 RoundCornerCoord = coord * 2;
+
+ float MinScreenDims = min(ScreenDims.x, ScreenDims.y);
+
+ float radius = MinScreenDims * 0.5 * max(radiusAmount, 0.01f);
+ float smooth = 1.0 / (MinScreenDims * 0.25 * max(smoothAmount, 0.01f));
+
+ // compute box
+ float box = roundBox(ScreenDims * RoundCornerCoord, ScreenDims * 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 coord, float amount)
+{
+ amount *= 0.25f; // reduced amount
+
+ float2 RatioCorrection = GetRatioCorrecton();
+
+ // center coordinates
+ coord -= 0.5f;
+
+ coord /= RatioCorrection;
+
+ // lens distortion coefficient
+ float k = amount;
+
+ // cubic distortion value
+ float kcube = amount * 2.0f;
+
+ // compute cubic distortion factor
+ float r2 = coord.x * coord.x + coord.y * coord.y;
+ float f = kcube == 0.0f
+ ? 1 + r2 * k
+ : 1 + r2 * (k + kcube * sqrt(r2));
+
+ // correct zoom
+ f /= 1.0f + amount * 0.5f;
+
+ // apply cubic distortion factor
+ coord *= f;
+
+ coord *= RatioCorrection;
+
+ // uncenter coordinates
+ coord += 0.5f;
+
+ return coord;
+}
+
+float4 ps_main(PS_INPUT Input) : COLOR
+{
+ float2 TexCoord = Input.TexCoord;
+ float2 BaseCoord = TexCoord;
+
+ // // test code
+ // // BaseCoord.x += (TexCoord.x > 0.5f ? -0.5f : 0.0f);
+ // BaseCoord.y += (TexCoord.y > 0.5f ? -0.5f : 0.0f);
+ // BaseCoord.y *= 2.0f;
+
+ // Screen Curvature
+ BaseCoord = GetDistortedCoords(BaseCoord, CurvatureAmount);
+
+ float2 BaseCoordCentered = BaseCoord;
+ BaseCoordCentered -= 0.5f;
+
+ // // test code
+ // BaseCoord.y /= 2.0f;
+ // // BaseCoord.x += (TexCoord.x > 0.5f ? +0.5f : 0.0f);
+ // BaseCoord.y += (TexCoord.y > 0.5 ? +0.5f : 0.0f);
+
+ float2 defaultScreenRatio = xor(OrientationSwapXY, RotationSwapXY)
+ ? DefaultScreenRatio.yx
+ : DefaultScreenRatio.xy;
+
+ float2 BaseRatioCoordCentered = BaseCoordCentered;
+ BaseRatioCoordCentered *= defaultScreenRatio;
+
+ // Color
+ float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
+ BaseColor.a = 1.0f;
+
+ // Vignetting Simulation
+ float2 VignetteCoord = BaseCoordCentered;
+
+ float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
+ BaseColor.rgb *= VignetteFactor;
+
+ // Light Reflection Simulation
+ float3 LightColor = float3(1.0f, 0.90f, 0.80f);
+
+ float2 SpotCoord = BaseRatioCoordCentered;
+ float2 NoiseCoord = BaseRatioCoordCentered;
+
+ float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
+ float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
+ BaseColor.rgb += SpotAddend * NoiseFactor * LightColor;
+
+ // Round Corners Simulation
+ float2 RoundCornerCoord = BaseCoordCentered;
+
+ float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, 0);
+ BaseColor.rgb *= roundCornerFactor;
+
+ // // test code
+ // BaseColor.rgb = BaseCoord.x * BaseCoord.y;
+ // BaseColor.rgb = TexCoord.y > 0.5f ? 1.0f : 0.5f;
+
+ return BaseColor;
+}
+
+//-----------------------------------------------------------------------------
+// Distortion Effect
+//-----------------------------------------------------------------------------
+
+technique DistortionTechnique
+{
+ 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/downsample.fx b/hlsl/downsample.fx
index 376e4b8802d..4a4a8fe3743 100644
--- a/hlsl/downsample.fx
+++ b/hlsl/downsample.fx
@@ -48,15 +48,15 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
-uniform float2 TargetSize;
+uniform float2 TargetDims;
-uniform float2 Prescale = float2(1.0f, 1.0f);
+uniform bool PrepareVector;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
- float2 TargetTexelSize = 1.0f / TargetSize;
+ float2 TargetTexelDims = 1.0f / TargetDims;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
@@ -67,11 +67,14 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Color = Input.Color;
float2 TexCoord = Input.Position.xy / ScreenDims;
-
- Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize * Prescale;
- Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize * Prescale;
- Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize * Prescale;
- Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize * Prescale;
+ TexCoord += PrepareVector
+ ? 0.5f / TargetDims // half texel offset correction (DX9)
+ : 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;
return Output;
}
diff --git a/hlsl/focus.fx b/hlsl/focus.fx
index b71bc0dcdc6..39e642b58c4 100644
--- a/hlsl/focus.fx
+++ b/hlsl/focus.fx
@@ -83,8 +83,9 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
-
- float2 TexCoord = Input.TexCoord + 0.5f / TargetDims;
+
+ float2 TexCoord = Input.TexCoord;
+ TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord0 = TexCoord;
Output.TexCoord1 = TexCoord + Coord1Offset * TargetTexelDims * Defocus;
@@ -117,7 +118,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f;
blurred = lerp(d0.rgb, blurred, 1.0f);
-
+
return float4(blurred, d0.a);
}
diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx
index 44b00ac0ee7..13c7700e2e8 100644
--- a/hlsl/phosphor.fx
+++ b/hlsl/phosphor.fx
@@ -68,18 +68,20 @@ uniform bool Passthrough;
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 + 0.5f / TargetDims;
+
+ Output.TexCoord = Input.TexCoord;
+ Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
+
Output.PrevCoord = Output.TexCoord;
Output.Color = Input.Color;
-
+
return Output;
}
@@ -93,13 +95,13 @@ float4 ps_main(PS_INPUT Input) : COLOR
{
float4 CurrPix = tex2D(DiffuseSampler, Input.TexCoord);
float3 PrevPix = tex2D(PreviousSampler, Input.PrevCoord).rgb * float3(Phosphor.r, Phosphor.g, Phosphor.b);
-
+
float RedMax = max(CurrPix.r, PrevPix.r);
float GreenMax = max(CurrPix.g, PrevPix.g);
float BlueMax = max(CurrPix.b, PrevPix.b);
return Passthrough
- ? CurrPix
+ ? CurrPix
: float4(RedMax, GreenMax, BlueMax, CurrPix.a);
}
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();
diff --git a/hlsl/primary.fx b/hlsl/primary.fx
index da9abf028be..130c1cd4706 100644
--- a/hlsl/primary.fx
+++ b/hlsl/primary.fx
@@ -45,24 +45,33 @@ struct PS_INPUT
// Simple Vertex Shader
//-----------------------------------------------------------------------------
+static const float Epsilon = 1.0e-7f;
+
uniform float2 ScreenDims;
+uniform float2 TargetDims;
uniform bool PostPass;
+
uniform float Brighten;
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 = PostPass
+ float2 targetDims = TargetDims + Epsilon; // bug: with exact target dimensions the font disappears
+
+ Output.TexCoord = PostPass
? Input.Position.xy / ScreenDims
: Input.TexCoord;
+ Output.TexCoord += PostPass
+ ? 0.5f / targetDims // half texel offset correction (DX9)
+ : 0.0f;
Output.Color = Input.Color;
@@ -76,7 +85,9 @@ VS_OUTPUT vs_main(VS_INPUT Input)
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
- return BaseTexel * (Input.Color + float4(Brighten, Brighten, Brighten, 0.0f));
+ BaseTexel *= Input.Color + float4(Brighten, Brighten, Brighten, 0.0f);
+
+ return BaseTexel;
}
//-----------------------------------------------------------------------------