From 43d7ab36632d01856f2d272dbd831b27242f7cd7 Mon Sep 17 00:00:00 2001 From: "Westley M. Martinez" Date: Fri, 16 Dec 2016 14:42:14 -0800 Subject: [PATCH] Implement LCD persistence shader. hlsl/phosphor.fx: Do LCD persistence effect using boolean LCD. LCD persistence is monochrome and thus does not have separate components like phosphor persistence. src/osd/modules/render/d3d/d3dhlsl.cpp: Add slider for LCD games. src/osd/modules/render/d3d/d3dhlsl.h: (BP) Add options for LCD games. src/osd/windows/winmain.cpp: (BP) Add options for LCD games. src/osd/windows/winmain.h: (BP) Add options for LCD games. --- hlsl/phosphor.fx | 17 ++++++++++++----- src/osd/modules/render/d3d/d3dhlsl.cpp | 19 +++++++++++++++++-- src/osd/modules/render/d3d/d3dhlsl.h | 3 +++ src/osd/windows/winmain.cpp | 1 + src/osd/windows/winmain.h | 2 ++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx index c6614d09520..874d67dfded 100644 --- a/hlsl/phosphor.fx +++ b/hlsl/phosphor.fx @@ -93,8 +93,10 @@ VS_OUTPUT vs_main(VS_INPUT Input) // Phosphor Pixel Shader //----------------------------------------------------------------------------- -uniform float DeltaTime = 0.0f; +uniform bool LCD = false; uniform int Mode = 0; +uniform float DeltaTime = 0.0f; +uniform float LCDTau = 0.0f; uniform float3 Tau = { 0.0f, 0.0f, 0.0f }; uniform float3 Beta = { 0.0f, 0.0f, 0.0f }; uniform float3 Gamma = { 0.0f, 0.0f, 0.0f }; @@ -107,15 +109,20 @@ float4 ps_main(PS_INPUT Input) : COLOR float g = PrevPix.g; float b = PrevPix.b; - if (Mode == 0) { + if (LCD) { + r *= LCDTau == 0 ? 0 : exp(-DeltaTime / LCDTau); + g *= LCDTau == 0 ? 0 : exp(-DeltaTime / LCDTau); + b *= LCDTau == 0 ? 0 : exp(-DeltaTime / LCDTau); + } + else if (Mode == 0) { r = 0; g = 0; b = 0; } else if (Mode == 1) { - r *= exp(-DeltaTime / Tau.r); - g *= exp(-DeltaTime / Tau.g); - b *= exp(-DeltaTime / Tau.b); + r *= Tau.r == 0 ? 0 : exp(-DeltaTime / Tau.r); + g *= Tau.g == 0 ? 0 : exp(-DeltaTime / Tau.g); + b *= Tau.b == 0 ? 0 : exp(-DeltaTime / Tau.b); } else { if (r != 0.0f) diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index 3c37b1087de..c07622127cf 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -526,6 +526,7 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r options->phosphor_beta, true); get_vector(winoptions.screen_phosphor_gamma(), 3, options->phosphor_gamma, true); + options->lcd_persistence = winoptions.screen_lcd_persistence(); options->saturation = winoptions.screen_saturation(); options->yiq_enable = winoptions.screen_yiq_enable(); options->yiq_jitter = winoptions.screen_yiq_jitter(); @@ -797,6 +798,7 @@ int shaders::create_resources() phosphor_effect->add_uniform("Tau", uniform::UT_VEC3, uniform::CU_PHOSPHOR_TAU); phosphor_effect->add_uniform("Beta", uniform::UT_VEC3, uniform::CU_PHOSPHOR_BETA); phosphor_effect->add_uniform("Gamma", uniform::UT_VEC3, uniform::CU_PHOSPHOR_GAMMA); + phosphor_effect->add_uniform("LCDTau", uniform::UT_FLOAT, uniform::CU_LCD_PERSISTENCE); 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); @@ -1078,9 +1080,12 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) { int next_index = source_index; + auto stype = machine->first_screen()->screen_type(); // skip phosphor if mode is off - if (options->phosphor_mode == 0) + if ((options->phosphor_mode == 0 && stype == SCREEN_TYPE_RASTER) || + (options->phosphor_mode == 0 && stype == SCREEN_TYPE_VECTOR) || + (options->lcd_persistence == 0 && stype == SCREEN_TYPE_LCD)) { return next_index; } @@ -1091,6 +1096,10 @@ int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *p curr_effect->set_texture("LastPass", rt->cache_texture); curr_effect->set_bool("Passthrough", false); curr_effect->set_float("DeltaTime", delta_time()); + if (stype == SCREEN_TYPE_LCD) + curr_effect->set_bool("LCD", true); + else + curr_effect->set_bool("LCD", false); next_index = rt->next_index(next_index); blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2); @@ -1962,6 +1971,7 @@ enum slider_option SLIDER_PHOSPHOR_TAU, SLIDER_PHOSPHOR_BETA, SLIDER_PHOSPHOR_GAMMA, + SLIDER_LCD_PERSISTENCE, SLIDER_BLOOM_BLEND_MODE, SLIDER_BLOOM_SCALE, SLIDER_BLOOM_OVERDRIVE, @@ -2041,9 +2051,10 @@ slider_desc shaders::s_sliders[] = { "Signal Exponent,", -800, 0, 800, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_POWER, 0.01f, "%2.2f", {} }, { "Signal Floor,", 0, 0, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_FLOOR, 0.01f, "%2.2f", {} }, { "Phosphor Persistence Mode,", 0, 0, 2, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR, SLIDER_PHOSPHOR_MODE, 0, "%s", { "Off", "Exponential", "Inverse Power" } }, - { "Phosphor Persistence tau,", 0, 26, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR, SLIDER_PHOSPHOR_TAU, 0.001f, "%3.3f", {} }, + { "Phosphor Persistence tau,", 1, 26, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR, SLIDER_PHOSPHOR_TAU, 0.001f, "%3.3f", {} }, { "Phosphor Persistence beta,", 50, 70, 200, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR, SLIDER_PHOSPHOR_BETA, 0.01f, "%2.2f", {} }, { "Phosphor Persistence gamma,", 1, 300, 1000, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR, SLIDER_PHOSPHOR_GAMMA, 1, "%.0f", {} }, + { "LCD Perisistence,", 0, 20, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD, SLIDER_LCD_PERSISTENCE, 0.001f, "%3.3f", {} }, { "Bloom Blend Mode", 0, 0, 1, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_BLEND_MODE, 0, "%s", { "Brighten", "Darken" } }, { "Bloom Scale", 0, 0, 2000, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_SCALE, 0.001f, "%1.3f", {} }, { "Bloom Overdrive,", 0, 0, 2000, 5, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_OVERDRIVE, 0.001f, "%1.3f", {} }, @@ -2119,6 +2130,7 @@ void *shaders::get_slider_option(int id, int index) case SLIDER_PHOSPHOR_TAU: return &(options->phosphor_tau[index]); case SLIDER_PHOSPHOR_BETA: return &(options->phosphor_beta[index]); case SLIDER_PHOSPHOR_GAMMA: return &(options->phosphor_gamma[index]); + case SLIDER_LCD_PERSISTENCE: return &(options->lcd_persistence); case SLIDER_BLOOM_BLEND_MODE: return &(options->bloom_blend_mode); case SLIDER_BLOOM_SCALE: return &(options->bloom_scale); case SLIDER_BLOOM_OVERDRIVE: return &(options->bloom_overdrive[index]); @@ -2416,6 +2428,9 @@ void uniform::update() break; case CU_PHOSPHOR_GAMMA: m_shader->set_vector("Gamma", 3, options->phosphor_gamma); + + case CU_LCD_PERSISTENCE: + m_shader->set_float("LCDTau", options->lcd_persistence); case CU_POST_REFLECTION: m_shader->set_float("ReflectionAmount", options->reflection); diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 134698b2fa1..3dda52de423 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -82,6 +82,8 @@ public: CU_PHOSPHOR_BETA, CU_PHOSPHOR_GAMMA, + CU_LCD_PERSISTENCE, + CU_POST_VIGNETTING, CU_POST_DISTORTION, CU_POST_CUBIC_DISTORTION, @@ -210,6 +212,7 @@ struct hlsl_options float phosphor_tau[3]; float phosphor_beta[3]; float phosphor_gamma[3]; + float lcd_persistence; float saturation; // NTSC diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index d93852f9bf0..06607e27f42 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -219,6 +219,7 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_PHOSPHOR_TAU";fs_phosphor_tau", "0.026,0.026,0.026", OPTION_STRING, "exponential time constant" }, { WINOPTION_PHOSPHOR_BETA";fs_phosphor_beta", "0.7,0.7,0.7", OPTION_STRING, "inverse power order" }, { WINOPTION_PHOSPHOR_GAMMA";fs_phosphor_gamma", "300,300,300", OPTION_STRING, "inverse power time constant" }, + { WINOPTION_LCD_PERSISTENCE";fs_lcd_persistence", "0.02", OPTION_STRING, "LCD pixel persistence time constant" }, /* NTSC simulation below this line */ { nullptr, nullptr, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" }, { WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enables YIQ-space HLSL post-processing" }, diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index b939b115b83..a5fb11a8055 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -72,6 +72,7 @@ #define WINOPTION_PHOSPHOR_TAU "phosphor_tau" #define WINOPTION_PHOSPHOR_BETA "phosphor_beta" #define WINOPTION_PHOSPHOR_GAMMA "phosphor_gamma" +#define WINOPTION_LCD_PERSISTENCE "lcd_persistence" #define WINOPTION_SATURATION "saturation" #define WINOPTION_YIQ_ENABLE "yiq_enable" #define WINOPTION_YIQ_JITTER "yiq_jitter" @@ -204,6 +205,7 @@ public: const char* screen_phosphor_tau() const { return value(WINOPTION_PHOSPHOR_TAU); } const char* screen_phosphor_beta() const { return value(WINOPTION_PHOSPHOR_BETA); } const char* screen_phosphor_gamma() const { return value(WINOPTION_PHOSPHOR_GAMMA); } + float screen_lcd_persistence() const { return float_value(WINOPTION_LCD_PERSISTENCE); } float screen_saturation() const { return float_value(WINOPTION_SATURATION); } // full screen options