summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ImJezze <jezze@gmx.net>2015-05-03 14:41:05 +0200
committer ImJezze <jezze@gmx.net>2015-05-03 14:41:05 +0200
commita70198a5fb532f1b5826bcc0a318c1d68291c0c4 (patch)
treeab035722cba9050061facc24ed893872ea4a5abf
parentcc3b682e52bf097d31db78032aad01d6a0b12e94 (diff)
HLSL shader improvements
- changed shadow mask implementation, shadow count XY now represent the number of pixel the shadow UV sized tiles will take on the screen - implemented rotation of the shadow mask texture depending on the default landscape or portrait view of the screen - removed prescale and pixel border of the shadow mask texture - added option to change the shadow UV offset, to reduce the color bleeding of the shadow mask - adjusted presets to work with the changed mask implementation - reduced defocus offset - improved downsampling for better blurring - improved alignment of bloom layers (raster and vector) - applied bloom effect to the render output of screenshot and AVI recording - changed curvature effect to fit screen size - changed scanlines to be not rendered into bloom layers - changed shadow mask to be not rendered into bloom layers - changed color floor to not light the bloom layers - changed shadow mask to not dark the color floor - added image vignetting simulation and option - added round screen corner simulation and option - added screen light reflection simulation and option - made usage of unused brightness offset (additive) - removed unused pincushion option - removed duplicate shadow count Y options - removed artwork/adapture.png - added artwork/adapture-grill.png - added artwork/shadow-mask.png - added artwork/slot-mask.png - added hlsl/simple.fx - removed unused shaders::blit() function - added shaders::screen_pass() function, which handles the (raster-)rendering on screen, into screenshot and AVI recording - added effect:set_bool() function
-rw-r--r--artwork/adapture-grill.pngbin0 -> 19734 bytes
-rw-r--r--artwork/aperture.pngbin271 -> 0 bytes
-rw-r--r--artwork/shadow-mask.pngbin0 -> 20397 bytes
-rw-r--r--artwork/slot-mask.pngbin0 -> 19768 bytes
-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
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h1
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.c393
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h24
-rw-r--r--src/osd/modules/render/drawd3d.c78
-rw-r--r--src/osd/windows/winmain.c16
-rw-r--r--src/osd/windows/winmain.h12
15 files changed, 801 insertions, 353 deletions
diff --git a/artwork/adapture-grill.png b/artwork/adapture-grill.png
new file mode 100644
index 00000000000..052b300f241
--- /dev/null
+++ b/artwork/adapture-grill.png
Binary files differ
diff --git a/artwork/aperture.png b/artwork/aperture.png
deleted file mode 100644
index 2243dc52c6e..00000000000
--- a/artwork/aperture.png
+++ /dev/null
Binary files differ
diff --git a/artwork/shadow-mask.png b/artwork/shadow-mask.png
new file mode 100644
index 00000000000..0c04c5f92fa
--- /dev/null
+++ b/artwork/shadow-mask.png
Binary files differ
diff --git a/artwork/slot-mask.png b/artwork/slot-mask.png
new file mode 100644
index 00000000000..5f4d41dbcd7
--- /dev/null
+++ b/artwork/slot-mask.png
Binary files differ
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();
+ }
+}
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index dd5e6b5f86c..399df12ad00 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -149,6 +149,7 @@ public:
private:
void prescale();
void compute_size(int texwidth, int texheight);
+ void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height);
texture_manager * m_texture_manager; // texture manager pointer
diff --git a/src/osd/modules/render/d3d/d3dhlsl.c b/src/osd/modules/render/d3d/d3dhlsl.c
index 733ccfe0723..3df21003c17 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.c
+++ b/src/osd/modules/render/d3d/d3dhlsl.c
@@ -59,8 +59,8 @@ hlsl_options shaders::s_hlsl_presets[4] =
{
{ // 25% Shadow mask, 50% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
true,
- 0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
- 0.03f, 0.03f,
+ 0.25f, { "adapture-grill.png" }, 6, 6, 0.1875f, 0.1875f, 0.0f, 0.0f,
+ 0.03f, 0.03f, 0.03f, 0.03f,
0.5f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
{ 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f },
@@ -82,8 +82,8 @@ hlsl_options shaders::s_hlsl_presets[4] =
},
{ // 25% Shadow mask, 0% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
true,
- 0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
- 0.03f, 0.03f,
+ 0.25f, { "adapture-grill.png" }, 6, 6, 0.1875f, 0.1875f, 0.0f, 0.0f,
+ 0.03f, 0.03f, 0.03f, 0.03f,
0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
{ 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f },
@@ -105,8 +105,8 @@ hlsl_options shaders::s_hlsl_presets[4] =
},
{ // 25% Shadow mask, 0% Scanlines, 0% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
true,
- 0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
- 0.0f, 0.0f,
+ 0.25f, { "adapture-grill.png" }, 6, 6, 0.1875f, 0.1875f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
{ 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f },
@@ -128,8 +128,8 @@ hlsl_options shaders::s_hlsl_presets[4] =
},
{ // 25% Shadow mask, 100% Scanlines, 15% Pincushion, 3 defocus, 24-degree Tint Out, 1.5 Exponent, 5% Floor, 70% Phosphor Return, 80% Saturation, Bad Convergence
true,
- 0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
- 0.15f, 0.15f,
+ 0.25f, { "adapture-grill.png" }, 6, 6, 0.1875f, 0.1875f, 0.0f, 0.0f,
+ 0.15f, 0.15f, 0.15f, 0.15f,
1.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f,
{ 3.0f, 3.0f },
{ 0.5f,-0.33f,0.7f },
@@ -736,8 +736,12 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende
options->shadow_mask_count_y = winoptions.screen_shadow_mask_count_y();
options->shadow_mask_u_size = winoptions.screen_shadow_mask_u_size();
options->shadow_mask_v_size = winoptions.screen_shadow_mask_v_size();
+ options->shadow_mask_u_offset = winoptions.screen_shadow_mask_u_offset();
+ options->shadow_mask_v_offset = winoptions.screen_shadow_mask_v_offset();
options->curvature = winoptions.screen_curvature();
- options->pincushion = winoptions.screen_pincushion();
+ options->round_corner = winoptions.screen_round_corner();
+ options->reflection = winoptions.screen_reflection();
+ options->vignetting = winoptions.screen_vignetting();
options->scanline_alpha = winoptions.screen_scanline_amount();
options->scanline_scale = winoptions.screen_scanline_scale();
options->scanline_height = winoptions.screen_scanline_height();
@@ -930,14 +934,14 @@ int shaders::create_resources(bool reset)
texture.palette = NULL;
texture.seqid = 0;
- // FIXME: should shadow bitmap really use prescale?
- // now create it
- shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, video_config.prescale, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ // now create it (no prescale, but wrap)
+ shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_TEXWRAP_MASK);
}
const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
+ simple_effect = new effect(this, d3d->get_device(), "simple.fx", fx_dir);
post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir);
prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
@@ -951,6 +955,7 @@ int shaders::create_resources(bool reset)
vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
if (!default_effect->is_valid()) return 1;
+ if (!simple_effect->is_valid()) return 1;
if (!post_effect->is_valid()) return 1;
if (!prescale_effect->is_valid()) return 1;
if (!phosphor_effect->is_valid()) return 1;
@@ -1017,18 +1022,27 @@ int shaders::create_resources(bool reset)
phosphor_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
- phosphor_effect->add_uniform("Passthrough", uniform::UT_FLOAT, uniform::CU_PHOSPHOR_IGNORE);
+ phosphor_effect->add_uniform("Passthrough", uniform::UT_FLOAT, uniform::CU_PHOSPHOR_IGNORE);
+
+ downsample_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
+
+ bloom_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
+
+ simple_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
post_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
post_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
- post_effect->add_uniform("PincushionAmount", uniform::UT_FLOAT, uniform::CU_POST_PINCUSHION);
+ post_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING);
post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE);
+ post_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER);
+ post_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION);
post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
+ post_effect->add_uniform("ShadowUVOffset", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV_OFFSET);
post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
@@ -1038,6 +1052,10 @@ int shaders::create_resources(bool reset)
post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
+
+ vector_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
+
+ default_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
initialized = true;
@@ -1057,6 +1075,7 @@ void shaders::begin_draw()
curr_effect = default_effect;
default_effect->set_technique("TestTechnique");
+ simple_effect->set_technique("TestTechnique");
post_effect->set_technique("ScanMaskTechnique");
phosphor_effect->set_technique("TestTechnique");
focus_effect->set_technique("TestTechnique");
@@ -1085,49 +1104,6 @@ void shaders::begin_frame()
//============================================================
void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
- UINT32 prim_index, UINT32 prim_count, int dstw, int dsth)
-{
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
-
- curr_effect = default_effect;
-
- curr_effect->set_texture("Diffuse", src);
-
- float dst_dims[2] = { (float)dstw, (float)dsth };
- curr_effect->set_vector("ScreenDims", 2, dst_dims);
- curr_effect->set_float("PostPass", 1.0f);
- curr_effect->set_float("PincushionAmount", options->pincushion);
- curr_effect->set_float("Brighten", 0.0f);
-
- unsigned int num_passes = 0;
- curr_effect->begin(&num_passes, 0);
-
- for (UINT pass = 0; pass < num_passes; pass++)
- {
- curr_effect->begin_pass(pass);
- // add the primitives
- HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
- curr_effect->end_pass();
- }
-
- curr_effect->end();
-
- if (new_dst)
- {
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
- }
-}
-
-
-
-//============================================================
-// shaders::blit
-//============================================================
-
-void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
UINT32 prim_index, UINT32 prim_count)
{
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
@@ -1136,13 +1112,10 @@ void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYP
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
curr_effect = default_effect;
+ curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", src);
-
- vec2f screendims = d3d->get_dims();
- curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
curr_effect->set_float("PostPass", 1.0f);
- curr_effect->set_float("PincushionAmount", options->pincushion);
curr_effect->set_float("Brighten", 1.0f);
unsigned int num_passes = 0;
@@ -1433,10 +1406,13 @@ void shaders::defocus_pass(render_target *rt, vec2f &texsize)
{
UINT num_passes = 0;
+ float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y };
+
// Defocus pass 1
curr_effect = focus_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->render_texture[2]);
+ curr_effect->set_vector("Prescale", 2, prescale);
curr_effect->begin(&num_passes, 0);
@@ -1481,13 +1457,13 @@ void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize,
{
UINT num_passes = 0;
- curr_effect = phosphor_effect;
phosphor_passthrough = false;
+
+ curr_effect = phosphor_effect;
curr_effect->update_uniforms();
float rtsize[2] = { rt->target_width, rt->target_height };
curr_effect->set_vector("TargetDims", 2, rtsize);
-
curr_effect->set_texture("Diffuse", focus_enable ? rt->render_texture[1] : rt->render_texture[2]);
curr_effect->set_texture("LastPass", ct->last_texture);
@@ -1534,73 +1510,26 @@ void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize,
curr_effect->end();
}
-void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
+void shaders::post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom)
{
UINT num_passes = 0;
- curr_effect = post_effect;
- curr_effect->update_uniforms();
- curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
-
- // Scanlines and shadow mask, at high res for AVI logging
- if(avi_output_file != NULL)
- {
- curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
-
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, avi_final_target);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
-
- curr_effect->begin(&num_passes, 0);
-
- for (UINT pass = 0; pass < num_passes; pass++)
- {
- curr_effect->begin_pass(pass);
- // add the primitives
- result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
- curr_effect->end_pass();
- }
-
- curr_effect->end();
- }
-
- if(render_snap)
- {
- curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
-
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, snap_target);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
-
- curr_effect->begin(&num_passes, 0);
-
- for (UINT pass = 0; pass < num_passes; pass++)
- {
- curr_effect->begin_pass(pass);
- // add the primitives
- result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
- curr_effect->end_pass();
- }
-
- curr_effect->end();
-
- snap_rendered = true;
- }
-}
-
-void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
-{
- UINT num_passes = 0;
+ float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y };
+ bool orientation_swap_xy = (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
curr_effect = post_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
-
curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
+ curr_effect->set_vector("Prescale", 2, prescale);
+ curr_effect->set_bool("ShadowSwapXY", orientation_swap_xy);
+ curr_effect->set_bool("PrepareBloom", prepare_bloom);
d3d->set_wrap(D3DTADDRESS_MIRROR);
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
+ HRESULT result = prepare_bloom
+ ? (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]) // target which is used by bloom effect
+ : (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@@ -1621,21 +1550,21 @@ void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta,
d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
}
-void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
+void shaders::bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
{
UINT num_passes = 0;
- curr_effect = downsample_effect;
+ float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y };
- curr_effect->set_texture("Diffuse", rt->render_texture[2]);
+ curr_effect = downsample_effect;
+ curr_effect->update_uniforms();
curr_effect->set_float("BloomRescale", options->raster_bloom_scale);
+ curr_effect->set_vector("Prescale", 2, prescale);
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
int bloom_index = 0;
float bloom_width = rt->target_width;
float bloom_height = rt->target_height;
- vec2f screendims = d3d->get_dims();
- curr_effect->set_vector("ScreenSize", 2, &screendims.c.x);
float bloom_dims[11][2];
for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
{
@@ -1645,7 +1574,7 @@ void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta,
curr_effect->begin(&num_passes, 0);
- curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[2] : rt->bloom_texture[bloom_index - 1]);
+ curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[3] : rt->bloom_texture[bloom_index - 1]);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
@@ -1670,9 +1599,8 @@ void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta,
}
curr_effect = bloom_effect;
+ curr_effect->update_uniforms();
- float target_size[2] = { d3d->get_width(), d3d->get_height() };
- curr_effect->set_vector("TargetSize", 2, target_size);
float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
@@ -1688,6 +1616,8 @@ void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta,
curr_effect->set_texture("DiffuseA", rt->render_texture[2]);
+ curr_effect->set_vector("Prescale", 2, prescale);
+
char name[9] = "Diffuse*";
for(int index = 1; index < bloom_index; index++)
{
@@ -1702,8 +1632,10 @@ void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta,
curr_effect->begin(&num_passes, 0);
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
+ HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
+ result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
for (UINT pass = 0; pass < num_passes; pass++)
{
@@ -1717,6 +1649,72 @@ void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta,
curr_effect->end();
}
+void shaders::screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
+{
+ UINT num_passes = 0;
+
+ curr_effect = simple_effect;
+ curr_effect->update_uniforms();
+ curr_effect->set_texture("DiffuseTexture", rt->render_texture[1]);
+
+ HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+
+ curr_effect->begin(&num_passes, 0);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ curr_effect->begin_pass(pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ curr_effect->end_pass();
+ }
+
+ curr_effect->end();
+
+ // Scanlines and shadow mask, at high res for AVI logging
+ if(avi_output_file != NULL)
+ {
+ result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, avi_final_target);
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+
+ curr_effect->begin(&num_passes, 0);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ curr_effect->begin_pass(pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ curr_effect->end_pass();
+ }
+
+ curr_effect->end();
+ }
+
+ if(render_snap)
+ {
+ result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, snap_target);
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+
+ curr_effect->begin(&num_passes, 0);
+
+ for (UINT pass = 0; pass < num_passes; pass++)
+ {
+ curr_effect->begin_pass(pass);
+ // add the primitives
+ result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
+ if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ curr_effect->end_pass();
+ }
+
+ curr_effect->end();
+
+ snap_rendered = true;
+ }
+}
+
//============================================================
// shaders::render_quad
//============================================================
@@ -1754,9 +1752,10 @@ void shaders::render_quad(poly_info *poly, int vertnum)
defocus_pass(rt, texsize);
}
phosphor_pass(rt, ct, texsize, focus_enable);
- avi_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
- screen_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
- raster_bloom_pass(rt, texsize, delta, poly, vertnum);
+ post_pass(rt, texsize, delta, sourcedims, poly, vertnum, true);
+ post_pass(rt, texsize, delta, sourcedims, poly, vertnum, false);
+ bloom_pass(rt, texsize, delta, poly, vertnum);
+ screen_pass(rt, texsize, delta, poly, vertnum);
curr_texture->increment_frame_count();
curr_texture->mask_frame_count(options->yiq_phase_count);
@@ -1775,12 +1774,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
lines_pending = true;
curr_effect = vector_effect;
-
- if(options->params_dirty)
- {
- vec2f screendims = d3d->get_dims();
- curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
- }
+ curr_effect->update_uniforms();
float time_params[2] = { 0.0f, 0.0f };
float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio };
@@ -1802,29 +1796,33 @@ void shaders::render_quad(poly_info *poly, int vertnum)
}
curr_effect->end();
+
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
curr_effect = default_effect;
-
+ curr_effect->update_uniforms();
+
curr_effect->set_float("FixedAlpha", 1.0f);
}
else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
{
render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
+ if (rt == NULL)
+ {
+ return;
+ }
- /* Bloom */
+ /* Bloom, todo: merge with bloom_pass() */
curr_effect = downsample_effect;
-
- curr_effect->set_texture("Diffuse", rt->render_texture[0]);
+ curr_effect->update_uniforms();
curr_effect->set_float("BloomRescale", options->vector_bloom_scale);
+ curr_effect->set_bool("PrepareVector", true);
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
int bloom_index = 0;
float bloom_width = rt->target_width;
float bloom_height = rt->target_height;
- float screen_size[2] = { d3d->get_width(), d3d->get_height() };
- curr_effect->set_vector("ScreenSize", 2, screen_size);
float bloom_dims[11][2];
for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
{
@@ -1859,15 +1857,11 @@ void shaders::render_quad(poly_info *poly, int vertnum)
// Bloom composite pass
curr_effect = bloom_effect;
+ curr_effect->update_uniforms();
- float target_size[2] = { d3d->get_width(), d3d->get_height() };
- curr_effect->set_vector("TargetSize", 2, target_size);
- float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight,
- options->bloom_level2_weight, options->bloom_level3_weight };
- float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight,
- options->bloom_level6_weight, options->bloom_level7_weight };
- float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight,
- options->bloom_level10_weight };
+ float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
+ float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
+ float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
curr_effect->set_vector("Level0123Weight", 4, weight0123);
curr_effect->set_vector("Level4567Weight", 4, weight4567);
curr_effect->set_vector("Level89AWeight", 3, weight89A);
@@ -1880,6 +1874,8 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_effect->set_texture("DiffuseA", rt->render_texture[0]);
+ curr_effect->set_bool("PrepareVector", true);
+
char name[9] = "Diffuse*";
for(int index = 1; index < bloom_index; index++)
{
@@ -1910,19 +1906,14 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_effect->end();
- /* Phosphor */
+ /* Phosphor, todo: merge with phosphor_pass() */
+ phosphor_passthrough = false;
+
curr_effect = phosphor_effect;
-
- if(options->params_dirty)
- {
- vec2f screendims = d3d->get_dims();
- curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
- curr_effect->set_vector("Phosphor", 3, options->phosphor);
- }
+ curr_effect->update_uniforms();
+
float target_dims[2] = { d3d->get_width(), d3d->get_height() };
curr_effect->set_vector("TargetDims", 2, target_dims);
- curr_effect->set_float("Passthrough", 0.0f);
-
curr_effect->set_texture("Diffuse", rt->render_texture[1]);
curr_effect->set_texture("LastPass", rt->render_texture[2]);
@@ -1959,9 +1950,8 @@ void shaders::render_quad(poly_info *poly, int vertnum)
else
{
curr_effect = default_effect;
-
- vec2f screendims = d3d->get_dims();
- curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
+ curr_effect->update_uniforms();
+
curr_effect->set_float("PostPass", 0.0f);
curr_effect->begin(&num_passes, 0);
@@ -2170,8 +2160,8 @@ bool shaders::register_texture(texture_info *texture)
enumerate_screens();
- int hlsl_prescale_x = prescale_force_x;
- int hlsl_prescale_y = prescale_force_y;
+ hlsl_prescale_x = prescale_force_x;
+ hlsl_prescale_y = prescale_force_y;
// Find the nearest prescale factor that is over our screen size
if (hlsl_prescale_x == 0)
@@ -2252,6 +2242,11 @@ void shaders::delete_resources(bool reset)
delete default_effect;
default_effect = NULL;
}
+ if (simple_effect != NULL)
+ {
+ delete simple_effect;
+ simple_effect = NULL;
+ }
if (post_effect != NULL)
{
delete post_effect;
@@ -2436,16 +2431,40 @@ static INT32 slider_shadow_mask_vsize(running_machine &machine, void *arg, std::
return slider_set(&(((hlsl_options*)arg)->shadow_mask_v_size), 1.0f / 32.0f, "%2.5f", str, newval);
}
+static INT32 slider_shadow_mask_uoffset(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ ((hlsl_options*)arg)->params_dirty = true;
+ return slider_set(&(((hlsl_options*)arg)->shadow_mask_u_offset), 0.01f, "%2.2f", str, newval);
+}
+
+static INT32 slider_shadow_mask_voffset(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ ((hlsl_options*)arg)->params_dirty = true;
+ return slider_set(&(((hlsl_options*)arg)->shadow_mask_v_offset), 0.01f, "%2.2f", str, newval);
+}
+
static INT32 slider_curvature(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
((hlsl_options*)arg)->params_dirty = true;
return slider_set(&(((hlsl_options*)arg)->curvature), 0.01f, "%2.2f", str, newval);
}
-static INT32 slider_pincushion(running_machine &machine, void *arg, std::string *str, INT32 newval)
+static INT32 slider_round_corner(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ ((hlsl_options*)arg)->params_dirty = true;
+ return slider_set(&(((hlsl_options*)arg)->round_corner), 0.01f, "%2.2f", str, newval);
+}
+
+static INT32 slider_reflection(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
((hlsl_options*)arg)->params_dirty = true;
- return slider_set(&(((hlsl_options*)arg)->pincushion), 0.01f, "%2.2f", str, newval);
+ return slider_set(&(((hlsl_options*)arg)->reflection), 0.01f, "%2.2f", str, newval);
+}
+
+static INT32 slider_vignetting(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ ((hlsl_options*)arg)->params_dirty = true;
+ return slider_set(&(((hlsl_options*)arg)->vignetting), 0.01f, "%2.2f", str, newval);
}
static INT32 slider_scanline_alpha(running_machine &machine, void *arg, std::string *str, INT32 newval)
@@ -2815,15 +2834,16 @@ static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, std::
shaders::slider_desc shaders::s_sliders[] =
{
{ "Shadow Mask Darkness", 0, 0, 100, 1, slider_shadow_mask_alpha },
- { "Shadow Mask X Count", 1, 320, 1024, 1, slider_shadow_mask_x_count },
- { "Shadow Mask Y Count", 1, 240, 1024, 1, slider_shadow_mask_y_count },
+ { "Shadow Mask X Count", 1, 6, 1024, 1, slider_shadow_mask_x_count },
+ { "Shadow Mask Y Count", 1, 6, 1024, 1, slider_shadow_mask_y_count },
{ "Shadow Mask Pixel Count X", 1, 6, 64, 1, slider_shadow_mask_usize },
- { "Shadow Mask Pixel Count Y", 1, 7, 64, 1, slider_shadow_mask_vsize },
- { "Shadow Mask Pixel Count Y", 1, 7, 64, 1, slider_shadow_mask_vsize },
- { "Shadow Mask Pixel Count Y", 1, 7, 64, 1, slider_shadow_mask_vsize },
- { "Shadow Mask Pixel Count Y", 1, 7, 64, 1, slider_shadow_mask_vsize },
+ { "Shadow Mask Pixel Count Y", 1, 6, 64, 1, slider_shadow_mask_vsize },
+ { "Shadow Mask Offset X", -100, 0, 100, 1, slider_shadow_mask_uoffset },
+ { "Shadow Mask Offset Y", -100, 0, 100, 1, slider_shadow_mask_voffset },
{ "Screen Curvature", 0, 3, 100, 1, slider_curvature },
- { "Image Pincushion", 0, 3, 100, 1, slider_pincushion },
+ { "Screen Round Corner", 0, 3, 100, 1, slider_round_corner },
+ { "Screen Reflection", 0, 3, 100, 1, slider_reflection },
+ { "Image Vignetting", 0, 3, 100, 1, slider_vignetting },
{ "Scanline Darkness", 0, 100, 100, 1, slider_scanline_alpha },
{ "Scanline Screen Height", 1, 20, 80, 1, slider_scanline_scale },
{ "Scanline Indiv. Height", 1, 20, 80, 1, slider_scanline_height },
@@ -3062,12 +3082,18 @@ void uniform::update()
m_shader->set_float("Passthrough", shadersys->phosphor_passthrough ? 1.0f : 0.0f);
break;
- case CU_POST_PINCUSHION:
- m_shader->set_float("PincushionAmount", options->pincushion);
+ case CU_POST_REFLECTION:
+ m_shader->set_float("ReflectionAmount", options->reflection);
+ break;
+ case CU_POST_VIGNETTING:
+ m_shader->set_float("VignettingAmount", options->vignetting);
break;
case CU_POST_CURVATURE:
m_shader->set_float("CurvatureAmount", options->curvature);
break;
+ case CU_POST_ROUND_CORNER:
+ m_shader->set_float("RoundCornerAmount", options->round_corner);
+ break;
case CU_POST_SHADOW_ALPHA:
m_shader->set_float("ShadowAlpha", shadersys->shadow_texture == NULL ? 0.0f : options->shadow_mask_alpha);
break;
@@ -3083,6 +3109,12 @@ void uniform::update()
m_shader->set_vector("ShadowUV", 2, shadowuv);
break;
}
+ case CU_POST_SHADOW_UV_OFFSET:
+ {
+ float shadowuv[2] = { options->shadow_mask_u_offset, options->shadow_mask_v_offset };
+ m_shader->set_vector("ShadowUVOffset", 2, shadowuv);
+ break;
+ }
case CU_POST_SHADOW_DIMS:
{
vec2f shadow_dims;
@@ -3344,6 +3376,11 @@ void effect::set_int(D3DXHANDLE param, int value)
m_effect->SetInt(param, value);
}
+void effect::set_bool(D3DXHANDLE param, bool value)
+{
+ m_effect->SetBool(param, value);
+}
+
void effect::set_matrix(D3DXHANDLE param, matrix *matrix)
{
m_effect->SetMatrix(param, (D3DXMATRIX*)matrix);
@@ -3431,7 +3468,7 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp
if (end - pos < 3)
fatalerror("Something very wrong is going on!!!\n");
- // copy the device name to an astring
+ // copy the device name to a string
std::string snapdevname;
snapdevname.assign(snapstr.substr(pos + 3, end - pos - 3));
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index b86af5a1bac..afb760669f3 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -74,11 +74,14 @@ public:
CU_PHOSPHOR_LIFE,
CU_PHOSPHOR_IGNORE,
- CU_POST_PINCUSHION,
+ CU_POST_VIGNETTING,
CU_POST_CURVATURE,
+ CU_POST_ROUND_CORNER,
+ CU_POST_REFLECTION,
CU_POST_SHADOW_ALPHA,
CU_POST_SHADOW_COUNT,
CU_POST_SHADOW_UV,
+ CU_POST_SHADOW_UV_OFFSET,
CU_POST_SHADOW_DIMS,
CU_POST_SCANLINE_ALPHA,
CU_POST_SCANLINE_SCALE,
@@ -146,6 +149,7 @@ public:
void set_vector(D3DXHANDLE param, int count, float *vector);
void set_float(D3DXHANDLE param, float value);
void set_int(D3DXHANDLE param, int value);
+ void set_bool(D3DXHANDLE param, bool value);
void set_matrix(D3DXHANDLE param, matrix *matrix);
void set_texture(D3DXHANDLE param, texture *tex);
@@ -184,8 +188,12 @@ struct hlsl_options
int shadow_mask_count_y;
float shadow_mask_u_size;
float shadow_mask_v_size;
+ float shadow_mask_u_offset;
+ float shadow_mask_v_offset;
float curvature;
- float pincushion;
+ float round_corner;
+ float reflection;
+ float vignetting;
float scanline_alpha;
float scanline_scale;
float scanline_height;
@@ -307,9 +315,6 @@ public:
private:
void blit(surface *dst, texture *src, surface *new_dst,
- D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count,
- int dstw, int dsth);
- void blit(surface *dst, texture *src, surface *new_dst,
D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
void enumerate_screens();
@@ -329,9 +334,9 @@ private:
void deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims);
void defocus_pass(render_target *rt, vec2f &texsize);
void phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable);
- void screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
- void avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
- void raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
+ void post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom);
+ void bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
+ void screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
base * d3dintf; // D3D interface
@@ -351,6 +356,8 @@ private:
int prescale_force_y; // prescale force y
int prescale_size_x; // prescale size x
int prescale_size_y; // prescale size y
+ int hlsl_prescale_x; // hlsl prescale x
+ int hlsl_prescale_y; // hlsl prescale y
int preset; // preset, if relevant
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
texture_info * shadow_texture; // shadow mask texture for post-processing shader
@@ -388,6 +395,7 @@ private:
surface * backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object
effect * default_effect; // pointer to the primary-effect object
+ effect * simple_effect; // pointer to the simple-effect object
effect * prescale_effect; // pointer to the prescale-effect object
effect * post_effect; // pointer to the post-effect object
effect * focus_effect; // pointer to the focus-effect object
diff --git a/src/osd/modules/render/drawd3d.c b/src/osd/modules/render/drawd3d.c
index 575d0888ea9..93c316c347f 100644
--- a/src/osd/modules/render/drawd3d.c
+++ b/src/osd/modules/render/drawd3d.c
@@ -1658,14 +1658,14 @@ void renderer::draw_quad(const render_primitive *prim)
return;
// fill in the vertexes clockwise
- vertex[0].x = prim->bounds.x0 - 0.5f;
- vertex[0].y = prim->bounds.y0 - 0.5f;
- vertex[1].x = prim->bounds.x1 - 0.5f;
- vertex[1].y = prim->bounds.y0 - 0.5f;
- vertex[2].x = prim->bounds.x0 - 0.5f;
- vertex[2].y = prim->bounds.y1 - 0.5f;
- vertex[3].x = prim->bounds.x1 - 0.5f;
- vertex[3].y = prim->bounds.y1 - 0.5f;
+ vertex[0].x = prim->bounds.x0;
+ vertex[0].y = prim->bounds.y0;
+ vertex[1].x = prim->bounds.x1;
+ vertex[1].y = prim->bounds.y0;
+ vertex[2].x = prim->bounds.x0;
+ vertex[2].y = prim->bounds.y1;
+ vertex[3].x = prim->bounds.x1;
+ vertex[3].y = prim->bounds.y1;
float width = prim->bounds.x1 - prim->bounds.x0;
float height = prim->bounds.y1 - prim->bounds.y0;
@@ -1713,9 +1713,11 @@ void renderer::draw_quad(const render_primitive *prim)
if (a > 255) a = 255;
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
- // set the color, Z parameters to standard values
+ // adjust half pixel X/Y offset, set the color, Z parameters to standard values
for (int i = 0; i < 4; i++)
{
+ vertex[i].x -= 0.5f;
+ vertex[i].y -= 0.5f;
vertex[i].z = 0.0f;
vertex[i].rhw = 1.0f;
vertex[i].color = color;
@@ -2080,28 +2082,14 @@ error:
//============================================================
-// texture_info::compute_size
+// texture_info::compute_size_subroutine
//============================================================
-void texture_info::compute_size(int texwidth, int texheight)
+void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height)
{
int finalheight = texheight;
int finalwidth = texwidth;
- // if we're not wrapping, add a 1-2 pixel border on all sides
- m_xborderpix = 0;
- m_yborderpix = 0;
- if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
- {
- // note we need 2 pixels in X for YUY textures
- m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
- m_yborderpix = 1;
- }
-
- // compute final texture size
- finalwidth += 2 * m_xborderpix;
- finalheight += 2 * m_yborderpix;
-
// round width/height up to nearest power of 2 if we need to
if (!(m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
{
@@ -2144,15 +2132,47 @@ void texture_info::compute_size(int texwidth, int texheight)
{
finalheight *= 2;
}
+
+ *p_width = finalwidth;
+ *p_height = finalheight;
+}
+
+//============================================================
+// texture_info::compute_size
+//============================================================
+
+void texture_info::compute_size(int texwidth, int texheight)
+{
+ int finalheight = texheight;
+ int finalwidth = texwidth;
+
+ m_xborderpix = 0;
+ m_yborderpix = 0;
+
+ // if we're not wrapping, add a 1-2 pixel border on all sides
+ if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
+ {
+ // note we need 2 pixels in X for YUY textures
+ m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
+ m_yborderpix = 1;
+ }
+
+ // compute final texture size
+ finalwidth += 2 * m_xborderpix;
+ finalheight += 2 * m_yborderpix;
+
+ compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
// if we added pixels for the border, and that just barely pushed us over, take it back
- if ((finalwidth > m_texture_manager->get_max_texture_width() && finalwidth - 2 * m_xborderpix <= m_texture_manager->get_max_texture_width()) ||
- (finalheight > m_texture_manager->get_max_texture_height() && finalheight - 2 * m_yborderpix <= m_texture_manager->get_max_texture_height()))
+ if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
{
- finalwidth -= 2 * m_xborderpix;
- finalheight -= 2 * m_yborderpix;
+ finalheight = texheight;
+ finalwidth = texwidth;
+
m_xborderpix = 0;
m_yborderpix = 0;
+
+ compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
}
// if we're above the max width/height, do what?
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index cc6fd4c2dd9..54afff74298 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -296,13 +296,17 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
{ WINOPTION_SHADOW_MASK_ALPHA";fs_shadwa(0.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask alpha-blend value (1.0 is fully blended, 0.0 is no mask)" },
{ WINOPTION_SHADOW_MASK_TEXTURE";fs_shadwt(0.0-1.0)", "aperture.png", OPTION_STRING, "shadow mask texture name" },
- { WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "320", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
- { WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "240", OPTION_INTEGER, "shadow mask height, in phosphor dots" },
- { WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.09375", OPTION_FLOAT, "shadow mask texture size in U direction" },
- { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.109375", OPTION_FLOAT, "shadow mask texture size in V direction" },
- { WINOPTION_CURVATURE";fs_curv(0.0-4.0)", "0.03", OPTION_FLOAT, "screen curvature amount" },
+ { WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "6", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
+ { WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "6", OPTION_INTEGER, "shadow mask height, in phosphor dots" },
+ { WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in U direction" },
+ { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in V direction" },
+ { WINOPTION_SHADOW_MASK_UOFFSET";fs_shadwou(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in U direction" },
+ { WINOPTION_SHADOW_MASK_VOFFSET";fs_shadwov(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in V direction" },
+ { WINOPTION_CURVATURE";fs_curv(0.0-1.0)", "0.03", OPTION_FLOAT, "screen curvature amount" },
+ { WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.03", OPTION_FLOAT, "screen round corner amount" },
+ { WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.03", OPTION_FLOAT, "screen reflection amount" },
+ { WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.03", OPTION_FLOAT, "image vignetting amount" },
/* Beam-related values below this line*/
- { WINOPTION_PINCUSHION";fs_pin(0.0-4.0)", "0.03", OPTION_FLOAT, "pincushion amount" },
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "1.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
{ WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" },
{ WINOPTION_SCANLINE_HEIGHT";fs_scanh(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height scaling value for scanlines" },
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index 92e4056973e..3d0e035701d 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -43,8 +43,12 @@
#define WINOPTION_SHADOW_MASK_COUNT_Y "shadow_mask_y_count"
#define WINOPTION_SHADOW_MASK_USIZE "shadow_mask_usize"
#define WINOPTION_SHADOW_MASK_VSIZE "shadow_mask_vsize"
-#define WINOPTION_PINCUSHION "pincushion"
+#define WINOPTION_SHADOW_MASK_UOFFSET "shadow_mask_uoffset"
+#define WINOPTION_SHADOW_MASK_VOFFSET "shadow_mask_voffset"
+#define WINOPTION_REFLECTION "reflection"
#define WINOPTION_CURVATURE "curvature"
+#define WINOPTION_ROUND_CORNER "round_corner"
+#define WINOPTION_VIGNETTING "vignetting"
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size"
#define WINOPTION_SCANLINE_HEIGHT "scanline_height"
@@ -140,14 +144,18 @@ public:
int screen_shadow_mask_count_y() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_Y); }
float screen_shadow_mask_u_size() const { return float_value(WINOPTION_SHADOW_MASK_USIZE); }
float screen_shadow_mask_v_size() const { return float_value(WINOPTION_SHADOW_MASK_VSIZE); }
+ float screen_shadow_mask_u_offset() const { return float_value(WINOPTION_SHADOW_MASK_UOFFSET); }
+ float screen_shadow_mask_v_offset() const { return float_value(WINOPTION_SHADOW_MASK_VOFFSET); }
float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); }
float screen_scanline_scale() const { return float_value(WINOPTION_SCANLINE_SCALE); }
float screen_scanline_height() const { return float_value(WINOPTION_SCANLINE_HEIGHT); }
float screen_scanline_bright_scale() const { return float_value(WINOPTION_SCANLINE_BRIGHT_SCALE); }
float screen_scanline_bright_offset() const { return float_value(WINOPTION_SCANLINE_BRIGHT_OFFSET); }
float screen_scanline_offset() const { return float_value(WINOPTION_SCANLINE_OFFSET); }
- float screen_pincushion() const { return float_value(WINOPTION_PINCUSHION); }
+ float screen_reflection() const { return float_value(WINOPTION_REFLECTION); }
float screen_curvature() const { return float_value(WINOPTION_CURVATURE); }
+ float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); }
+ float screen_vignetting() const { return float_value(WINOPTION_VIGNETTING); }
const char *screen_defocus() const { return value(WINOPTION_DEFOCUS); }
const char *screen_converge_x() const { return value(WINOPTION_CONVERGE_X); }
const char *screen_converge_y() const { return value(WINOPTION_CONVERGE_Y); }