Merge pull request #522 from ImJezze/pull

HLSL: Improved Defocus, Fixed LCD screen, Extended Shadow Mask and Bloom [ImJezze]

Made defocus strength equal for x/y and independent from screen size

defocus is now independent from screen size and ratio
horizontal and vertical defocus now have the same strength
replaced asymmetric defocus kernel by a symmetric kernel
defocus is now limited to a maximum of 10
added shader uniforms for orientation and rotation settings
Fixed HLSL for LCD screen

fixed wrong detection of vector screen, which meant that a LCD screen was also detected as vector screen
re-enabled scan-line and other CRT related sliders for LCD screen
Extended Shadow Mask and Bloom functionality

added shadow mask option to choose between "Screen" and "Source" tile mode ("Screen" is the default as before)
added bloom option to choose between "Addition" and "Darken" blend mode ("Addition" is the default as before)
the alpha channel of a shadow mask is now filled with the background color of the screen by the amount of the inverted alpha value
added monochrome-matrix.png which can be used in combination with "Source" tile mode and "Darken" blend mode to simulate a STN LCD
This commit is contained in:
Miodrag Milanović 2015-12-26 14:19:44 +01:00
commit 851f66aff9
13 changed files with 366 additions and 195 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -19,6 +19,7 @@ Surface/Color Processing Parameters
-----------------------------------
Name Values Description
shadow_mask_tile_mode 0 or 1 0 for screen based tile mode or 1 for source based tile mode.
shadow_mask_alpha 0.0 to 1.0 The ovearll darkness of each shadow mask pixel.
shadow_mask_texture [filename] A PNG that defines the shadow mask for each pixel.
shadow_mask_x_count 1+ The number of pixels one shadow mask tile uses on screen.
@ -101,6 +102,7 @@ vector_length_ratio 500.0 Vector fade length (4.0 - vectors fade t
Bloom Post-Processing Options
-----------------------------
Name Default Values Description
bloom_blend_mode 0 or 1 0 for addition blend mode or 1 for darken blend mode.
bloom_scale 0.500 Bloom intensity factor. (0.000-2.000)
bloom_overdrive 0.00,0.00,0.00 Bloom overdrive factor to bright full saturated colors. (0.000-2.000)
bloom_lvl0_weight 1.00 Bloom level 0 (full-size target) weight. (0.00-1.00)

View File

@ -162,12 +162,15 @@ uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f);
uniform float CurvatureAmount = 1.0f;
uniform float RoundCornerAmount = 0.0f;
uniform float SmoothBorderAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform int ShadowTileMode = 0; // 0 based on screen dimension, 1 based on source dimension
uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f);
@ -248,7 +251,7 @@ float GetSpotAddend(float2 coord, float amount)
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount;
float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75);
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
@ -292,8 +295,6 @@ float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
float2 GetDistortedCoords(float2 centerCoord, float amount)
{
amount *= 0.25f; // reduced amount
// lens distortion coefficient
float k = amount;
@ -368,19 +369,20 @@ float2 GetAdjustedCoords(float2 coord, float2 centerOffset, float distortionAmou
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims;
float2 HalfSourceRect = PrepareVector
? float2(0.5f, 0.5f)
: SourceRect * 0.5f;
float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
ScreenCoord = GetCoords(ScreenCoord, float2(0.5f, 0.5f), CurvatureAmount);
ScreenCoord = GetCoords(ScreenCoord, float2(0.5f, 0.5f), CurvatureAmount * 0.25f); // reduced amount
float2 DistortionCoord = Input.TexCoord;
DistortionCoord = GetCoords(DistortionCoord, HalfSourceRect, CurvatureAmount);
DistortionCoord = GetCoords(DistortionCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount
float2 BaseCoord = Input.TexCoord;
BaseCoord = GetAdjustedCoords(BaseCoord, HalfSourceRect, CurvatureAmount);
BaseCoord = GetAdjustedCoords(BaseCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount
float2 DistortionCoordCentered = DistortionCoord;
DistortionCoordCentered -= HalfSourceRect;
@ -409,7 +411,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
// ? shadowUV.yx
// : shadowUV.xy;
float2 screenCoord = ScreenCoord;
float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord;
screenCoord = xor(OrientationSwapXY, RotationSwapXY)
? screenCoord.yx
: screenCoord.xy;
@ -419,7 +421,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = (ScreenTexelDims * shadowCount);
float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount);
shadowTile = xor(OrientationSwapXY, RotationSwapXY)
? shadowTile.yx
: shadowTile.xy;
@ -431,10 +433,14 @@ float4 ps_main(PS_INPUT Input) : COLOR
// ? ShadowCoord.yx
// : ShadowCoord.xy;
float3 ShadowColor = tex2D(ShadowSampler, ShadowCoord).rgb;
ShadowColor = lerp(1.0f, ShadowColor, ShadowAlpha);
float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord);
float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha);
float ShadowMaskClear = (1.0f - ShadowColor.a) * ShadowAlpha;
BaseColor.rgb *= ShadowColor;
// apply shadow mask color
BaseColor.rgb *= ShadowMaskColor;
// clear shadow mask by background color
BaseColor.rgb = lerp(BaseColor.rgb, BackColor, ShadowMaskClear);
}
// Color Compression (may not affect bloom)

View File

