mirror of
https://github.com/holub/mame
synced 2025-04-15 13:07:23 +03:00
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
This commit is contained in:
parent
a86983713d
commit
8ed3a7d94a
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<ui_menu_item>& 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);
|
||||
|
@ -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;
|
||||
|
@ -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" },
|
||||
|
@ -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); }
|
||||
|
Loading…
Reference in New Issue
Block a user