From 8ed3a7d94a65ee01bf1adce3ea8118c04d41a18d Mon Sep 17 00:00:00 2001 From: ImJezze Date: Mon, 18 Apr 2016 20:25:28 +0200 Subject: [PATCH] Refactored distortion pass - separated curvature parameter into distortion, cubic_distortion and distort_corner - distortion and cubic_distortion can be negative, to compensate each other - distort_corner is intependent from the image distortion --- docs/hlsl.txt | 4 ++- hlsl/distortion.fx | 39 ++++++++++++++++++-------- ini/presets/gameboy.ini | 4 ++- ini/presets/gba.ini | 4 ++- ini/presets/lcd-matrix.ini | 4 ++- ini/presets/lcd.ini | 4 ++- ini/presets/raster.ini | 4 ++- ini/presets/vector-mono.ini | 4 ++- ini/presets/vector.ini | 4 ++- src/osd/modules/render/d3d/d3dhlsl.cpp | 34 ++++++++++++++++------ src/osd/modules/render/d3d/d3dhlsl.h | 8 ++++-- src/osd/windows/winmain.cpp | 4 ++- src/osd/windows/winmain.h | 8 ++++-- 13 files changed, 93 insertions(+), 32 deletions(-) diff --git a/docs/hlsl.txt b/docs/hlsl.txt index db6cfa6def4..13382f97273 100644 --- a/docs/hlsl.txt +++ b/docs/hlsl.txt @@ -27,7 +27,9 @@ shadow_mask_usize 0.0 to 1.0 The size of one shadow mask tile in U/V shadow_mask_vsize 0.0 to 1.0 The shadow mask textures always has a size of power-of-two. shadow_mask_voffset -1.0 to 1.0 The offset of the shadow mask texture in U/V coordinates. shadow_mask_voffset -1.0 to 1.0 An offset of 1.0 repressents one pixel on screen. -curvature 0.0 to 1.0 Curvature amount of the screen. +distortion -1.0 to 1.0 Distortion amount of the screen. +cubic_distortion -1.0 to 1.0 Cubic Distortion amount of the screen. +distort_corner 0.0 to 1.0 Distorted corners amount of the screen. round_corner 0.0 to 1.0 Rounded corners amount of the screen. smooth_border 0.0 to 1.0 Smooth borders amount of the screen. reflection 0.0 to 1.0 Refelection amount of the screen highlight. diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx index e33b8811ba5..f683397b17a 100644 --- a/hlsl/distortion.fx +++ b/hlsl/distortion.fx @@ -111,7 +111,9 @@ VS_OUTPUT vs_main(VS_INPUT Input) // Distortion Pixel Shader //----------------------------------------------------------------------------- -uniform float CurvatureAmount = 0.0f; +uniform float DistortionAmount = 0.0f; // k - quartic distortion coefficient +uniform float CubicDistortionAmount = 0.0f; // kcube - cubic distortion modifier +uniform float DistortCornerAmount = 0.0f; uniform float RoundCornerAmount = 0.0f; uniform float SmoothBorderAmount = 0.0f; uniform float VignettingAmount = 0.0f; @@ -195,13 +197,13 @@ float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) } // www.francois-tarlier.com/blog/cubic-lens-distortion-shader/ -float2 GetDistortedCoords(float2 centerCoord, float amount) +float2 GetDistortedCoords(float2 centerCoord, float amount, float amountCube) { // lens distortion coefficient float k = amount; // cubic distortion value - float kcube = amount * 2.0f; + float kcube = amountCube; // compute cubic distortion factor float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y; @@ -210,7 +212,7 @@ float2 GetDistortedCoords(float2 centerCoord, float amount) : 1.0f + r2 * (k + kcube * sqrt(r2)); // fit screen bounds - f /= 1.0f + amount * 0.5f; + f /= 1.0f + amount * 0.25 + amountCube * 0.125f; // apply cubic distortion factor centerCoord *= f; @@ -218,13 +220,13 @@ float2 GetDistortedCoords(float2 centerCoord, float amount) return centerCoord; } -float2 GetCoords(float2 coord, float distortionAmount) +float2 GetCoords(float2 coord, float distortionAmount, float cubicDistortionAmount) { // center coordinates coord -= 0.5f; // distort coordinates - coord = GetDistortedCoords(coord, distortionAmount); + coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount); // un-center coordinates coord += 0.5f; @@ -234,18 +236,33 @@ float2 GetCoords(float2 coord, float distortionAmount) float4 ps_main(PS_INPUT Input) : COLOR { + float distortionAmount = DistortionAmount; + float cubicDistortionAmount = CubicDistortionAmount > 0 + ? CubicDistortionAmount * 1.1 // cubic distortion need to be a little higher to compensate the quartic distortion + : CubicDistortionAmount * 1.2; // negativ values even more + + float2 TexelDims = 1.0f / TargetDims; + // Screen Curvature - float2 TexCoord = GetCoords(Input.TexCoord, CurvatureAmount * 0.25f); // reduced amount + float2 TexCoord = GetCoords(Input.TexCoord, distortionAmount, cubicDistortionAmount); + + // Corner Curvature + float2 CornerCoord = GetCoords(Input.TexCoord, DistortCornerAmount, 0.0f); + + // clip border + clip(TexCoord < 0.0f - TexelDims || TexCoord > 1.0f + TexelDims ? -1 : 1); float2 TexCoordCentered = TexCoord; TexCoordCentered -= 0.5f; + float2 CornerCoordCentered = CornerCoord; + CornerCoordCentered -= 0.5f; // Color float4 BaseColor = tex2D(DiffuseSampler, TexCoord); BaseColor.a = 1.0f; // Vignetting Simulation - float2 VignetteCoord = TexCoordCentered; + float2 VignetteCoord = CornerCoordCentered; float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); BaseColor.rgb *= VignetteFactor; @@ -253,15 +270,15 @@ float4 ps_main(PS_INPUT Input) : COLOR // Light Reflection Simulation float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin - float2 SpotCoord = TexCoordCentered; - float2 NoiseCoord = TexCoordCentered; + float2 SpotCoord = CornerCoordCentered; + float2 NoiseCoord = CornerCoordCentered; float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); BaseColor.rgb += SpotAddend * NoiseFactor * LightColor; // Round Corners Simulation - float2 RoundCornerCoord = TexCoordCentered; + float2 RoundCornerCoord = CornerCoordCentered; float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount); BaseColor.rgb *= roundCornerFactor; diff --git a/ini/presets/gameboy.ini b/ini/presets/gameboy.ini index 763ce5b78d5..f24453232ce 100644 --- a/ini/presets/gameboy.ini +++ b/ini/presets/gameboy.ini @@ -10,7 +10,9 @@ shadow_mask_usize 0.5 shadow_mask_vsize 0.5 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/gba.ini b/ini/presets/gba.ini index 0c8308fc072..40b1274b52f 100644 --- a/ini/presets/gba.ini +++ b/ini/presets/gba.ini @@ -10,7 +10,9 @@ shadow_mask_usize 0.1875 shadow_mask_vsize 0.1875 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/lcd-matrix.ini b/ini/presets/lcd-matrix.ini index f9de4013eca..7c97229d9f4 100644 --- a/ini/presets/lcd-matrix.ini +++ b/ini/presets/lcd-matrix.ini @@ -10,7 +10,9 @@ shadow_mask_usize 0.5 shadow_mask_vsize 0.5 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/lcd.ini b/ini/presets/lcd.ini index 0c8308fc072..40b1274b52f 100644 --- a/ini/presets/lcd.ini +++ b/ini/presets/lcd.ini @@ -10,7 +10,9 @@ shadow_mask_usize 0.1875 shadow_mask_vsize 0.1875 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/raster.ini b/ini/presets/raster.ini index 7e589fe9cb2..302ef5904fa 100644 --- a/ini/presets/raster.ini +++ b/ini/presets/raster.ini @@ -10,7 +10,9 @@ shadow_mask_usize 0.1875 shadow_mask_vsize 0.25 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/vector-mono.ini b/ini/presets/vector-mono.ini index 6a3db343cb3..5ff73b66c21 100644 --- a/ini/presets/vector-mono.ini +++ b/ini/presets/vector-mono.ini @@ -17,7 +17,9 @@ flicker 0.15 # hlsl_oversampling 0 shadow_mask_alpha 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/ini/presets/vector.ini b/ini/presets/vector.ini index 1aeb22c5f86..f7311cceb38 100644 --- a/ini/presets/vector.ini +++ b/ini/presets/vector.ini @@ -20,7 +20,9 @@ shadow_mask_usize 0.1875 shadow_mask_vsize 0.25 shadow_mask_uoffset 0.0 shadow_mask_voffset 0.0 -curvature 0.0 +distortion 0.0 +cubic_distortion 0.0 +distort_corner 0.0 round_corner 0.0 smooth_border 0.0 reflection 0.0 diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index 4ee6fcbd5ac..000fd254fe0 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -680,7 +680,9 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r 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->distortion = winoptions.screen_distortion(); + options->cubic_distortion = winoptions.screen_cubic_distortion(); + options->distort_corner = winoptions.screen_distort_corner(); options->round_corner = winoptions.screen_round_corner(); options->smooth_border = winoptions.screen_smooth_border(); options->reflection = winoptions.screen_reflection(); @@ -989,7 +991,9 @@ int shaders::create_resources(bool reset, std::vector& sliders) post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR); distortion_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING); - distortion_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE); + distortion_effect->add_uniform("DistortionAmount", uniform::UT_FLOAT, uniform::CU_POST_DISTORTION); + distortion_effect->add_uniform("CubicDistortionAmount", uniform::UT_FLOAT, uniform::CU_POST_CUBIC_DISTORTION); + distortion_effect->add_uniform("DistortCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_DISTORT_CORNER); distortion_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER); 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); @@ -1496,7 +1500,9 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info // skip distortion if no influencing settings if (options->reflection == 0 && options->vignetting == 0 && - options->curvature == 0 && + options->distortion == 0 && + options->cubic_distortion == 0 && + options->distort_corner == 0 && options->round_corner == 0 && options->smooth_border == 0) { @@ -2277,7 +2283,9 @@ enum slider_option SLIDER_SHADOW_MASK_V_SIZE, SLIDER_SHADOW_MASK_U_OFFSET, SLIDER_SHADOW_MASK_V_OFFSET, - SLIDER_CURVATURE, + SLIDER_DISTORTION, + SLIDER_CUBIC_DISTORTION, + SLIDER_DISTORT_CORNER, SLIDER_ROUND_CORNER, SLIDER_SMOOTH_BORDER, SLIDER_REFLECTION, @@ -2352,7 +2360,9 @@ slider_desc shaders::s_sliders[] = { "Shadow Mask Pixel Count Y", 1, 1, 64, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_SHADOW_MASK_V_SIZE, 0.03125f, "%2.5f", {} }, { "Shadow Mask Offset X", -100, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_SHADOW_MASK_U_OFFSET, 0.01f, "%1.2f", {} }, { "Shadow Mask Offset Y", -100, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_SHADOW_MASK_V_OFFSET, 0.01f, "%1.2f", {} }, - { "Screen Curvature", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_CURVATURE, 0.01f, "%2.2f", {} }, + { "Screen Distortion", -100, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_DISTORTION, 0.01f, "%2.2f", {} }, + { "Screen Distortion (Cubic)", -100, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_CUBIC_DISTORTION, 0.01f, "%2.2f", {} }, + { "Screen Distort Corner", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_DISTORT_CORNER, 0.01f, "%1.2f", {} }, { "Screen Round Corner", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_ROUND_CORNER, 0.01f, "%1.2f", {} }, { "Screen Smooth Border", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_SMOOTH_BORDER, 0.01f, "%1.2f", {} }, { "Screen Reflection", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_REFLECTION, 0.01f, "%1.2f", {} }, @@ -2421,7 +2431,9 @@ void *shaders::get_slider_option(int id, int index) case SLIDER_SHADOW_MASK_V_SIZE: return &(options->shadow_mask_v_size); case SLIDER_SHADOW_MASK_U_OFFSET: return &(options->shadow_mask_u_offset); case SLIDER_SHADOW_MASK_V_OFFSET: return &(options->shadow_mask_v_offset); - case SLIDER_CURVATURE: return &(options->curvature); + case SLIDER_DISTORTION: return &(options->distortion); + case SLIDER_CUBIC_DISTORTION: return &(options->cubic_distortion); + case SLIDER_DISTORT_CORNER: return &(options->distort_corner); case SLIDER_ROUND_CORNER: return &(options->round_corner); case SLIDER_SMOOTH_BORDER: return &(options->smooth_border); case SLIDER_REFLECTION: return &(options->reflection); @@ -2756,8 +2768,14 @@ void uniform::update() case CU_POST_VIGNETTING: m_shader->set_float("VignettingAmount", options->vignetting); break; - case CU_POST_CURVATURE: - m_shader->set_float("CurvatureAmount", options->curvature); + case CU_POST_DISTORTION: + m_shader->set_float("DistortionAmount", options->distortion); + break; + case CU_POST_CUBIC_DISTORTION: + m_shader->set_float("CubicDistortionAmount", options->cubic_distortion); + break; + case CU_POST_DISTORT_CORNER: + m_shader->set_float("DistortCornerAmount", options->distort_corner); break; case CU_POST_ROUND_CORNER: m_shader->set_float("RoundCornerAmount", options->round_corner); diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 738d77330f7..8851531678e 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -81,7 +81,9 @@ public: CU_PHOSPHOR_IGNORE, CU_POST_VIGNETTING, - CU_POST_CURVATURE, + CU_POST_DISTORTION, + CU_POST_CUBIC_DISTORTION, + CU_POST_DISTORT_CORNER, CU_POST_ROUND_CORNER, CU_POST_SMOOTH_BORDER, CU_POST_REFLECTION, @@ -197,7 +199,9 @@ struct hlsl_options float shadow_mask_v_size; float shadow_mask_u_offset; float shadow_mask_v_offset; - float curvature; + float distortion; + float cubic_distortion; + float distort_corner; float round_corner; float smooth_border; float reflection; diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index ba3e6af9c4a..7edb996fb0a 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -170,7 +170,9 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.25", OPTION_FLOAT, "shadow mask texture height, in U/V dimensions" }, { 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.0", OPTION_FLOAT, "screen curvature amount" }, + { WINOPTION_DISTORTION";fs_dist(-1.0-1.0)", "0.0", OPTION_FLOAT, "screen distortion amount" }, + { WINOPTION_CUBIC_DISTORTION";fs_cubedist(-1.0-1.0)", "0.0", OPTION_FLOAT, "screen cubic distortion amount" }, + { WINOPTION_DISTORT_CORNER";fs_distc(0.0-1.0)", "0.0", OPTION_FLOAT, "screen distort corner amount" }, { WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.0", OPTION_FLOAT, "screen round corner amount" }, { WINOPTION_SMOOTH_BORDER";fs_smob(0.0-1.0)", "0.0", OPTION_FLOAT, "screen smooth border amount" }, { WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.0", OPTION_FLOAT, "screen reflection amount" }, diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 94d422a545b..48559039d0f 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -42,7 +42,9 @@ #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_DISTORTION "distortion" +#define WINOPTION_CUBIC_DISTORTION "cubic_distortion" +#define WINOPTION_DISTORT_CORNER "distort_corner" #define WINOPTION_ROUND_CORNER "round_corner" #define WINOPTION_SMOOTH_BORDER "smooth_border" #define WINOPTION_VIGNETTING "vignetting" @@ -149,7 +151,9 @@ public: float screen_scanline_jitter() const { return float_value(WINOPTION_SCANLINE_JITTER); } float screen_hum_bar_alpha() const { return float_value(WINOPTION_HUM_BAR_ALPHA); } float screen_reflection() const { return float_value(WINOPTION_REFLECTION); } - float screen_curvature() const { return float_value(WINOPTION_CURVATURE); } + float screen_distortion() const { return float_value(WINOPTION_DISTORTION); } + float screen_cubic_distortion() const { return float_value(WINOPTION_CUBIC_DISTORTION); } + float screen_distort_corner() const { return float_value(WINOPTION_DISTORT_CORNER); } float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); } float screen_smooth_border() const { return float_value(WINOPTION_SMOOTH_BORDER); } float screen_vignetting() const { return float_value(WINOPTION_VIGNETTING); }