@ -240,7 +240,9 @@ uniform float4 Level0123Weight;
uniform float4 Level4567Weight;
uniform float3 Level89AWeight;
uniform float3 OverdriveWeight;
uniform int BloomBlendMode = 1; // 0 addition, 1 darken
uniform float BloomScale;
uniform float3 BloomOverdrive;
float3 GetNoiseFactor(float3 n, float random)
{
@ -262,43 +264,78 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 texel9 = tex2D(DiffuseSampler9, Input.TexCoord89.zw).rgb;
float3 texelA = tex2D(DiffuseSamplerA, Input.TexCoordA).rgb;
texel0 = texel0 * Level0123Weight.x;
texel1 = texel1 * Level0123Weight.y;
texel2 = texel2 * Level0123Weight.z;
texel3 = texel3 * Level0123Weight.w;
texel4 = texel4 * Level4567Weight.x;
texel5 = texel5 * Level4567Weight.y;
texel6 = texel6 * Level4567Weight.z;
texel7 = texel7 * Level4567Weight.w;
texel8 = texel8 * Level89AWeight.x;
texel9 = texel9 * Level89AWeight.y;
texelA = texelA * Level89AWeight.z;
float3 blend;
float3 bloom = float3(
texel1 +
texel2 +
texel3 +
texel4 +
texel5 +
texel6 +
texel7 +
texel8 +
texel9 +
texelA);
// addition
if (BloomBlendMode == 0)
{
texel0 *= Level0123Weight.x;
texel1 *= Level0123Weight.y;
texel2 *= Level0123Weight.z;
texel3 *= Level0123Weight.w;
texel4 *= Level4567Weight.x;
texel5 *= Level4567Weight.y;
texel6 *= Level4567Weight.z;
texel7 *= Level4567Weight.w;
texel8 *= Level89AWeight.x;
texel9 *= Level89AWeight.y;
texelA *= Level89AWeight.z;
float3 bloomOverdrive = max(0.0f, texel0 + bloom - 1.0f) * OverdriveWeight;
float3 bloom = float3(
texel1 +
texel2 +
texel3 +
texel4 +
texel5 +
texel6 +
texel7 +
texel8 +
texel9 +
texelA) * BloomScale;
bloom.r += bloomOverdrive.g * 0.5f;
bloom.r += bloomOverdrive.b * 0.5f;
bloom.g += bloomOverdrive.r * 0.5f;
bloom.g += bloomOverdrive.b * 0.5f;
bloom.b += bloomOverdrive.r * 0.5f;
bloom.b += bloomOverdrive.g * 0.5f;
float3 bloomOverdrive = max(0.0f, texel0 + bloom - 1.0f) * BloomOverdrive;
float2 NoiseCoord = Input.TexCoord01.xy;
float3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
return float4(texel0 + bloom * NoiseFactor, 1.0f);
bloom.r += bloomOverdrive.g * 0.5f;
bloom.r += bloomOverdrive.b * 0.5f;
bloom.g += bloomOverdrive.r * 0.5f;
bloom.g += bloomOverdrive.b * 0.5f;
bloom.b += bloomOverdrive.r * 0.5f;
bloom.b += bloomOverdrive.g * 0.5f;
float2 NoiseCoord = Input.TexCoord01.xy;
float3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
blend = texel0 + bloom * NoiseFactor;
}
// darken
else
{
texel1 = min(texel0, texel1);
texel2 = min(texel0, texel2);
texel3 = min(texel0, texel3);
texel4 = min(texel0, texel4);
texel5 = min(texel0, texel5);
texel6 = min(texel0, texel6);
texel7 = min(texel0, texel7);
texel8 = min(texel0, texel8);
texel9 = min(texel0, texel9);
texelA = min(texel0, texelA);
blend = texel0 * Level0123Weight.x;
blend = lerp(blend, texel1, Level0123Weight.y * BloomScale);
blend = lerp(blend, texel2, Level0123Weight.z * BloomScale);
blend = lerp(blend, texel3, Level0123Weight.w * BloomScale);
blend = lerp(blend, texel4, Level4567Weight.x * BloomScale);
blend = lerp(blend, texel5, Level4567Weight.y * BloomScale);
blend = lerp(blend, texel6, Level4567Weight.z * BloomScale);
blend = lerp(blend, texel7, Level4567Weight.w * BloomScale);
blend = lerp(blend, texel8, Level89AWeight.x * BloomScale);
blend = lerp(blend, texel9, Level89AWeight.y * BloomScale);
blend = lerp(blend, texelA, Level89AWeight.z * BloomScale);
}
return float4(blend, 1.0f);
}
//-----------------------------------------------------------------------------

View File

@ -49,20 +49,20 @@ struct PS_INPUT
uniform float2 ScreenDims;
uniform float2 SourceDims;
uniform float YIQEnable;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 invDims = 1.0f / SourceDims;
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 += 0.5f / SourceDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
Output.TexCoord = Input.TexCoord + 0.5f * invDims;
return Output;
}
@ -84,17 +84,17 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 OutRGB = BaseTexel.rgb;
// -- RGB Tint & Shift --
// RGB Tint & Shift
float ShiftedRed = dot(OutRGB, RedRatios);
float ShiftedGrn = dot(OutRGB, GrnRatios);
float ShiftedBlu = dot(OutRGB, BluRatios);
// -- RGB Offset & Scale --
// RGB Scale & Offset
float3 OutTexel = float3(ShiftedRed, ShiftedGrn, ShiftedBlu) * Scale + Offset;
// -- Saturation --
float3 Gray = float3(0.3f, 0.59f, 0.11f);
float OutLuma = dot(OutTexel, Gray);
// Saturation
float3 Grayscale = float3(0.299f, 0.587f, 0.114f);
float OutLuma = dot(OutTexel, Grayscale);
float3 OutChroma = OutTexel - OutLuma;
float3 Saturated = OutLuma + OutChroma * Saturation;

View File

