Improve Interpolation Accuracy (#1686)

* Fix Up Y Interp Inputs

* Change Linear Interp Formula

Fixes a handful of pixels.
Still not perfect.

* Cleanup

remove some unnecessary code and parentheses
This commit is contained in:
Jaklyy 2023-08-10 12:00:40 -04:00 committed by GitHub
parent 7731f66e55
commit 5f9e7e19f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 29 deletions

View File

@ -78,13 +78,12 @@ private:
this->x1 = x1; this->x1 = x1;
this->xdiff = x1 - x0; this->xdiff = x1 - x0;
// calculate reciprocals for linear mode and Z interpolation // calculate reciprocal for Z interpolation
// TODO eventually: use a faster reciprocal function? // TODO eventually: use a faster reciprocal function?
if (this->xdiff != 0) if (this->xdiff != 0)
this->xrecip = (1<<30) / this->xdiff; this->xrecip_z = (1<<22) / this->xdiff;
else else
this->xrecip = 0; this->xrecip_z = 0;
this->xrecip_z = this->xrecip >> 8;
// linear mode is used if both W values are equal and have // linear mode is used if both W values are equal and have
// low-order bits cleared (0-6 along X, 1-6 along Y) // low-order bits cleared (0-6 along X, 1-6 along Y)
@ -156,11 +155,10 @@ private:
else else
{ {
// linear interpolation // linear interpolation
// checkme: the rounding bias there (3<<24) is a guess
if (y0 < y1) if (y0 < y1)
return y0 + ((((s64)(y1-y0) * x * xrecip) + (3<<24)) >> 30); return y0 + (s64)(y1-y0) * x / xdiff;
else else
return y1 + ((((s64)(y0-y1) * (xdiff-x) * xrecip) + (3<<24)) >> 30); return y1 + (s64)(y0-y1) * (xdiff - x) / xdiff;
} }
} }
@ -220,7 +218,7 @@ private:
int shift; int shift;
bool linear; bool linear;
s32 xrecip, xrecip_z; s32 xrecip_z;
s32 w0n, w0d, w1d; s32 w0n, w0d, w1d;
u32 yfactor; u32 yfactor;
@ -326,20 +324,12 @@ private:
s32 x = XVal(); s32 x = XVal();
if (XMajor) int interpoffset = (Increment >= 0x40000) && (side ^ Negative);
{ Interp.Setup(y0-interpoffset, y1-interpoffset, w0, w1);
if (side) Interp.Setup(x0-1, x1-1, w0, w1); // checkme Interp.SetX(y);
else Interp.Setup(x0, x1, w0, w1);
Interp.SetX(x);
// used for calculating AA coverage // used for calculating AA coverage
xcov_incr = (ylen << 10) / xlen; if (XMajor) xcov_incr = (ylen << 10) / xlen;
}
else
{
Interp.Setup(y0, y1, w0, w1);
Interp.SetX(y);
}
return x; return x;
} }
@ -350,14 +340,7 @@ private:
y++; y++;
s32 x = XVal(); s32 x = XVal();
if (XMajor) Interp.SetX(y);
{
Interp.SetX(x);
}
else
{
Interp.SetX(y);
}
return x; return x;
} }