summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2011-06-06 21:25:38 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2011-06-06 21:25:38 +0000
commit1ec454197a94b693b67f8b9d8bb702288b1478fe (patch)
tree9010ee023db94a28dde5ac5f5d5edaa5e38beb58
parent1d33744bd45f67fd1bd6f1a71aaa42db5d49a138 (diff)
HLSL Updates: [Ryan Holtz, Bat Country Entertainment, austere]
- Reworked default shadow mask settings, eliminating rainbow banding and matching reference shots more closely - Moved color power to occur after shadow mask, as it is intended to simulate nonlinear phosphor response - Added a variable-width notch filter to the Y channel in NTSC post-processing, eliminating luma banding on e.g. CoCo 2 and Apple II
-rw-r--r--artwork/aperture.pngbin305 -> 271 bytes
-rw-r--r--hlsl/color.fx8
-rw-r--r--hlsl/post.fx10
-rw-r--r--hlsl/yiq_decode.fx22
-rw-r--r--src/osd/windows/d3dhlsl.c8
-rw-r--r--src/osd/windows/winmain.c21
-rw-r--r--src/osd/windows/winmain.h2
7 files changed, 42 insertions, 29 deletions
diff --git a/artwork/aperture.png b/artwork/aperture.png
index d94aa881c48..2243dc52c6e 100644
--- a/artwork/aperture.png
+++ b/artwork/aperture.png
Binary files differ
diff --git a/hlsl/color.fx b/hlsl/color.fx
index e4aa954e8b5..e7ceeb57978 100644
--- a/hlsl/color.fx
+++ b/hlsl/color.fx
@@ -100,10 +100,6 @@ uniform float BluFloor = 0.0f;
uniform float Saturation = 1.0f;
-uniform float RedPower = 2.2f;
-uniform float GrnPower = 2.2f;
-uniform float BluPower = 2.2f;
-
float4 ps_main(PS_INPUT Input) : COLOR
{
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
@@ -126,10 +122,6 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 OutChroma = OutTexel - OutLuma;
float3 Saturated = OutLuma + OutChroma * Saturation;
- OutRGB.r = pow(Saturated.r, RedPower);
- OutRGB.g = pow(Saturated.g, GrnPower);
- OutRGB.b = pow(Saturated.b, BluPower);
-
return float4(OutRGB, BaseTexel.a);
}
diff --git a/hlsl/post.fx b/hlsl/post.fx
index 6a148637805..eee6aaa4798 100644
--- a/hlsl/post.fx
+++ b/hlsl/post.fx
@@ -119,6 +119,10 @@ uniform float BluFloor = 0.0f;
uniform float SnapX = 0.0f;
uniform float SnapY = 0.0f;
+uniform float RedPower = 2.2f;
+uniform float GrnPower = 2.2f;
+uniform float BluPower = 2.2f;
+
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 Ratios = float2(WidthRatio, HeightRatio);
@@ -174,13 +178,17 @@ float4 ps_main(PS_INPUT Input) : COLOR
float2 ShadowDims = float2(ShadowWidth, ShadowHeight);
float2 ShadowUV = float2(ShadowU, ShadowV);
float2 ShadowMaskSize = float2(ShadowMaskSizeX, ShadowMaskSizeY);
- float2 ShadowFrac = frac(BaseCoord * ShadowMaskSize * 0.5f);
+ float2 ShadowFrac = frac(BaseCoord * ShadowMaskSize);
float2 ShadowCoord = ShadowFrac * ShadowUV + float2(1.5f / ShadowWidth, 1.5f / ShadowHeight);
float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord).rgb, UseShadow);
// -- Final Pixel --
float4 Output = float4(Scanned * lerp(1.0f, ShadowTexel, ShadowBrightness), BaseTexel.a) * Input.Color;
+ Output.r = pow(Output.r, RedPower);
+ Output.g = pow(Output.g, GrnPower);
+ Output.b = pow(Output.b, BluPower);
+
return Output;
}
diff --git a/hlsl/yiq_decode.fx b/hlsl/yiq_decode.fx
index 61ba590717a..c94ae76de0d 100644
--- a/hlsl/yiq_decode.fx
+++ b/hlsl/yiq_decode.fx
@@ -91,7 +91,8 @@ uniform float PValue = 1.0f;
uniform float OValue = 0.0f;
uniform float ScanTime = 52.6f;
-uniform float YFreqResponse = 3.0f;
+uniform float NotchHalfWidth = 1.0f;
+uniform float YFreqResponse = 6.0f;
uniform float IFreqResponse = 1.2f;
uniform float QFreqResponse = 0.6f;
@@ -108,15 +109,17 @@ float4 ps_main(PS_INPUT Input) : COLOR
float MaxC = 2.1183f;
float MinC = -1.1183f;
float CRange = MaxC - MinC;
- float Fc_y = YFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float Fc_y1 = (CCValue - NotchHalfWidth) * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float Fc_y2 = (CCValue + NotchHalfWidth) * ScanTime / (RawWidth * 4.0f / WidthRatio);
+ float Fc_y3 = YFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
float Fc_i = IFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
float Fc_q = QFreqResponse * ScanTime / (RawWidth * 4.0f / WidthRatio);
float PI = 3.1415926535897932384626433832795;
float PI2 = 2.0f * PI;
- float PI2Length = PI2 / 42.0f;
+ float PI2Length = PI2 / 82.0f;
float4 NOffset = float4(0.0f, 1.0f, 2.0f, 3.0f);
float W = PI2 * CCValue * ScanTime;
- for(float n = -21.0f; n < 22.0f; n += 4.0f)
+ for(float n = -41.0f; n < 42.0f; n += 4.0f)
{
float4 n4 = n + NOffset;
float4 CoordX = Input.Coord0.x + Input.Coord0.z * n4 * 0.25f;
@@ -125,9 +128,14 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 C = tex2D(CompositeSampler, TexCoord + float2(0.625f, 0.4f) / RawDims) * CRange + MinC;
float4 WT = W * (CoordX * WidthRatio + AValue * CoordY * 2.0f * (RawHeight / HeightRatio) + BValue) + OValue;
- float4 SincYIn = PI2 * Fc_y * n4;
- float4 IdealY = 2.0f * Fc_y * ((SincYIn != 0.0f) ? (sin(SincYIn) / SincYIn) : 1.0f);
- float4 FilterY = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealY;
+ float4 SincYIn1 = PI2 * Fc_y1 * n4;
+ float4 SincYIn2 = PI2 * Fc_y2 * n4;
+ float4 SincYIn3 = PI2 * Fc_y3 * n4;
+ float4 SincY1 = ((SincYIn1 != 0.0f) ? (sin(SincYIn1) / SincYIn1) : 1.0f);
+ float4 SincY2 = ((SincYIn2 != 0.0f) ? (sin(SincYIn2) / SincYIn2) : 1.0f);
+ float4 SincY3 = ((SincYIn3 != 0.0f) ? (sin(SincYIn3) / SincYIn3) : 1.0f);
+ float4 IdealY = (2.0f * Fc_y1 * SincY1 - 2.0f * Fc_y2 * SincY2) + 2.0f * Fc_y3 * SincY3;
+ float4 FilterY = (0.54f + 0.46f * cos(PI2Length * n4)) * IdealY;
float4 SincIIn = PI2 * Fc_i * n4;
float4 IdealI = 2.0f * Fc_i * ((SincIIn != 0.0f) ? (sin(SincIIn) / SincIIn) : 1.0f);
diff --git a/src/osd/windows/d3dhlsl.c b/src/osd/windows/d3dhlsl.c
index 1269105e8c3..0182852ee8d 100644
--- a/src/osd/windows/d3dhlsl.c
+++ b/src/osd/windows/d3dhlsl.c
@@ -1016,6 +1016,9 @@ void hlsl_info::init_effect_info(d3d_poly_info *poly)
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightScale", options->scanline_bright_scale);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightOffset", options->scanline_bright_offset);
(*d3dintf->effect.set_float)(curr_effect, "ScanlineOffset", (poly->texture->cur_frame == 0) ? 0.0f : options->scanline_offset);
+ (*d3dintf->effect.set_float)(curr_effect, "RedPower", options->red_power);
+ (*d3dintf->effect.set_float)(curr_effect, "GrnPower", options->green_power);
+ (*d3dintf->effect.set_float)(curr_effect, "BluPower", options->blue_power);
}
else
{
@@ -1062,6 +1065,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
(*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
(*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
+ (*d3dintf->effect.set_float)(curr_effect, "NotchHalfWidth", winoptions.screen_yiq_n());
(*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
(*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
(*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
@@ -1102,6 +1106,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "BValue", (poly->texture->cur_frame == 2) ? 0.0f : ((float)poly->texture->cur_frame * winoptions.screen_yiq_b()));
(*d3dintf->effect.set_float)(curr_effect, "OValue", winoptions.screen_yiq_o());
(*d3dintf->effect.set_float)(curr_effect, "PValue", winoptions.screen_yiq_p());
+ (*d3dintf->effect.set_float)(curr_effect, "NotchHalfWidth", winoptions.screen_yiq_n());
(*d3dintf->effect.set_float)(curr_effect, "YFreqResponse", winoptions.screen_yiq_y());
(*d3dintf->effect.set_float)(curr_effect, "IFreqResponse", winoptions.screen_yiq_i());
(*d3dintf->effect.set_float)(curr_effect, "QFreqResponse", winoptions.screen_yiq_q());
@@ -1156,9 +1161,6 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "RedScale", options->red_scale);
(*d3dintf->effect.set_float)(curr_effect, "GrnScale", options->green_scale);
(*d3dintf->effect.set_float)(curr_effect, "BluScale", options->blue_scale);
- (*d3dintf->effect.set_float)(curr_effect, "RedPower", options->red_power);
- (*d3dintf->effect.set_float)(curr_effect, "GrnPower", options->green_power);
- (*d3dintf->effect.set_float)(curr_effect, "BluPower", options->blue_power);
(*d3dintf->effect.set_float)(curr_effect, "Saturation", options->saturation);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, smalltarget0[poly->texture->target_index]);
diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c
index 48e3310ae90..8a16363b398 100644
--- a/src/osd/windows/winmain.c
+++ b/src/osd/windows/winmain.c
@@ -333,14 +333,14 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_HLSL_PRESCALE_SIZE, "3", OPTION_INTEGER, "HLSL scaling pre-pass factor (usually 2 or 3)" },
{ WINOPTION_HLSL_PRESET";(-1-5)", "-1", OPTION_INTEGER, "HLSL preset to use (0-5)" },
{ WINOPTION_HLSL_WRITE, NULL, OPTION_STRING, "enable 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_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" },
+ { 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", "640", OPTION_INTEGER, "shadow mask width, in phosphor dots" },
- { WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "480", 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_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.0", OPTION_FLOAT, "screen curvature amount" },
{ WINOPTION_SCREEN_SCALE_TOP";fs_scalex(0.0-2.0)", "1.0", OPTION_FLOAT, "screen scale, top" },
{ WINOPTION_SCREEN_SCALE_BOTTOM";fs_scaley(0.0-2.0)", "1.0", OPTION_FLOAT, "screen scale, bottom" },
@@ -389,9 +389,9 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_RED_SCALE";fs_redmul(0.0-2.0)", "1.0", OPTION_FLOAT, "red signal scaling value (multiplicative)" },
{ WINOPTION_GREEN_SCALE";fs_grnmul(0.0-2.0)", "1.0", OPTION_FLOAT, "green signal scaling value (multiplicative)" },
{ WINOPTION_BLUE_SCALE";fs_blumul(0.0-2.0)", "1.0", OPTION_FLOAT, "blue signal scaling value (multiplicative)" },
- { WINOPTION_RED_POWER";fs_redpow(0.01-32.0)", "1.0", OPTION_FLOAT, "red signal power value (exponential)" },
- { WINOPTION_GREEN_POWER";fs_grnpow(0.01-32.0)", "1.0", OPTION_FLOAT, "green signal power value (exponential)" },
- { WINOPTION_BLUE_POWER";fs_blupow(0.01-32.0)", "1.0", OPTION_FLOAT, "blue signal power value (exponential)" },
+ { WINOPTION_RED_POWER";fs_redpow(0.01-4.0)", "1.0", OPTION_FLOAT, "red signal power value (exponential)" },
+ { WINOPTION_GREEN_POWER";fs_grnpow(0.01-4.0)", "1.0", OPTION_FLOAT, "green signal power value (exponential)" },
+ { WINOPTION_BLUE_POWER";fs_blupow(0.01-4.0)", "1.0", OPTION_FLOAT, "blue signal power value (exponential)" },
{ WINOPTION_RED_FLOOR";fs_redfl(0.0-1.0)", "0.0", OPTION_FLOAT, "red signal floor level" },
{ WINOPTION_GREEN_FLOOR";fs_grnfl(0.0-1.0)", "0.0", OPTION_FLOAT, "green signal floor level" },
{ WINOPTION_BLUE_FLOOR";fs_blufl(0.0-1.0)", "0.0", OPTION_FLOAT, "blue signal floor level" },
@@ -405,7 +405,8 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_YIQ_BVALUE";yiqb", "0.5", OPTION_FLOAT, "B value for NTSC signal processing" },
{ WINOPTION_YIQ_OVALUE";yiqo", "0.0", OPTION_FLOAT, "Outgoing Color Carrier phase offset for NTSC signal processing" },
{ WINOPTION_YIQ_PVALUE";yiqp", "1.0", OPTION_FLOAT, "Incoming Pixel Clock scaling value for NTSC signal processing" },
- { WINOPTION_YIQ_YVALUE";yiqy", "3.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
+ { WINOPTION_YIQ_NVALUE";yiqn", "1.0", OPTION_FLOAT, "Y filter notch width for NTSC signal processing" },
+ { WINOPTION_YIQ_YVALUE";yiqy", "6.0", OPTION_FLOAT, "Y filter cutoff frequency for NTSC signal processing" },
{ WINOPTION_YIQ_IVALUE";yiqi", "1.2", OPTION_FLOAT, "I filter cutoff frequency for NTSC signal processing" },
{ WINOPTION_YIQ_QVALUE";yiqq", "0.6", OPTION_FLOAT, "Q filter cutoff frequency for NTSC signal processing" },
{ WINOPTION_YIQ_SCAN_TIME";yiqsc", "52.6", OPTION_FLOAT, "Horizontal scanline duration for NTSC signal processing (in usec)" },
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index fcd97c3cd68..99717cb17ca 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -147,6 +147,7 @@
#define WINOPTION_YIQ_BVALUE "yiq_b"
#define WINOPTION_YIQ_OVALUE "yiq_o"
#define WINOPTION_YIQ_PVALUE "yiq_p"
+#define WINOPTION_YIQ_NVALUE "yiq_n"
#define WINOPTION_YIQ_YVALUE "yiq_y"
#define WINOPTION_YIQ_IVALUE "yiq_i"
#define WINOPTION_YIQ_QVALUE "yiq_q"
@@ -268,6 +269,7 @@ public:
float screen_yiq_b() const { return float_value(WINOPTION_YIQ_BVALUE); }
float screen_yiq_o() const { return float_value(WINOPTION_YIQ_OVALUE); }
float screen_yiq_p() const { return float_value(WINOPTION_YIQ_PVALUE); }
+ float screen_yiq_n() const { return float_value(WINOPTION_YIQ_NVALUE); }
float screen_yiq_y() const { return float_value(WINOPTION_YIQ_YVALUE); }
float screen_yiq_i() const { return float_value(WINOPTION_YIQ_IVALUE); }
float screen_yiq_q() const { return float_value(WINOPTION_YIQ_QVALUE); }