@ -71,7 +71,7 @@ uniform float Prescale;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 invDims = 1.0f / SourceDims;
float2 Ratios = SourceRect;
Output.Position = float4(Input.Position.xyz, 1.0f);
@ -92,7 +92,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.CoordX = ((((TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + RadialConvergeX / SourceDims.x) + 0.5f) * Ratios.x + ConvergeX * invDims.x;
Output.CoordY = ((((TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + RadialConvergeY / SourceDims.y) + 0.5f) * Ratios.y + ConvergeY * invDims.y;
Output.TexCoord = TexCoord;
Output.TexCoord = TexCoord;
return Output;
}
@ -103,11 +103,11 @@ VS_OUTPUT vs_main(VS_INPUT Input)
float4 ps_main(PS_INPUT Input) : COLOR
{
float Alpha = tex2D(DiffuseSampler, Input.TexCoord).a;
float Alpha = tex2D(DiffuseSampler, Input.TexCoord).a;
float RedTexel = tex2D(DiffuseSampler, float2(Input.CoordX.x, Input.CoordY.x)).r;
float GrnTexel = tex2D(DiffuseSampler, float2(Input.CoordX.y, Input.CoordY.y)).g;
float BluTexel = tex2D(DiffuseSampler, float2(Input.CoordX.z, Input.CoordY.z)).b;
return float4(RedTexel, GrnTexel, BluTexel, Alpha);
}

View File

@ -181,7 +181,7 @@ float GetSpotAddend(float2 coord, float amount)
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount;
float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75);
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
@ -215,8 +215,6 @@ float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
float2 GetDistortedCoords(float2 centerCoord, float amount)
{
amount *= 0.25f; // reduced amount
// lens distortion coefficient
float k = amount;
@ -266,7 +264,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float2 BaseCoord = TexCoord;
// Screen Curvature
BaseCoord = GetCoords(BaseCoord, CurvatureAmount);
BaseCoord = GetCoords(BaseCoord, CurvatureAmount * 0.25f); // reduced amount
float2 BaseCoordCentered = BaseCoord;
BaseCoordCentered -= 0.5f;

View File

@ -25,14 +25,7 @@ struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
float2 TexCoord2 : TEXCOORD2;
float2 TexCoord3 : TEXCOORD3;
float2 TexCoord4 : TEXCOORD4;
float2 TexCoord5 : TEXCOORD5;
float2 TexCoord6 : TEXCOORD6;
float2 TexCoord7 : TEXCOORD7;
float2 TexCoord : TEXCOORD0;
};
struct VS_INPUT
@ -45,39 +38,31 @@ struct VS_INPUT
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
float2 TexCoord2 : TEXCOORD2;
float2 TexCoord3 : TEXCOORD3;
float2 TexCoord4 : TEXCOORD4;
float2 TexCoord5 : TEXCOORD5;
float2 TexCoord6 : TEXCOORD6;
float2 TexCoord7 : TEXCOORD7;
float2 TexCoord : TEXCOORD0;
};
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
bool xor(bool a, bool b)
{
return (a || b) && !(a && b);
}
//-----------------------------------------------------------------------------
// Simple Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 Defocus = float2(0.0f, 0.0f);
float2 Coord1Offset = float2(-0.2f, -0.6f);
float2 Coord2Offset = float2( 0.4f, -0.4f);
float2 Coord3Offset = float2( 0.6f, 0.2f);
float2 Coord4Offset = float2( 0.2f, 0.6f);
float2 Coord5Offset = float2(-0.4f, 0.6f);
float2 Coord6Offset = float2(-0.6f, 0.2f);
float2 Coord7Offset = float2(-0.6f, -0.4f);
uniform float2 SourceRect;
uniform float2 QuadDims;
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; // flip y
@ -87,15 +72,8 @@ VS_OUTPUT vs_main(VS_INPUT Input)
float2 TexCoord = Input.TexCoord;
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord0 = TexCoord;
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.TexCoord = TexCoord;
Output.Color = Input.Color;
return Output;
@ -105,21 +83,44 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// Simple Pixel Shader
//-----------------------------------------------------------------------------
float2 Coord1Offset = float2( 0.75f, 0.50f);
float2 Coord2Offset = float2( 0.25f, 1.00f);
float2 Coord3Offset = float2(-0.50f, 0.75f);
float2 Coord4Offset = float2(-1.00f, 0.25f);
float2 Coord5Offset = float2(-0.75f, -0.50f);
float2 Coord6Offset = float2(-0.25f, -1.00f);
float2 Coord7Offset = float2( 0.50f, -0.75f);
float2 Coord8Offset = float2( 1.00f, -0.25f);
uniform float2 Defocus = float2(0.0f, 0.0f);
uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation
uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 d0 = tex2D(DiffuseSampler, Input.TexCoord0);
float3 d1 = tex2D(DiffuseSampler, Input.TexCoord1).rgb;
float3 d2 = tex2D(DiffuseSampler, Input.TexCoord2).rgb;
float3 d3 = tex2D(DiffuseSampler, Input.TexCoord3).rgb;
float3 d4 = tex2D(DiffuseSampler, Input.TexCoord4).rgb;
float3 d5 = tex2D(DiffuseSampler, Input.TexCoord5).rgb;
float3 d6 = tex2D(DiffuseSampler, Input.TexCoord6).rgb;
float3 d7 = tex2D(DiffuseSampler, Input.TexCoord7).rgb;
float2 QuadRatio =
float2(1.0f, xor(OrientationSwapXY, RotationSwapXY)
? QuadDims.y / QuadDims.x
: QuadDims.x / QuadDims.y);
float3 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f;
blurred = lerp(d0.rgb, blurred, 1.0f);
// imaginary texel dimensions independed from quad dimensions, but dependend on quad ratio
float2 DefocusTexelDims = (1.0f / 1024.0) * SourceRect * QuadRatio * Defocus;
return float4(blurred, d0.a);
float4 d = tex2D(DiffuseSampler, Input.TexCoord);
float3 d1 = tex2D(DiffuseSampler, Input.TexCoord + Coord1Offset * DefocusTexelDims).rgb;
float3 d2 = tex2D(DiffuseSampler, Input.TexCoord + Coord2Offset * DefocusTexelDims).rgb;
float3 d3 = tex2D(DiffuseSampler, Input.TexCoord + Coord3Offset * DefocusTexelDims).rgb;
float3 d4 = tex2D(DiffuseSampler, Input.TexCoord + Coord4Offset * DefocusTexelDims).rgb;
float3 d5 = tex2D(DiffuseSampler, Input.TexCoord + Coord5Offset * DefocusTexelDims).rgb;
float3 d6 = tex2D(DiffuseSampler, Input.TexCoord + Coord6Offset * DefocusTexelDims).rgb;
float3 d7 = tex2D(DiffuseSampler, Input.TexCoord + Coord7Offset * DefocusTexelDims).rgb;
float3 d8 = tex2D(DiffuseSampler, Input.TexCoord + Coord8Offset * DefocusTexelDims).rgb;
float3 blurred = (d.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8) / 9.0f;
blurred = lerp(d.rgb, blurred, 1.0f);
return float4(blurred, d.a);
}
//-----------------------------------------------------------------------------

