diff options
author | 2016-12-16 12:35:58 -0800 | |
---|---|---|
committer | 2016-12-29 14:57:28 -0800 | |
commit | 0b6f935443d2fa048a9b2f9db8b00cf6cb8e7078 (patch) | |
tree | 25f40a0e82b5142c3249aae70fbba1a05bcb00c1 | |
parent | 1fafe7706cbfcfc6e39c23c3c713fbb102557cbe (diff) |
Implement new phosphor shader.
hlsl/phosphor.fx: Make changes to the pixel shader. New
uniforms: Mode, Tau, Beta, Gamma. Remove Phosphor. Mode selects the
mode for phosphor simulation: off (no decay), exponential, inverse
power. Tau is the time constant for exp. decay. Beta and Gamma are
constants for inv-pow.
src/osd/modules/render/d3d/d3dhlsl.cpp: Provide uniforms and add
sliders for new options.
src/osd/modules/render/d3d/d3dhlsl.h: (BP) Provide new options.
src/osd/windows/winmain.cpp: (BP) Provide new options.
src/osd/windows/winmain.h: (BP) Provide new options.
-rw-r--r-- | hlsl/phosphor.fx | 38 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.cpp | 47 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.h | 10 | ||||
-rw-r--r-- | src/osd/windows/winmain.cpp | 5 | ||||
-rw-r--r-- | src/osd/windows/winmain.h | 10 |
5 files changed, 86 insertions, 24 deletions
diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx index d78473a2c6e..c6614d09520 100644 --- a/hlsl/phosphor.fx +++ b/hlsl/phosphor.fx @@ -93,21 +93,41 @@ VS_OUTPUT vs_main(VS_INPUT Input) // Phosphor Pixel Shader //----------------------------------------------------------------------------- -uniform float3 Phosphor = float3(0.0f, 0.0f, 0.0f); uniform float DeltaTime = 0.0f; -static const float F = 30.0f; +uniform int Mode = 0; +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 }; float4 ps_main(PS_INPUT Input) : COLOR { float4 CurrPix = tex2D(DiffuseSampler, Input.TexCoord); float3 PrevPix = tex2D(PreviousSampler, Input.PrevCoord).rgb; - - PrevPix.r *= Phosphor.r == 0 ? 0 : pow(Phosphor.r, F * DeltaTime); - PrevPix.g *= Phosphor.g == 0 ? 0 : pow(Phosphor.g, F * DeltaTime); - PrevPix.b *= Phosphor.b == 0 ? 0 : pow(Phosphor.b, F * DeltaTime); - float RedMax = max(CurrPix.r, PrevPix.r); - float GreenMax = max(CurrPix.g, PrevPix.g); - float BlueMax = max(CurrPix.b, PrevPix.b); + float r = PrevPix.r; + float g = PrevPix.g; + float b = PrevPix.b; + + 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); + } + else { + if (r != 0.0f) + r = pow(Gamma.r * DeltaTime + pow(1 / r, 1 / Beta.r), -Beta.r); + if (g != 0.0f) + g = pow(Gamma.g * DeltaTime + pow(1 / g, 1 / Beta.g), -Beta.g); + if (b != 0.0f) + b = pow(Gamma.b * DeltaTime + pow(1 / b, 1 / Beta.b), -Beta.b); + } + float RedMax = max(CurrPix.r, r); + float GreenMax = max(CurrPix.g, g); + float BlueMax = max(CurrPix.b, b); return Passthrough ? CurrPix : float4(RedMax, GreenMax, BlueMax, CurrPix.a); diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index a6cfad8cae9..3c37b1087de 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -1,4 +1,5 @@ // license:BSD-3-Clause +// // copyright-holders:Aaron Giles //============================================================ // @@ -518,7 +519,13 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r get_vector(winoptions.screen_scale(), 3, options->scale, true); get_vector(winoptions.screen_power(), 3, options->power, true); get_vector(winoptions.screen_floor(), 3, options->floor, true); - get_vector(winoptions.screen_phosphor(), 3, options->phosphor, true); + options->phosphor_mode = winoptions.screen_phosphor_mode(); + get_vector(winoptions.screen_phosphor_tau(), 3, + options->phosphor_tau, true); + get_vector(winoptions.screen_phosphor_beta(), 3, + options->phosphor_beta, true); + get_vector(winoptions.screen_phosphor_gamma(), 3, + options->phosphor_gamma, true); options->saturation = winoptions.screen_saturation(); options->yiq_enable = winoptions.screen_yiq_enable(); options->yiq_jitter = winoptions.screen_yiq_jitter(); @@ -786,7 +793,10 @@ int shaders::create_resources() focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE); - phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE); + phosphor_effect->add_uniform("Mode", uniform::UT_INT, uniform::CU_PHOSPHOR_MODE); + 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); 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); @@ -1069,13 +1079,12 @@ int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *p { int next_index = source_index; - // skip phosphor if no influencing settings - if (options->phosphor[0] == 0.0f && options->phosphor[1] == 0.0f && options->phosphor[2] == 0.0f) + // skip phosphor if mode is off + if (options->phosphor_mode == 0) { return next_index; } - // Shader needs time between last update curr_effect = phosphor_effect; curr_effect->update_uniforms(); curr_effect->set_texture("Diffuse", rt->target_texture[next_index]); @@ -1949,7 +1958,10 @@ enum slider_option SLIDER_SCALE, SLIDER_POWER, SLIDER_FLOOR, - SLIDER_PHOSPHOR, + SLIDER_PHOSPHOR_MODE, + SLIDER_PHOSPHOR_TAU, + SLIDER_PHOSPHOR_BETA, + SLIDER_PHOSPHOR_GAMMA, SLIDER_BLOOM_BLEND_MODE, SLIDER_BLOOM_SCALE, SLIDER_BLOOM_OVERDRIVE, @@ -1982,6 +1994,7 @@ enum slider_screen_type SLIDER_SCREEN_TYPE_RASTER = 1, SLIDER_SCREEN_TYPE_VECTOR = 2, SLIDER_SCREEN_TYPE_LCD = 4, + SLIDER_SCREEN_TYPE_RASTER_OR_VECTOR = SLIDER_SCREEN_TYPE_RASTER | SLIDER_SCREEN_TYPE_VECTOR, SLIDER_SCREEN_TYPE_LCD_OR_RASTER = SLIDER_SCREEN_TYPE_RASTER | SLIDER_SCREEN_TYPE_LCD, SLIDER_SCREEN_TYPE_ANY = SLIDER_SCREEN_TYPE_RASTER | SLIDER_SCREEN_TYPE_VECTOR | SLIDER_SCREEN_TYPE_LCD }; @@ -2027,7 +2040,10 @@ slider_desc shaders::s_sliders[] = { "Signal Scale,", -200, 100, 200, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_SCALE, 0.01f, "%2.2f", {} }, { "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,", 0, 0, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_PHOSPHOR, 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 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", {} }, { "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", {} }, @@ -2099,7 +2115,10 @@ void *shaders::get_slider_option(int id, int index) case SLIDER_SCALE: return &(options->scale[index]); case SLIDER_POWER: return &(options->power[index]); case SLIDER_FLOOR: return &(options->floor[index]); - case SLIDER_PHOSPHOR: return &(options->phosphor[index]); + case SLIDER_PHOSPHOR_MODE: return &(options->phosphor_mode); + 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_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]); @@ -2386,9 +2405,17 @@ void uniform::update() m_shader->set_vector("Defocus", 2, &options->defocus[0]); break; - case CU_PHOSPHOR_LIFE: - m_shader->set_vector("Phosphor", 3, options->phosphor); + case CU_PHOSPHOR_MODE: + m_shader->set_int("Mode", options->phosphor_mode); + break; + case CU_PHOSPHOR_TAU: + m_shader->set_vector("Tau", 3, options->phosphor_tau); + break; + case CU_PHOSPHOR_BETA: + m_shader->set_vector("Beta", 3, options->phosphor_beta); break; + case CU_PHOSPHOR_GAMMA: + m_shader->set_vector("Gamma", 3, options->phosphor_gamma); 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 ed25d2c52e8..134698b2fa1 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -77,7 +77,10 @@ public: CU_FOCUS_SIZE, - CU_PHOSPHOR_LIFE, + CU_PHOSPHOR_MODE, + CU_PHOSPHOR_TAU, + CU_PHOSPHOR_BETA, + CU_PHOSPHOR_GAMMA, CU_POST_VIGNETTING, CU_POST_DISTORTION, @@ -203,7 +206,10 @@ struct hlsl_options float scale[3]; float power[3]; float floor[3]; - float phosphor[3]; + int phosphor_mode; + float phosphor_tau[3]; + float phosphor_beta[3]; + float phosphor_gamma[3]; float saturation; // NTSC diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index b146e8b6357..d93852f9bf0 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -215,7 +215,10 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_SCALE";fs_scale", "1.0,1.0,1.0", OPTION_STRING, "signal scaling value (multiplicative)" }, { WINOPTION_POWER";fs_power", "1.0,1.0,1.0", OPTION_STRING, "signal power value (exponential)" }, { WINOPTION_FLOOR";fs_floor", "0.0,0.0,0.0", OPTION_STRING, "signal floor level" }, - { WINOPTION_PHOSPHOR";fs_phosphor", "0.0,0.0,0.0", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" }, + { WINOPTION_PHOSPHOR_MODE";fs_phosphor_mode", "0", OPTION_STRING, "phosphorescence decay mode (0: off, 1: exponential, 2: inverse-power)" }, + { 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" }, /* 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 1c40a346d34..b939b115b83 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -68,7 +68,10 @@ #define WINOPTION_SCALE "scale" #define WINOPTION_POWER "power" #define WINOPTION_FLOOR "floor" -#define WINOPTION_PHOSPHOR "phosphor_life" +#define WINOPTION_PHOSPHOR_MODE "phosphor_mode" +#define WINOPTION_PHOSPHOR_TAU "phosphor_tau" +#define WINOPTION_PHOSPHOR_BETA "phosphor_beta" +#define WINOPTION_PHOSPHOR_GAMMA "phosphor_gamma" #define WINOPTION_SATURATION "saturation" #define WINOPTION_YIQ_ENABLE "yiq_enable" #define WINOPTION_YIQ_JITTER "yiq_jitter" @@ -197,7 +200,10 @@ public: const char *screen_scale() const { return value(WINOPTION_SCALE); } const char *screen_power() const { return value(WINOPTION_POWER); } const char *screen_floor() const { return value(WINOPTION_FLOOR); } - const char *screen_phosphor() const { return value(WINOPTION_PHOSPHOR); } + int screen_phosphor_mode() const { return int_value(WINOPTION_PHOSPHOR_MODE); } + 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_saturation() const { return float_value(WINOPTION_SATURATION); } // full screen options |