Vector curvature correction

- corrected vector curvature on x-axis when screen dims and render
target dims differ (there is still a difference on y-axis)
This commit is contained in:
ImJezze 2015-07-19 12:28:51 +02:00
parent 9ce2864141
commit d132946c6f
2 changed files with 56 additions and 32 deletions

View file

@ -66,11 +66,13 @@ bool xor(bool a, bool b)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3)
uniform float2 SourceDims; // size of the texture in power-of-two size uniform float2 SourceDims; // size of the texture in power-of-two size
uniform float2 SourceRect; // size of the uv rectangle uniform float2 SourceRect; // size of the uv rectangle
uniform float2 TargetDims; // size of target
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
@ -142,7 +144,7 @@ static const float Epsilon = 1.0e-7f;
static const float PI = 3.1415927f; static const float PI = 3.1415927f;
static const float E = 2.7182817f; static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (GelfondSchneider constant) static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
float nextPowerOfTwo(float n) float nextPowerOfTwo(float n)
{ {
@ -214,9 +216,13 @@ float RoundBox(float2 p, float2 b, float r)
float GetRoundCornerFactor(float2 coord, float amount) float GetRoundCornerFactor(float2 coord, float amount)
{ {
float2 SourceArea = 1.0f / SourceRect; // hint: vector target area is always quadratic
float2 SourceRes = SourceDims * SourceRect; float2 UsedSourceRect = PrepareVector
float2 SourceRatio = float2(1.0f, SourceRes.y / SourceRes.x); ? float2(1.0f, 1.0f)
: SourceRect;
float2 SourceArea = 1.0f / UsedSourceRect;
float2 SourceDimsArea = SourceDims * UsedSourceRect;
float2 SourceRatio = float2(1.0f, SourceDimsArea.y / SourceDimsArea.x);
float2 SourceTexelDims = 1.0f / SourceDims; float2 SourceTexelDims = 1.0f / SourceDims;
// base on the default ratio of 4:3 // base on the default ratio of 4:3
@ -250,24 +256,24 @@ float4 ps_main(PS_INPUT Input) : COLOR
float2 ScreenTexelDims = 1.0f / ScreenDims; float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims; float2 SourceTexelDims = 1.0f / SourceDims;
float2 SourceArea = 1.0f / SourceRect; // hint: vector target area is always quadratic
float2 HalfSourceRect = SourceRect * 0.5f; float2 UsedSourceRect = PrepareVector
? float2(1.0f, 1.0f)
: SourceRect;
float UsedCurvatureAmount = CurvatureAmount * 0.25f; // reduced curvature
float2 SourceArea = 1.0f / UsedSourceRect;
float2 DoubleSourceArea = SourceArea * 2.0f;
float SquareSourceAreaLength = pow(length(SourceArea), 2.0f);
float2 HalfSourceRect = UsedSourceRect * 0.5f;
// Screen Curvature // Screen Curvature
float2 CurvatureUnitCoord = float2 CurvatureUnitCoord = (Input.TexCoord * DoubleSourceArea) - 1.0f;
Input.TexCoord float2 CurvatureFactor = (1.0 / SquareSourceAreaLength) * UsedCurvatureAmount;
* SourceArea * 2.0f - float2 CurvatureCurve = CurvatureUnitCoord * pow(length(CurvatureUnitCoord), 2.0f) * CurvatureFactor;
1.0f; float2 CurvatureZoom = 1.0f - (DoubleSourceArea * CurvatureFactor);
float2 CurvatureCurve =
CurvatureUnitCoord // todo: vector cuverture requires a correction on y-axis if screen and target size differ and y > x
* pow(length(CurvatureUnitCoord), 2.0f)
/ pow(length(SourceArea), 2.0f)
* CurvatureAmount * 0.25f; // reduced curvature
float2 CurvatureZoom =
1.0f -
SourceArea * 2.0f
/ pow(length(SourceArea), 2.0f)
* CurvatureAmount * 0.25f; // reduced curvature
float2 ScreenCoord = Input.ScreenCoord / ScreenDims; float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
ScreenCoord -= HalfSourceRect; ScreenCoord -= HalfSourceRect;
@ -280,11 +286,26 @@ float4 ps_main(PS_INPUT Input) : COLOR
BaseCoord *= CurvatureZoom; // zoom BaseCoord *= CurvatureZoom; // zoom
BaseCoord += HalfSourceRect; BaseCoord += HalfSourceRect;
BaseCoord += CurvatureCurve; // distortion BaseCoord += CurvatureCurve; // distortion
float2 CurvatureCorrection = 1.0f;
// vector cuverture correction
if (PrepareVector)
{
float ScreenRatio = ScreenDims.x / ScreenDims.y;
float TargetRatio = TargetDims.x / TargetDims.y;
// hint: vector cuverture requires a correction on the x-axis by the amount that screen and target size differ
CurvatureCorrection.x +=
(ScreenRatio / TargetRatio - 1.0f)
* (1.0f + SquareSourceAreaLength * UsedCurvatureAmount);
}
// the floowing coordinates are used for effects
float2 BaseCoordCentered = Input.TexCoord; float2 BaseCoordCentered = Input.TexCoord;
BaseCoordCentered -= HalfSourceRect; BaseCoordCentered -= HalfSourceRect;
BaseCoordCentered *= CurvatureZoom; // zoom BaseCoordCentered *= CurvatureZoom * CurvatureCorrection; // zoom
BaseCoordCentered += CurvatureCurve; // distortion BaseCoordCentered += CurvatureCurve * CurvatureCorrection; // distortion
float2 BaseAreaCoord = BaseCoord; float2 BaseAreaCoord = BaseCoord;
BaseAreaCoord *= SourceArea; BaseAreaCoord *= SourceArea;
@ -304,6 +325,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f; BaseColor.a = 1.0f;
// BaseColor.rgb = 1.0f;
// Vignetting Simulation (may affect bloom) // Vignetting Simulation (may affect bloom)
float2 VignetteCoord = BaseAreaCoordCentered; float2 VignetteCoord = BaseAreaCoordCentered;

View file

@ -1446,6 +1446,9 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
float prescale[2] = { float prescale[2] = {
prepare_vector ? 1.0f : (float)hlsl_prescale_x, prepare_vector ? 1.0f : (float)hlsl_prescale_x,
prepare_vector ? 1.0f : (float)hlsl_prescale_y }; prepare_vector ? 1.0f : (float)hlsl_prescale_y };
float target_dims[2] = {
poly->get_prim_width(),
poly->get_prim_height() };
bool orientation_swap_xy = bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy = bool rotation_swap_xy =
@ -1458,24 +1461,23 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int
curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]); curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
curr_effect->set_float("ScanlineOffset", texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset); curr_effect->set_float("ScanlineOffset", texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset);
curr_effect->set_vector("Prescale", 2, prescale); curr_effect->set_vector("Prescale", 2, prescale);
curr_effect->set_vector("TargetDims", 2, target_dims);
curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy); curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy);
curr_effect->set_bool("RotationSwapXY", rotation_swap_xy); curr_effect->set_bool("RotationSwapXY", rotation_swap_xy);
curr_effect->set_bool("PrepareBloom", prepare_bloom); curr_effect->set_bool("PrepareBloom", prepare_bloom);
curr_effect->set_bool("PrepareVector", prepare_vector);
if (prepare_vector) if (prepare_vector)
{ {
int source_width = d3d->get_width(); int texture_width = 0;
int source_height = d3d->get_height(); int texture_height = 0;
int target_width = 0;
int target_height = 0;
texture_info::compute_size_subroutine(d3d->get_texture_manager(), source_width, source_height, &target_width, &target_height); texture_info::compute_size_subroutine(d3d->get_texture_manager(), (int)target_dims[0], (int)target_dims[1], &texture_width, &texture_height);
// todo: fix fullscreen float source_dims[2] = { (float)texture_width, (float)texture_height };
float source_dims[2] = { (float)target_width, (float)source_height }; float source_rect[2] = { target_dims[0] / texture_width , target_dims[1] / texture_height };
float source_rect[2] = { 1.0f, 1.0f };
curr_effect->set_bool("PrepareVector", prepare_vector); // override uniforms
curr_effect->set_vector("SourceDims", 2, source_dims); curr_effect->set_vector("SourceDims", 2, source_dims);
curr_effect->set_vector("SourceRect", 2, source_rect); curr_effect->set_vector("SourceRect", 2, source_rect);
} }