View File

@ -88,7 +88,6 @@ uniform bool RotationSwapXY = false; // swapped default screen orientation due t
uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
uniform bool PrepareVector = false;
uniform bool PrepareRaster = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
@ -128,13 +127,16 @@ VS_OUTPUT vs_main(VS_INPUT Input)
uniform float2 ScreenScale = float2(1.0f, 1.0f);
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
uniform float ScanlineAlpha = 1.0f;
uniform float ScanlineAlpha = 0.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f);
uniform int ShadowTileMode = 0; // 0 based on screen dimension, 1 based on source dimension
uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f);
@ -162,6 +164,7 @@ float2 GetAdjustedCoords(float2 coord, float2 centerOffset)
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims;
float2 HalfSourceRect = PrepareVector
? float2(0.5f, 0.5f)
@ -192,7 +195,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
// ? shadowUV.yx
// : shadowUV.xy;
float2 screenCoord = ScreenCoord;
float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord;
screenCoord = xor(OrientationSwapXY, RotationSwapXY)
? screenCoord.yx
: screenCoord.xy;
@ -202,7 +205,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = (ScreenTexelDims * shadowCount);
float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount);
shadowTile = xor(OrientationSwapXY, RotationSwapXY)
? shadowTile.yx
: shadowTile.xy;
@ -214,10 +217,14 @@ float4 ps_main(PS_INPUT Input) : COLOR
// ? ShadowCoord.yx
// : ShadowCoord.xy;
float3 ShadowColor = tex2D(ShadowSampler, ShadowCoord).rgb;
ShadowColor = lerp(1.0f, ShadowColor, ShadowAlpha);
float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord);
float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha);
float ShadowMaskClear = (1.0f - ShadowColor.a) * ShadowAlpha;
BaseColor.rgb *= ShadowColor;
// apply shadow mask color
BaseColor.rgb *= ShadowMaskColor;
// clear shadow mask by background color
BaseColor.rgb = lerp(BaseColor.rgb, BackColor, ShadowMaskClear);
}
// Color Compression (may not affect bloom)
@ -235,8 +242,8 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Scanline Simulation (may not affect bloom)
if (!PrepareBloom)
{
// Scanline Simulation (only for raster screen)
if (PrepareRaster)
// Scanline Simulation (may not affect vector screen)
if (!PrepareVector)
{
float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y;
float ScanJitter = ScanlineOffset * SourceDims.y;

View File

@ -688,6 +688,7 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende
if (!options->params_init)
{
strncpy(options->shadow_mask_texture, winoptions.screen_shadow_mask_texture(), sizeof(options->shadow_mask_texture));
options->shadow_mask_tile_mode = winoptions.screen_shadow_mask_tile_mode();
options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha();
options->shadow_mask_count_x = winoptions.screen_shadow_mask_count_x();
options->shadow_mask_count_y = winoptions.screen_shadow_mask_count_y();
@ -734,6 +735,7 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende
options->yiq_phase_count = winoptions.screen_yiq_phase_count();
options->vector_length_scale = winoptions.screen_vector_length_scale();
options->vector_length_ratio = winoptions.screen_vector_length_ratio();
options->bloom_blend_mode = winoptions.screen_bloom_blend_mode();
options->bloom_scale = winoptions.screen_bloom_scale();
get_vector(winoptions.screen_bloom_overdrive(), 3, options->bloom_overdrive, TRUE);
options->bloom_level0_weight = winoptions.screen_bloom_lvl0_weight();
@ -968,7 +970,6 @@ int shaders::create_resources(bool reset)
color_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
color_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
color_effect->add_uniform("YIQEnable", uniform::UT_FLOAT, uniform::CU_NTSC_ENABLE);
color_effect->add_uniform("RedRatios", uniform::UT_VEC3, uniform::CU_COLOR_RED_RATIOS);
color_effect->add_uniform("GrnRatios", uniform::UT_VEC3, uniform::CU_COLOR_GRN_RATIOS);
color_effect->add_uniform("BluRatios", uniform::UT_VEC3, uniform::CU_COLOR_BLU_RATIOS);
@ -988,7 +989,11 @@ int shaders::create_resources(bool reset)
focus_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
focus_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
focus_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
focus_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE);
focus_effect->add_uniform("OrientationSwapXY", uniform::UT_BOOL, uniform::CU_ORIENTATION_SWAP);
focus_effect->add_uniform("RotationSwapXY", uniform::UT_BOOL, uniform::CU_ROTATION_SWAP);
phosphor_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
phosphor_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
@ -1025,6 +1030,10 @@ int shaders::create_resources(bool reset)
post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
post_effect->add_uniform("OrientationSwapXY", uniform::UT_BOOL, uniform::CU_ORIENTATION_SWAP);
post_effect->add_uniform("RotationSwapXY", uniform::UT_BOOL, uniform::CU_ROTATION_SWAP);
post_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
distortion_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
distortion_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
distortion_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
@ -1035,6 +1044,10 @@ int shaders::create_resources(bool reset)
distortion_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER);
distortion_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION);
distortion_effect->add_uniform("OrientationSwapXY", uniform::UT_BOOL, uniform::CU_ORIENTATION_SWAP);
distortion_effect->add_uniform("RotationSwapXY", uniform::UT_BOOL, uniform::CU_ROTATION_SWAP);
distortion_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
vector_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
default_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
@ -1268,6 +1281,46 @@ int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int
return next_index;
}
rgb_t shaders::apply_color_convolution(rgb_t color)
{
// this function uses the same algorithm as the color convolution shader pass
float r = static_cast<float>(color.r()) / 255.0f;
float g = static_cast<float>(color.g()) / 255.0f;
float b = static_cast<float>(color.b()) / 255.0f;
float *rRatio = options->red_ratio;
float *gRatio = options->grn_ratio;
float *bRatio = options->blu_ratio;
float *offset = options->offset;
float *scale = options->scale;
float saturation = options->saturation;
// RGB Tint & Shift
float rShifted = r * rRatio[0] + g * rRatio[1] + b * rRatio[2];
float gShifted = r * gRatio[0] + g * gRatio[1] + b * gRatio[2];
float bShifted = r * bRatio[0] + g * bRatio[1] + b * bRatio[2];
// RGB Scale & Offset
r = rShifted * scale[0] + offset[0];
g = gShifted * scale[1] + offset[1];
b = bShifted * scale[2] + offset[2];
// Saturation
float grayscale[3] = { 0.299f, 0.587f, 0.114f };
float luma = r * grayscale[0] + g * grayscale[1] + b * grayscale[2];
float chroma[3] = { r - luma, g - luma, b - luma };
r = chroma[0] * saturation + luma;
g = chroma[1] * saturation + luma;
b = chroma[2] * saturation + luma;
return rgb_t(
MAX(0, MIN(255, static_cast<int>(r * 255.0f))),
MAX(0, MIN(255, static_cast<int>(g * 255.0f))),
MAX(0, MIN(255, static_cast<int>(b * 255.0f))));
}
int shaders::color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum)
{
int next_index = source_index;
@ -1366,22 +1419,7 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
texture_info *texture = poly->get_texture();
bool prepare_vector =
(machine->first_screen()->screen_type() & SCREEN_TYPE_VECTOR) == SCREEN_TYPE_VECTOR;
bool prepare_raster =
(machine->first_screen()->screen_type() & SCREEN_TYPE_RASTER) == SCREEN_TYPE_RASTER;
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
int rotation_type =
(d3d->window().target()->orientation() & ROT90) == ROT90
? 1
: (d3d->window().target()->orientation() & ROT180) == ROT180
? 2
: (d3d->window().target()->orientation() & ROT270) == ROT270
? 3
: 0;
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
screen_device_iterator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.first();
@ -1399,19 +1437,26 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
float screen_scale[2] = { xscale, yscale };
float screen_offset[2] = { xoffset, yoffset };
rgb_t back_color_rgb = machine->first_screen()->palette() == NULL
? rgb_t(0, 0, 0)
: machine->first_screen()->palette()->palette()->entry_color(0);
back_color_rgb = apply_color_convolution(back_color_rgb);
float back_color[3] = {
static_cast<float>(back_color_rgb.r()) / 255.0f,
static_cast<float>(back_color_rgb.g()) / 255.0f,
static_cast<float>(back_color_rgb.b()) / 255.0f };
curr_effect = post_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
curr_effect->set_vector("BackColor", 3, back_color);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
curr_effect->set_float("ScanlineOffset", texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset);
curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy);
curr_effect->set_bool("RotationSwapXY", rotation_swap_xy);
curr_effect->set_int("RotationType", rotation_type); // backward compatibility
curr_effect->set_bool("PrepareBloom", prepare_bloom);
curr_effect->set_bool("PrepareVector", prepare_vector);
curr_effect->set_bool("PrepareRaster", prepare_raster);
next_index = rt->next_index(next_index);
blit(prepare_bloom ? rt->native_target[next_index] : rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
@ -1424,7 +1469,7 @@ int shaders::downsample_pass(render_target *rt, int source_index, poly_info *pol
int next_index = source_index;
bool prepare_vector =
(machine->first_screen()->screen_type() & SCREEN_TYPE_VECTOR) == SCREEN_TYPE_VECTOR;
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
float bloom_rescale = options->bloom_scale;
// skip downsample if no influencing settings
@ -1482,20 +1527,20 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in
float weight0123[4] = {
options->bloom_level0_weight,
options->bloom_level1_weight * bloom_rescale,
options->bloom_level2_weight * bloom_rescale,
options->bloom_level3_weight * bloom_rescale
options->bloom_level1_weight,
options->bloom_level2_weight,
options->bloom_level3_weight
};
float weight4567[4] = {
options->bloom_level4_weight * bloom_rescale,
options->bloom_level5_weight * bloom_rescale,
options->bloom_level6_weight * bloom_rescale,
options->bloom_level7_weight * bloom_rescale
options->bloom_level4_weight,
options->bloom_level5_weight,
options->bloom_level6_weight,
options->bloom_level7_weight
};
float weight89A[3] = {
options->bloom_level8_weight * bloom_rescale,
options->bloom_level9_weight * bloom_rescale,
options->bloom_level10_weight * bloom_rescale
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);
@ -1507,7 +1552,9 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in
curr_effect->set_vector("Level89Size", 4, bloom_dims[8]);
curr_effect->set_vector("LevelASize", 2, bloom_dims[10]);
curr_effect->set_vector("OverdriveWeight", 3, options->bloom_overdrive);
curr_effect->set_int("BloomBlendMode", options->bloom_blend_mode);
curr_effect->set_float("BloomScale", bloom_rescale);
curr_effect->set_vector("BloomOverdrive", 3, options->bloom_overdrive);
curr_effect->set_texture("DiffuseA", rt->prescale_texture[next_index]);
@ -1563,26 +1610,9 @@ int shaders::distortion_pass(render_target *rt, int source_index, poly_info *pol
return next_index;
}
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
int rotation_type =
(d3d->window().target()->orientation() & ROT90) == ROT90
? 1
: (d3d->window().target()->orientation() & ROT180) == ROT180
? 2
: (d3d->window().target()->orientation() & ROT270) == ROT270
? 3
: 0;
curr_effect = distortion_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy);
curr_effect->set_bool("RotationSwapXY", rotation_swap_xy);
curr_effect->set_int("RotationType", rotation_type);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
@ -1629,7 +1659,7 @@ int shaders::screen_pass(render_target *rt, int source_index, poly_info *poly, i
int next_index = source_index;
bool prepare_vector =
(machine->first_screen()->screen_type() & SCREEN_TYPE_VECTOR) == SCREEN_TYPE_VECTOR;
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
curr_effect = default_effect;
curr_effect->update_uniforms();
@ -1766,7 +1796,8 @@ void shaders::render_quad(poly_info *poly, int vertnum)
int next_index = 0;
next_index = vector_buffer_pass(rt, next_index, poly, vertnum);
next_index = defocus_pass(rt, next_index, poly, vertnum);
next_index = defocus_pass(rt, next_index, poly, vertnum); // 1st pass
next_index = defocus_pass(rt, next_index, poly, vertnum); // 2nd pass
next_index = phosphor_pass(rt, ct, next_index, poly, vertnum);
// create bloom textures
@ -2245,8 +2276,25 @@ static INT32 slider_set(float *option, float scale, const char *fmt, std::string
return floor(*option / scale + 0.5f);
}
static INT32 slider_shadow_mask_tile_mode(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
hlsl_options *options = (hlsl_options*)arg;
if (newval != SLIDER_NOCHANGE)
{
options->shadow_mask_tile_mode = newval;
}
if (str != NULL)
{
strprintf(*str, "%s", options->shadow_mask_tile_mode == 0 ? "Screen" : "Source");
}
options->params_dirty = true;
return options->shadow_mask_tile_mode;
}
static INT32 slider_shadow_mask_alpha(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
((hlsl_options*)arg)->params_dirty = true;
return slider_set(&(((hlsl_options*)arg)->shadow_mask_alpha), 0.01f, "%2.2f", str, newval);
}
@ -2618,6 +2666,22 @@ static INT32 slider_vector_length_max(running_machine &machine, void *arg, std::
return slider_set(&(((hlsl_options*)arg)->vector_length_ratio), 1.0f, "%4f", str, newval);
}
static INT32 slider_bloom_blend_mode(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
hlsl_options *options = (hlsl_options*)arg;
if (newval != SLIDER_NOCHANGE)
{
options->bloom_blend_mode = newval;
}
if (str != NULL)
{
strprintf(*str, "%s", options->bloom_blend_mode == 0 ? "Addition" : "Darken");
}
options->params_dirty = true;
return options->bloom_blend_mode;
}
static INT32 slider_bloom_scale(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
((hlsl_options*)arg)->params_dirty = true;
@ -2714,6 +2778,7 @@ shaders::slider_desc shaders::s_sliders[] =
{
{ "Vector Length Attenuation", 0, 50, 100, 1, 2, slider_vector_attenuation },
{ "Vector Attenuation Length Limit", 1, 500, 1000, 1, 2, slider_vector_length_max },
{ "Shadow Mask Tile Mode", 0, 0, 1, 1, 7, slider_shadow_mask_tile_mode },
{ "Shadow Mask Darkness", 0, 0, 100, 1, 7, slider_shadow_mask_alpha },
{ "Shadow Mask X Count", 1, 1, 1024, 1, 7, slider_shadow_mask_x_count },
{ "Shadow Mask Y Count", 1, 1, 1024, 1, 7, slider_shadow_mask_y_count },
@ -2726,26 +2791,26 @@ shaders::slider_desc shaders::s_sliders[] =
{ "Screen Smooth Border", 0, 0, 100, 1, 7, slider_smooth_border },
{ "Screen Reflection", 0, 0, 100, 1, 7, slider_reflection },
{ "Image Vignetting", 0, 0, 100, 1, 7, slider_vignetting },
{ "Scanline Darkness", 0, 0, 100, 1, 1, slider_scanline_alpha },
{ "Scanline Screen Height", 1, 20, 80, 1, 1, slider_scanline_scale },
{ "Scanline Indiv. Height", 1, 20, 80, 1, 1, slider_scanline_height },
{ "Scanline Brightness", 0, 20, 40, 1, 1, slider_scanline_bright_scale },
{ "Scanline Brightness Overdrive", 0, 0, 20, 1, 1, slider_scanline_bright_offset },
{ "Scanline Jitter", 0, 0, 40, 1, 1, slider_scanline_offset },
{ "Defocus X", 0, 0, 64, 1, 3, slider_defocus_x },
{ "Defocus Y", 0, 0, 64, 1, 3, slider_defocus_y },
{ "Red Position Offset X", -1500, 0, 1500, 1, 3, slider_red_converge_x },
{ "Red Position Offset Y", -1500, 0, 1500, 1, 3, slider_red_converge_y },
{ "Green Position Offset X", -1500, 0, 1500, 1, 3, slider_green_converge_x },
{ "Green Position Offset Y", -1500, 0, 1500, 1, 3, slider_green_converge_y },
{ "Blue Position Offset X", -1500, 0, 1500, 1, 3, slider_blue_converge_x },
{ "Blue Position Offset Y", -1500, 0, 1500, 1, 3, slider_blue_converge_y },
{ "Red Convergence X", -1500, 0, 1500, 1, 3, slider_red_radial_converge_x },
{ "Red Convergence Y", -1500, 0, 1500, 1, 3, slider_red_radial_converge_y },
{ "Green Convergence X", -1500, 0, 1500, 1, 3, slider_green_radial_converge_x },
{ "Green Convergence Y", -1500, 0, 1500, 1, 3, slider_green_radial_converge_y },
{ "Blue Convergence X", -1500, 0, 1500, 1, 3, slider_blue_radial_converge_x },
{ "Blue Convergence Y", -1500, 0, 1500, 1, 3, slider_blue_radial_converge_y },
{ "Scanline Darkness", 0, 0, 100, 1, 5, slider_scanline_alpha },
{ "Scanline Screen Height", 1, 20, 80, 1, 5, slider_scanline_scale },
{ "Scanline Indiv. Height", 1, 20, 80, 1, 5, slider_scanline_height },
{ "Scanline Brightness", 0, 20, 40, 1, 5, slider_scanline_bright_scale },
{ "Scanline Brightness Overdrive", 0, 0, 20, 1, 5, slider_scanline_bright_offset },
{ "Scanline Jitter", 0, 0, 40, 1, 5, slider_scanline_offset },
{ "Defocus X", 0, 0, 20, 1, 7, slider_defocus_x },
{ "Defocus Y", 0, 0, 20, 1, 7, slider_defocus_y },
{ "Red Position Offset X", -1500, 0, 1500, 1, 7, slider_red_converge_x },
{ "Red Position Offset Y", -1500, 0, 1500, 1, 7, slider_red_converge_y },
{ "Green Position Offset X", -1500, 0, 1500, 1, 7, slider_green_converge_x },
{ "Green Position Offset Y", -1500, 0, 1500, 1, 7, slider_green_converge_y },
{ "Blue Position Offset X", -1500, 0, 1500, 1, 7, slider_blue_converge_x },
{ "Blue Position Offset Y", -1500, 0, 1500, 1, 7, slider_blue_converge_y },
{ "Red Convergence X", -1500, 0, 1500, 1, 7, slider_red_radial_converge_x },
{ "Red Convergence Y", -1500, 0, 1500, 1, 7, slider_red_radial_converge_y },
{ "Green Convergence X", -1500, 0, 1500, 1, 7, slider_green_radial_converge_x },
{ "Green Convergence Y", -1500, 0, 1500, 1, 7, slider_green_radial_converge_y },
{ "Blue Convergence X", -1500, 0, 1500, 1, 7, slider_blue_radial_converge_x },
{ "Blue Convergence Y", -1500, 0, 1500, 1, 7, slider_blue_radial_converge_y },
{ "Red Output from Red Input", -400, 0, 400, 5, 7, slider_red_from_r },
{ "Red Output from Green Input", -400, 0, 400, 5, 7, slider_red_from_g },
{ "Red Output from Blue Input", -400, 0, 400, 5, 7, slider_red_from_b },
@ -2771,6 +2836,7 @@ shaders::slider_desc shaders::s_sliders[] =
{ "Red Phosphor Life", 0, 0, 100, 1, 7, slider_red_phosphor_life },
{ "Green Phosphor Life", 0, 0, 100, 1, 7, slider_green_phosphor_life },
{ "Blue Phosphor Life", 0, 0, 100, 1, 7, slider_blue_phosphor_life },
{ "Bloom Blend Mode", 0, 0, 1, 1, 7, slider_bloom_blend_mode },
{ "Bloom Scale", 0, 0, 2000, 5, 7, slider_bloom_scale },
{ "Bloom Red Overdrive", 0, 0, 2000, 5, 7, slider_bloom_red_overdrive },
{ "Bloom Green Overdrive", 0, 0, 2000, 5, 7, slider_bloom_green_overdrive },
@ -2834,6 +2900,7 @@ uniform::uniform(effect *shader, const char *name, uniform_type type, int id)
m_next = NULL;
m_handle = m_shader->get_parameter(NULL, name);
m_ival = 0;
m_bval = false;
memset(m_vec, 0, sizeof(float) * 4);
m_mval = NULL;
m_texture = NULL;
@ -2841,6 +2908,7 @@ uniform::uniform(effect *shader, const char *name, uniform_type type, int id)
switch (type)
{
case UT_BOOL:
case UT_INT:
case UT_FLOAT:
case UT_MATRIX:
@ -2919,6 +2987,33 @@ void uniform::update()
break;
}
case CU_ORIENTATION_SWAP:
{
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
m_shader->set_bool("OrientationSwapXY", orientation_swap_xy);
}
case CU_ROTATION_SWAP:
{
bool rotation_swap_xy =
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
m_shader->set_bool("RotationSwapXY", rotation_swap_xy);
}
case CU_ROTATION_TYPE:
{
int rotation_type =
(d3d->window().target()->orientation() & ROT90) == ROT90
? 1
: (d3d->window().target()->orientation() & ROT180) == ROT180
? 2
: (d3d->window().target()->orientation() & ROT270) == ROT270
? 3
: 0;
m_shader->set_int("RotationType", rotation_type);
}
case CU_NTSC_CCFREQ:
m_shader->set_float("CCValue", options->yiq_cc);
break;
@ -3123,6 +3218,11 @@ void uniform::set(int x)
m_ival = x;
}
void uniform::set(bool x)
{
m_bval = x;
}
void uniform::set(matrix *mat)
{
m_mval = mat;
@ -3137,6 +3237,9 @@ void uniform::upload()
{
switch (m_type)
{
case UT_BOOL:
m_shader->set_bool(m_handle, m_bval);
break;
case UT_INT:
m_shader->set_int(m_handle, m_ival);
break;

View File

@ -37,6 +37,7 @@ public:
UT_VEC2,
UT_FLOAT,
UT_INT,
UT_BOOL,
UT_MATRIX,
UT_SAMPLER
} uniform_type;
@ -49,6 +50,10 @@ public:
CU_TARGET_DIMS,
CU_QUAD_DIMS,
CU_ORIENTATION_SWAP,
CU_ROTATION_SWAP,
CU_ROTATION_TYPE,
CU_NTSC_CCFREQ,
CU_NTSC_A,
CU_NTSC_B,
@ -114,6 +119,7 @@ public:
void set(float x, float y);
void set(float x);
void set(int x);
void set(bool x);
void set(matrix *mat);
void set(texture *tex);
@ -125,6 +131,7 @@ protected:
float m_vec[4];
int m_ival;
bool m_bval;
matrix *m_mval;
texture *m_texture;
int m_count;
@ -188,6 +195,7 @@ struct hlsl_options
{
bool params_init;
bool params_dirty;
int shadow_mask_tile_mode;
float shadow_mask_alpha;
char shadow_mask_texture[1024];
int shadow_mask_count_x;
@ -241,6 +249,7 @@ struct hlsl_options
float vector_length_ratio;
// Bloom
int bloom_blend_mode;
float bloom_scale;
float bloom_overdrive[3];
float bloom_level0_weight;
@ -342,6 +351,8 @@ private:
cache_target * find_cache_target(UINT32 screen_index, int width, int height);
void remove_cache_target(cache_target *cache);
rgb_t apply_color_convolution(rgb_t color);
// Shader passes
int ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);

View File

@ -288,6 +288,7 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_HLSL_WRITE, NULL, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" },
{ WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" },
{ WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
{ WINOPTION_SHADOW_MASK_TILE_MODE, "0", OPTION_INTEGER, "shadow mask tile mode (0 for screen based, 1 for source based)" },
{ 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)", "shadow-mask.png", OPTION_STRING, "shadow mask texture name" },
{ WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "6", OPTION_INTEGER, "shadow mask tile width, in screen dimensions" },
@ -345,6 +346,7 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" },
/* Bloom below this line */
{ NULL, NULL, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" },
{ WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for addition, 1 for darken)" },
{ WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for bloom" },
{ WINOPTION_BLOOM_OVERDRIVE, "1.0,1.0,1.0", OPTION_STRING, "Overdrive factor for bloom" },
{ WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "Bloom level 0 (full-size target) weight" },

View File

@ -36,6 +36,7 @@
#define WINOPTION_HLSL_WRITE "hlsl_write"
#define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width"
#define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height"
#define WINOPTION_SHADOW_MASK_TILE_MODE "shadow_mask_tile_mode"
#define WINOPTION_SHADOW_MASK_ALPHA "shadow_mask_alpha"
#define WINOPTION_SHADOW_MASK_TEXTURE "shadow_mask_texture"
#define WINOPTION_SHADOW_MASK_COUNT_X "shadow_mask_x_count"
@ -84,6 +85,7 @@
#define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale"
#define WINOPTION_VECTOR_LENGTH_RATIO "vector_length_ratio"
#define WINOPTION_VECTOR_TIME_PERIOD "vector_time_period"
#define WINOPTION_BLOOM_BLEND_MODE "bloom_blend_mode"
#define WINOPTION_BLOOM_SCALE "bloom_scale"
#define WINOPTION_BLOOM_OVERDRIVE "bloom_overdrive"
#define WINOPTION_BLOOM_LEVEL0_WEIGHT "bloom_lvl0_weight"
@ -138,6 +140,7 @@ public:
int d3d_hlsl_prescale_y() const { return int_value(WINOPTION_HLSL_PRESCALE_Y); }
int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); }
int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); }
int screen_shadow_mask_tile_mode() const { return int_value(WINOPTION_SHADOW_MASK_TILE_MODE); }
float screen_shadow_mask_alpha() const { return float_value(WINOPTION_SHADOW_MASK_ALPHA); }
const char *screen_shadow_mask_texture() const { return value(WINOPTION_SHADOW_MASK_TEXTURE); }
int screen_shadow_mask_count_x() const { return int_value(WINOPTION_SHADOW_MASK_COUNT_X); }
@ -180,6 +183,7 @@ public:
float screen_vector_length_scale() const { return float_value(WINOPTION_VECTOR_LENGTH_SCALE); }
float screen_vector_length_ratio() const { return float_value(WINOPTION_VECTOR_LENGTH_RATIO); }
float screen_vector_time_period() const { return float_value(WINOPTION_VECTOR_TIME_PERIOD); }
int screen_bloom_blend_mode() const { return int_value(WINOPTION_BLOOM_BLEND_MODE); }
float screen_bloom_scale() const { return float_value(WINOPTION_BLOOM_SCALE); }
const char *screen_bloom_overdrive() const { return value(WINOPTION_BLOOM_OVERDRIVE); }
float screen_bloom_lvl0_weight() const { return float_value(WINOPTION_BLOOM_LEVEL0_WEIGHT); }