diff --git a/artwork/adapture-grill.png b/artwork/adapture-grill.png new file mode 100644 index 00000000000..052b300f241 Binary files /dev/null and b/artwork/adapture-grill.png differ diff --git a/artwork/aperture.png b/artwork/aperture.png deleted file mode 100644 index 2243dc52c6e..00000000000 Binary files a/artwork/aperture.png and /dev/null differ diff --git a/artwork/shadow-mask.png b/artwork/shadow-mask.png new file mode 100644 index 00000000000..0c04c5f92fa Binary files /dev/null and b/artwork/shadow-mask.png differ diff --git a/artwork/slot-mask.png b/artwork/slot-mask.png new file mode 100644 index 00000000000..5f4d41dbcd7 Binary files /dev/null and b/artwork/slot-mask.png 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 = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -27,7 +27,7 @@ sampler DiffuseSampler0 = sampler_state sampler DiffuseSampler1 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -38,7 +38,7 @@ sampler DiffuseSampler1 = sampler_state sampler DiffuseSampler2 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -49,7 +49,7 @@ sampler DiffuseSampler2 = sampler_state sampler DiffuseSampler3 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -60,7 +60,7 @@ sampler DiffuseSampler3 = sampler_state sampler DiffuseSampler4 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -71,7 +71,7 @@ sampler DiffuseSampler4 = sampler_state sampler DiffuseSampler5 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -82,7 +82,7 @@ sampler DiffuseSampler5 = sampler_state sampler DiffuseSampler6 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -93,7 +93,7 @@ sampler DiffuseSampler6 = sampler_state sampler DiffuseSampler7 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -104,7 +104,7 @@ sampler DiffuseSampler7 = sampler_state sampler DiffuseSampler8 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -115,7 +115,7 @@ sampler DiffuseSampler8 = sampler_state sampler DiffuseSampler9 = sampler_state { - Texture = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -126,7 +126,7 @@ sampler DiffuseSampler9 = sampler_state sampler DiffuseSamplerA = sampler_state { - Texture = ; + Texture = ; 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] = ; // 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 = ; + Texture = ; 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] = ; 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 = ; + Texture = ; 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] = ; 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 = ; + Texture = ; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; @@ -19,7 +19,7 @@ texture ShadowTexture; sampler ShadowSampler = sampler_state { - Texture = ; + Texture = ; 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; + BaseCoord += CurvatureCurve; // distortion - ScanCoord -= HalfRect; - ScanCoord *= 1.0f - PincushionAmount * UsedArea * 0.2f; // Warning: Magic constant - ScanCoord += HalfRect; - ScanCoord += PincushionCurve; + float2 BaseCoordCentered = Input.TexCoord; + BaseCoordCentered -= HalfRect; + BaseCoordCentered *= CurvatureZoom; // zoom + BaseCoordCentered += CurvatureCurve; // distortion - 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; + // float2 BaseAreaRatioCoord = BaseCoord; + // BaseAreaRatioCoord *= UsedArea * ScreenRatio; - // RGB Pincushion Calculation - float3 PincushionCurveX = PinUnitCoord.x * PincushionAmount * PincushionR2; - float3 PincushionCurveY = PinUnitCoord.y * PincushionAmount * PincushionR2; + float2 BaseAreaRatioCoordCentered = BaseCoordCentered; + BaseAreaRatioCoordCentered *= UsedArea * ScreenRatio; - float4 BaseTexel = tex2D(DiffuseSampler, BaseCoord); + // float2 BaseAreaCoord = BaseCoord; + // BaseAreaCoord *= UsedArea; - // -- 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); + float2 BaseAreaCoordCentered = BaseCoordCentered; + BaseAreaCoordCentered *= UsedArea; - // -- 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; + // Alpha Clipping (1px border in drawd3d does not work for some reason) + clip(BaseCoord < ScreenTexelDims ? -1 : 1); + clip(BaseCoord > SourceRect + ScreenTexelDims ? -1 : 1); - // -- Color Compression (increasing the floor of the signal without affecting the ceiling) -- - Scanned = Floor + (1.0f - Floor) * Scanned; + float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); + BaseColor.a = 1.0f; - // 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); + // 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] = ; 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 = ; + 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] = ; + + 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(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"); @@ -1080,49 +1099,6 @@ void shaders::begin_frame() } -//============================================================ -// shaders::blit -//============================================================ - -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 //============================================================ @@ -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; + 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()); - - // 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; - - 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)->pincushion), 0.01f, "%2.2f", str, newval); + 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)->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; @@ -306,9 +314,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); }