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
This commit is contained in:
ImJezze 2015-05-03 14:41:05 +02:00
parent cc3b682e52
commit a70198a5fb
15 changed files with 794 additions and 346 deletions

BIN
artwork/adapture-grill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

BIN
artwork/shadow-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
artwork/slot-mask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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) (GelfondSchneider 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] = <DiffuseSampler>;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
PixelShader = compile ps_3_0 ps_main();
}
}
}

91
hlsl/simple.fx Normal file
View File

@ -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();
}
}

View File

@ -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

View File

@ -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");
@ -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));

View File

@ -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

View File

@ -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?

View File

@ -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" },

View File

@ -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); }