summaryrefslogtreecommitdiffstatshomepage
path: root/hlsl
diff options
context:
space:
mode:
Diffstat (limited to 'hlsl')
-rw-r--r--hlsl/bloom.fx85
-rw-r--r--hlsl/downsample.fx47
-rw-r--r--hlsl/focus.fx42
-rw-r--r--hlsl/post.fx365
-rw-r--r--hlsl/simple.fx91
5 files changed, 500 insertions, 130 deletions
diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx
index 69cc930c357..00353498b92 100644
--- a/hlsl/bloom.fx
+++ b/hlsl/bloom.fx
@@ -16,7 +16,7 @@ texture DiffuseK;
sampler DiffuseSampler0 = sampler_state
{
- Texture = <DiffuseA>;
+ Texture = <DiffuseA>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -27,7 +27,7 @@ sampler DiffuseSampler0 = sampler_state
sampler DiffuseSampler1 = sampler_state
{
- Texture = <DiffuseB>;
+ Texture = <DiffuseB>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -38,7 +38,7 @@ sampler DiffuseSampler1 = sampler_state
sampler DiffuseSampler2 = sampler_state
{
- Texture = <DiffuseC>;
+ Texture = <DiffuseC>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -49,7 +49,7 @@ sampler DiffuseSampler2 = sampler_state
sampler DiffuseSampler3 = sampler_state
{
- Texture = <DiffuseD>;
+ Texture = <DiffuseD>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -60,7 +60,7 @@ sampler DiffuseSampler3 = sampler_state
sampler DiffuseSampler4 = sampler_state
{
- Texture = <DiffuseE>;
+ Texture = <DiffuseE>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -71,7 +71,7 @@ sampler DiffuseSampler4 = sampler_state
sampler DiffuseSampler5 = sampler_state
{
- Texture = <DiffuseF>;
+ Texture = <DiffuseF>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -82,7 +82,7 @@ sampler DiffuseSampler5 = sampler_state
sampler DiffuseSampler6 = sampler_state
{
- Texture = <DiffuseG>;
+ Texture = <DiffuseG>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -93,7 +93,7 @@ sampler DiffuseSampler6 = sampler_state
sampler DiffuseSampler7 = sampler_state
{
- Texture = <DiffuseH>;
+ Texture = <DiffuseH>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -104,7 +104,7 @@ sampler DiffuseSampler7 = sampler_state
sampler DiffuseSampler8 = sampler_state
{
- Texture = <DiffuseI>;
+ Texture = <DiffuseI>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -115,7 +115,7 @@ sampler DiffuseSampler8 = sampler_state
sampler DiffuseSampler9 = sampler_state
{
- Texture = <DiffuseJ>;
+ Texture = <DiffuseJ>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -126,7 +126,7 @@ sampler DiffuseSampler9 = sampler_state
sampler DiffuseSamplerA = sampler_state
{
- Texture = <DiffuseK>;
+ Texture = <DiffuseK>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -156,7 +156,6 @@ struct VS_INPUT
float3 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
- float2 Unused : TEXCOORD1;
};
struct PS_INPUT
@@ -174,7 +173,10 @@ struct PS_INPUT
// Bloom Vertex Shader
//-----------------------------------------------------------------------------
-uniform float2 TargetSize;
+uniform float2 ScreenDims;
+
+uniform float2 Prescale = float2(8.0f, 8.0f);
+
uniform float4 Level01Size;
uniform float4 Level23Size;
uniform float4 Level45Size;
@@ -182,22 +184,43 @@ uniform float4 Level67Size;
uniform float4 Level89Size;
uniform float2 LevelASize;
+uniform bool PrepareVector = false;
+
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
-
+
+ float2 ScreenDimsTexel = 1.0f / ScreenDims;
+
+ float2 HalfPrescale = Prescale * 0.5f;
+
Output.Position = float4(Input.Position.xyz, 1.0f);
- Output.Position.xy /= TargetSize;
+ Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
- Output.Position.xy -= float2(0.5f, 0.5f);
- Output.Position.xy *= float2(2.0f, 2.0f);
+ Output.Position.xy -= 0.5f;
+ Output.Position.xy *= 2.0f;
+
Output.Color = Input.Color;
- Output.TexCoord01 = Input.Position.xyxy / TargetSize.xyxy - 0.5f / Level01Size;
- Output.TexCoord23 = Input.Position.xyxy / TargetSize.xyxy - 0.5f / Level23Size;
- Output.TexCoord45 = Input.Position.xyxy / TargetSize.xyxy - 0.5f / Level45Size;
- Output.TexCoord67 = Input.Position.xyxy / TargetSize.xyxy - 0.5f / Level67Size;
- Output.TexCoord89 = Input.Position.xyxy / TargetSize.xyxy - 0.5f / Level89Size;
- Output.TexCoordA = Input.Position.xy / TargetSize - 0.5f / LevelASize;
+
+ // Vector graphics is not prescaled it has the size of the screen
+ if (PrepareVector)
+ {
+ Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level01Size;
+ Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level23Size;
+ Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level45Size;
+ Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level67Size;
+ Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level89Size;
+ Output.TexCoordA = Input.Position.xy / ScreenDims.xy + 1.0f / LevelASize;
+ }
+ else
+ {
+ Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level01Size;
+ Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level23Size;
+ Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level45Size;
+ Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level67Size;
+ Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level89Size;
+ Output.TexCoordA = Input.Position.xy / ScreenDims.xy + HalfPrescale.xy / LevelASize;
+ }
return Output;
}
@@ -236,8 +259,18 @@ float4 ps_main(PS_INPUT Input) : COLOR
texel9 = texel9 * Level89AWeight.y;
texelA = texelA * Level89AWeight.z;
- float4 sum = float4(texel0 + texel1 + texel2 + texel3 + texel4 +
- texel5 + texel6 + texel7 + texel8 + texel9 + texelA, 1.0f);
+ float4 sum = float4(
+ texel0 +
+ texel1 +
+ texel2 +
+ texel3 +
+ texel4 +
+ texel5 +
+ texel6 +
+ texel7 +
+ texel8 +
+ texel9 +
+ texelA, 1.0f);
return sum;
}
@@ -264,6 +297,6 @@ technique TestTechnique
Sampler[10] = <DiffuseSamplerA>; // 2x2
VertexShader = compile vs_3_0 vs_main();
- PixelShader = compile ps_3_0 ps_main();
+ PixelShader = compile ps_3_0 ps_main();
}
}
diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx
index 8d073e4cdb0..cabe6b0bcde 100644
--- a/hlsl/downsample.fx
+++ b/hlsl/downsample.fx
@@ -6,7 +6,7 @@ texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
- Texture = <DiffuseTexture>;
+ Texture = <DiffuseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -32,7 +32,6 @@ struct VS_INPUT
float3 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
- float2 Unused : TEXCOORD1;
};
struct PS_INPUT
@@ -46,26 +45,46 @@ struct PS_INPUT
// Downsample Vertex Shader
//-----------------------------------------------------------------------------
-uniform float2 ScreenSize;
+uniform float2 ScreenDims;
uniform float2 TargetSize;
+
+uniform float2 Prescale = float2(8.0f, 8.0f);
+
uniform float BloomRescale;
+uniform bool PrepareVector = false;
+
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
-
+
+ float2 TargetTexelSize = 1.0f / TargetSize;
+
Output.Position = float4(Input.Position.xyz, 1.0f);
- Output.Position.xy /= ScreenSize;
+ Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.xy -= 0.5f;
Output.Position.xy *= 2.0f;
+
Output.Color = Input.Color;
- float2 InvTargetSize = 1.0f / TargetSize;
- float2 TexCoord = Input.Position.xy / ScreenSize;
- Output.TexCoord01.xy = TexCoord + float2(0.5f, 0.5f) * InvTargetSize;
- Output.TexCoord01.zw = TexCoord + float2(1.5f, 0.5f) * InvTargetSize;
- Output.TexCoord23.xy = TexCoord + float2(0.5f, 1.5f) * InvTargetSize;
- Output.TexCoord23.zw = TexCoord + float2(1.5f, 1.5f) * InvTargetSize;
+
+ float2 TexCoord = Input.Position.xy / ScreenDims;
+
+ // Vector graphics is not prescaled it has the size of the screen
+ if (PrepareVector)
+ {
+ Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize;
+ Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize;
+ Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize;
+ Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize;
+ }
+ else
+ {
+ 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;
+ }
return Output;
}
@@ -80,7 +99,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 texel1 = tex2D(DiffuseSampler, Input.TexCoord01.zw);
float4 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy);
float4 texel3 = tex2D(DiffuseSampler, Input.TexCoord23.zw);
- float4 outTexel = (texel0 + texel1 + texel2 + texel3) * BloomRescale;
+
+ float4 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0 * BloomRescale;
+
return float4(outTexel.rgb, 1.0f);
}
@@ -97,6 +118,6 @@ technique TestTechnique
Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_2_0 vs_main();
- PixelShader = compile ps_2_0 ps_main();
+ PixelShader = compile ps_2_0 ps_main();
}
}
diff --git a/hlsl/focus.fx b/hlsl/focus.fx
index 6cb8cbdc56f..0e0c64a43c0 100644
--- a/hlsl/focus.fx
+++ b/hlsl/focus.fx
@@ -6,7 +6,7 @@ texture Diffuse;
sampler DiffuseSampler = sampler_state
{
- Texture = <Diffuse>;
+ Texture = <Diffuse>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -59,8 +59,11 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
+
uniform float2 Defocus = float2(0.0f, 0.0f);
+uniform float2 Prescale = float2(8.0f, 8.0f);
+
float2 Coord0Offset = float2( 0.0f, 0.0f);
float2 Coord1Offset = float2(-0.2f, -0.6f);
float2 Coord2Offset = float2( 0.4f, -0.4f);
@@ -73,24 +76,31 @@ float2 Coord7Offset = float2(-0.6f, -0.4f);
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
-
+
+ float2 ScreenTexelDims = 1.0f / ScreenDims;
+
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.xy -= 0.5f;
- Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
- Output.Color = Input.Color;
+ Output.Position.xy *= 2.0f;
+
+ // todo: there is an offset which can be noticed at lower prescale in high-resolution
+ float2 FocusPrescaleOffset = ScreenTexelDims / Prescale;
- float2 InvTexSize = 1.0f / ScreenDims;
float2 TexCoord = Input.TexCoord;
- Output.TexCoord0 = TexCoord + Coord0Offset * InvTexSize * Defocus;
- Output.TexCoord1 = TexCoord + Coord1Offset * InvTexSize * Defocus;
- Output.TexCoord2 = TexCoord + Coord2Offset * InvTexSize * Defocus;
- Output.TexCoord3 = TexCoord + Coord3Offset * InvTexSize * Defocus;
- Output.TexCoord4 = TexCoord + Coord4Offset * InvTexSize * Defocus;
- Output.TexCoord5 = TexCoord + Coord5Offset * InvTexSize * Defocus;
- Output.TexCoord6 = TexCoord + Coord6Offset * InvTexSize * Defocus;
- Output.TexCoord7 = TexCoord + Coord7Offset * InvTexSize * Defocus;
+ TexCoord += FocusPrescaleOffset;
+
+ Output.TexCoord0 = TexCoord + Coord0Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord1 = TexCoord + Coord1Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord2 = TexCoord + Coord2Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord3 = TexCoord + Coord3Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord4 = TexCoord + Coord4Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord5 = TexCoord + Coord5Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord6 = TexCoord + Coord6Offset * ScreenTexelDims * Defocus;
+ Output.TexCoord7 = TexCoord + Coord7Offset * ScreenTexelDims * Defocus;
+
+ Output.Color = Input.Color;
return Output;
}
@@ -114,6 +124,10 @@ float4 ps_main(PS_INPUT Input) : COLOR
blurred = lerp(d0.rgb, blurred, 1.0f);
return float4(blurred, d0.a);
+
+ // float4 texel = tex2D(DiffuseSampler, Input.TexCoord0);
+
+ // return float4(texel.rgb, 1.0f);
}
//-----------------------------------------------------------------------------
@@ -129,6 +143,6 @@ technique TestTechnique
Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_2_0 vs_main();
- PixelShader = compile ps_2_0 ps_main();
+ PixelShader = compile ps_2_0 ps_main();
}
}
diff --git a/hlsl/post.fx b/hlsl/post.fx
index 89a92fd6969..07b0aa92dbb 100644
--- a/hlsl/post.fx
+++ b/hlsl/post.fx
@@ -6,7 +6,7 @@ texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
- Texture = <DiffuseTexture>;
+ Texture = <DiffuseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -19,7 +19,7 @@ texture ShadowTexture;
sampler ShadowSampler = sampler_state
{
- Texture = <ShadowTexture>;
+ Texture = <ShadowTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
@@ -32,46 +32,70 @@ sampler ShadowSampler = sampler_state
// Vertex Definitions
//-----------------------------------------------------------------------------
-struct VS_OUTPUT
+struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
-struct VS_INPUT
+struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
- float2 Unused : TEXCOORD1;
+ float2 ScreenCoord : TEXCOORD1;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
+ float2 ScreenCoord : TEXCOORD1;
};
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Vertex Shader
//-----------------------------------------------------------------------------
-uniform float2 ScreenDims;
-uniform float2 SourceDims;
-uniform float2 SourceRect;
+uniform float2 ScreenDims; // size of the window or fullscreen
+uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f);
+
+uniform float2 SourceDims; // size of the texture in power-of-two size
+uniform float2 SourceRect; // size of the uv rectangle
+
+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
+uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
-
+
+ float2 ScreenTexelDims = 1.0f / ScreenDims;
+ float2 SourceTexelDims = 1.0f / SourceDims;
+
+ // todo: calculate offset
+ float2 ScreenCoordPrescaleOffset = 0.0f;
+ ScreenCoordPrescaleOffset += ShadowUVOffset;
+
+ Output.ScreenCoord = Input.Position;
+ Output.ScreenCoord += ScreenCoordPrescaleOffset;
+
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
- Output.Position.y = 1.0f - Output.Position.y;
- Output.Position.xy -= 0.5f;
- Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
+ 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 -= SourceTexelDims * 0.5f;
+
Output.Color = Input.Color;
- Output.TexCoord = Input.TexCoord + 0.5f / SourceDims;
return Output;
}
@@ -80,90 +104,277 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// Post-Processing Pixel Shader
//-----------------------------------------------------------------------------
-uniform float PI = 3.14159265f;
-
-uniform float PincushionAmount = 0.00f;
-uniform float CurvatureAmount = 0.08f;
-
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 = 0.5f;
+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(320.0f, 240.0f);
-uniform float2 ShadowUV = float2(0.375f, 0.375f);
-uniform float2 ShadowDims = float2(8.0f, 8.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);
+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);
+}
+
+// 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);
+}
+
+// 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 VignetteBlur = amount * 2.0f;
+
+ // 0.5 full screen fitting circle
+ float VignetteRadius = 1.0f - amount * 0.5f;
+ float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, length(VignetteCoord));
+
+ // reduce strength to 50%
+ Vignette = lerp(1.0, 1.0 * Vignette, 0.5f);
+
+ 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)
+{
+ float2 HalfSourceDims = SourceDims * 0.5f;
+ float2 SourceTexelDims = 1.0f / SourceDims;
+
+ float2 RoundCoord = coord;
+
+ // bug: offset and scale correction (due to miss-aligned fullscreen quad)
+ RoundCoord *= (1.0f + SourceTexelDims * ScreenRatio * 2.0f);
+ RoundCoord -= SourceTexelDims * ScreenRatio;
+
+ // hint: roundness correction (base on the default ratio of 4:3)
+ RoundCoord *= SourceDims / ScreenRatio;
+
+ float radius = amount * 50.0f;
+
+ // compute box
+ float box = RoundBox(RoundCoord.xy, HalfSourceDims / ScreenRatio, radius);
+
+ float solidBorder = smoothstep(1.0f, 0.5f, box);
+
+ // apply blur
+ float blur = 1.0f / max(2.0f, amount * 100.0f); // blur amount
+ box *= blur * 2.0f; // blur stength
+ box += 1.0f - pow(blur * 0.5f, 0.5f); // blur offset
+
+ float blurBorder = smoothstep(1.0f, 0.5f, box);
+
+ float border = solidBorder * (blurBorder + 0.5f);
+
+ return saturate(border);
+}
+
float4 ps_main(PS_INPUT Input) : COLOR
{
+ float2 ScreenTexelDims = 1.0f / ScreenDims;
+
float2 UsedArea = 1.0f / SourceRect;
float2 HalfRect = SourceRect * 0.5f;
- float2 R2 = 1.0f / pow(length(UsedArea), 2.0f);
- // -- Screen Pincushion Calculation --
- float2 PinUnitCoord = Input.TexCoord * UsedArea * 2.0f - 1.0f;
- float PincushionR2 = pow(length(PinUnitCoord), 2.0f) * R2;
- float2 PincushionCurve = PinUnitCoord * PincushionAmount * PincushionR2;
+
+ // Screen Curvature
+ float2 CurvatureUnitCoord = Input.TexCoord * (UsedArea * 2.0f) - 1.0f;
+ float2 CurvatureCurve =
+ CurvatureAmount * 0.25f
+ * CurvatureUnitCoord
+ * pow(length(CurvatureUnitCoord), 2.0f)
+ / pow(length(UsedArea), 2.0f);
+ float2 CurvatureZoom = 1.0f - (CurvatureAmount * 0.25f) * (UsedArea * 0.5f);
+
+ float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
+ ScreenCoord -= HalfRect;
+ ScreenCoord *= CurvatureZoom; // zoom
+ ScreenCoord += HalfRect;
+ ScreenCoord += CurvatureCurve; // distortion
+
float2 BaseCoord = Input.TexCoord;
- float2 ScanCoord = BaseCoord - 0.5f / ScreenDims;
-
BaseCoord -= HalfRect;
- BaseCoord *= 1.0f - PincushionAmount * UsedArea * 0.2f; // Warning: Magic constant
+ BaseCoord *= CurvatureZoom; // zoom
BaseCoord += HalfRect;
- BaseCoord += PincushionCurve;
-
- ScanCoord -= HalfRect;
- ScanCoord *= 1.0f - PincushionAmount * UsedArea * 0.2f; // Warning: Magic constant
- ScanCoord += HalfRect;
- ScanCoord += PincushionCurve;
-
- float2 CurveClipUnitCoord = Input.TexCoord * UsedArea * 2.0f - 1.0f;
- float CurvatureClipR2 = pow(length(CurveClipUnitCoord), 2.0f) * R2;
- float2 CurvatureClipCurve = CurveClipUnitCoord * CurvatureAmount * CurvatureClipR2;
- float2 ScreenClipCoord = Input.TexCoord;
- ScreenClipCoord -= HalfRect;
- ScreenClipCoord *= 1.0f - CurvatureAmount * UsedArea * 0.2f; // Warning: Magic constant
- ScreenClipCoord += HalfRect;
- ScreenClipCoord += CurvatureClipCurve;
-
- // RGB Pincushion Calculation
- float3 PincushionCurveX = PinUnitCoord.x * PincushionAmount * PincushionR2;
- float3 PincushionCurveY = PinUnitCoord.y * PincushionAmount * PincushionR2;
-
- float4 BaseTexel = tex2D(DiffuseSampler, BaseCoord);
-
- // -- Alpha Clipping (1px border in drawd3d does not work for some reason) --
- clip((BaseCoord < 1.0f / SourceDims) ? -1 : 1);
- clip((BaseCoord > (SourceRect + 1.0f / SourceDims)) ? -1 : 1);
-
- // -- Scanline Simulation --
- float InnerSine = ScanCoord.y * SourceDims.y * ScanlineScale;
- float ScanBrightMod = sin(InnerSine * PI + ScanlineOffset * SourceDims.y);
- float3 ScanBrightness = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f) * 0.5f, ScanlineAlpha);
- float3 Scanned = BaseTexel.rgb * ScanBrightness;
-
- // -- Color Compression (increasing the floor of the signal without affecting the ceiling) --
- Scanned = Floor + (1.0f - Floor) * Scanned;
-
- // Shadow mask
- // Note: This is broken right now and needs fixed
- float2 ShadowFrac = frac(BaseCoord * ShadowCount);
- float2 ShadowCoord = ShadowFrac * ShadowUV + 0.5f / ShadowDims;
- float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord).rgb, ShadowAlpha);
+ BaseCoord += CurvatureCurve; // distortion
+
+ float2 BaseCoordCentered = Input.TexCoord;
+ BaseCoordCentered -= HalfRect;
+ BaseCoordCentered *= CurvatureZoom; // zoom
+ BaseCoordCentered += CurvatureCurve; // distortion
+
+ // float2 BaseAreaRatioCoord = BaseCoord;
+ // BaseAreaRatioCoord *= UsedArea * ScreenRatio;
+
+ float2 BaseAreaRatioCoordCentered = BaseCoordCentered;
+ BaseAreaRatioCoordCentered *= UsedArea * ScreenRatio;
+
+ // float2 BaseAreaCoord = BaseCoord;
+ // BaseAreaCoord *= UsedArea;
+
+ float2 BaseAreaCoordCentered = BaseCoordCentered;
+ BaseAreaCoordCentered *= UsedArea;
+
+ // Alpha Clipping (1px border in drawd3d does not work for some reason)
+ clip(BaseCoord < ScreenTexelDims ? -1 : 1);
+ clip(BaseCoord > SourceRect + ScreenTexelDims ? -1 : 1);
+
+ float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
+ BaseColor.a = 1.0f;
+
+ // Vignetting Simulation (may affect bloom)
+ float2 VignetteCoord = BaseAreaRatioCoordCentered;
+
+ float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
+ BaseColor.rgb *= VignetteFactor;
+
+ // Mask Simulation (may not affect bloom)
+ if (!PrepareBloom)
+ {
+ float2 ShadowTexelDims = 1.0f / ShadowDims;
+ ShadowTexelDims = OrientationSwapXY
+ ? ShadowTexelDims.yx
+ : ShadowTexelDims.xy;
- // -- Final Pixel --
- float4 Output = float4(Scanned * ShadowTexel, BaseTexel.a) * Input.Color;
+ float2 shadowUV = ShadowUV;
+ shadowUV = OrientationSwapXY
+ ? shadowUV.yx
+ : shadowUV.xy;
- Output.r = pow(Output.r, Power.r);
- Output.g = pow(Output.g, Power.g);
- Output.b = pow(Output.b, Power.b);
+ float2 screenCoord = ScreenCoord;
+ screenCoord = OrientationSwapXY
+ ? screenCoord.yx
+ : screenCoord.xy;
+
+ float2 shadowTile = (ScreenTexelDims * ShadowCount);
+ shadowTile = OrientationSwapXY
+ ? shadowTile.yx
+ : shadowTile.xy;
+
+ float2 ShadowFrac = frac(screenCoord / shadowTile);
+ float2 ShadowCoord = (ShadowFrac * shadowUV);
+ ShadowCoord += ShadowTexelDims * 0.5f; // half texel offset
+ ShadowCoord = OrientationSwapXY
+ ? ShadowCoord.yx
+ : ShadowCoord.xy;
+
+ float3 ShadowColor = tex2D(ShadowSampler, ShadowCoord).rgb;
+ ShadowColor = lerp(1.0f, ShadowColor, ShadowAlpha);
+
+ BaseColor.rgb *= ShadowColor;
+ }
+
+ // 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)
+ {
+ // todo: there is an offset which can be noticed at lower prescale in high-resolution
+ float2 ScanlinePrescaleOffset = 0.0f;
+
+ float InnerSine = BaseCoordCentered.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;
+ }
+
+ // Output
+ float4 Output = 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;
}
@@ -180,6 +391,6 @@ technique ScanMaskTechnique
//Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_3_0 vs_main();
- PixelShader = compile ps_3_0 ps_main();
+ PixelShader = compile ps_3_0 ps_main();
}
-}
+} \ No newline at end of file
diff --git a/hlsl/simple.fx b/hlsl/simple.fx
new file mode 100644
index 00000000000..9f510ea9c73
--- /dev/null
+++ b/hlsl/simple.fx
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------------
+// Effect File Variables
+//-----------------------------------------------------------------------------
+
+texture DiffuseTexture;
+
+sampler DiffuseSampler = sampler_state
+{
+ Texture = <DiffuseTexture>;
+ MipFilter = LINEAR;
+ MinFilter = LINEAR;
+ MagFilter = LINEAR;
+ AddressU = CLAMP;
+ AddressV = CLAMP;
+ AddressW = CLAMP;
+};
+
+//-----------------------------------------------------------------------------
+// Vertex Definitions
+//-----------------------------------------------------------------------------
+
+struct VS_OUTPUT
+{
+ float4 Position : POSITION;
+ float4 Color : COLOR0;
+ float2 TexCoord : TEXCOORD0;
+};
+
+struct VS_INPUT
+{
+ float3 Position : POSITION;
+ float4 Color : COLOR0;
+ float2 TexCoord : TEXCOORD0;
+};
+
+struct PS_INPUT
+{
+ float4 Color : COLOR0;
+ float2 TexCoord : TEXCOORD0;
+};
+
+//-----------------------------------------------------------------------------
+// Simple Vertex Shader
+//-----------------------------------------------------------------------------
+
+uniform float2 ScreenDims;
+
+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.Position.xy / ScreenDims;
+
+ Output.Color = Input.Color;
+
+ return Output;
+}
+
+//-----------------------------------------------------------------------------
+// Simple Pixel Shader
+//-----------------------------------------------------------------------------
+
+float4 ps_main(PS_INPUT Input) : COLOR
+{
+ float4 texel = tex2D(DiffuseSampler, Input.TexCoord);
+
+ return float4(texel.rgb, 1.0f);
+}
+
+//-----------------------------------------------------------------------------
+// Simple Effect
+//-----------------------------------------------------------------------------
+
+technique TestTechnique
+{
+ pass Pass0
+ {
+ Lighting = FALSE;
+
+ Sampler[0] = <DiffuseSampler>;
+
+ VertexShader = compile vs_2_0 vs_main();
+ PixelShader = compile ps_2_0 ps_main();
+ }
+}