Skip to content

Commit

Permalink
Improve Interpolation Accuracy (#1686)
Browse files Browse the repository at this point in the history
* Fix Up Y Interp Inputs

* Change Linear Interp Formula

Fixes a handful of pixels.
Still not perfect.

* Cleanup

remove some unnecessary code and parentheses
  • Loading branch information
Jaklyy authored Aug 10, 2023
1 parent 7731f66 commit 5f9e7e1
Showing 1 changed file with 12 additions and 29 deletions.
41 changes: 12 additions & 29 deletions src/GPU3D_Soft.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ class SoftRenderer : public Renderer3D
this->x1 = x1;
this->xdiff = x1 - x0;

// calculate reciprocals for linear mode and Z interpolation
// calculate reciprocal for Z interpolation
// TODO eventually: use a faster reciprocal function?
if (this->xdiff != 0)
this->xrecip = (1<<30) / this->xdiff;
this->xrecip_z = (1<<22) / this->xdiff;
else
this->xrecip = 0;
this->xrecip_z = this->xrecip >> 8;
this->xrecip_z = 0;

// linear mode is used if both W values are equal and have
// low-order bits cleared (0-6 along X, 1-6 along Y)
Expand Down Expand Up @@ -156,11 +155,10 @@ class SoftRenderer : public Renderer3D
else
{
// linear interpolation
// checkme: the rounding bias there (3<<24) is a guess
if (y0 < y1)
return y0 + ((((s64)(y1-y0) * x * xrecip) + (3<<24)) >> 30);
return y0 + (s64)(y1-y0) * x / xdiff;
else
return y1 + ((((s64)(y0-y1) * (xdiff-x) * xrecip) + (3<<24)) >> 30);
return y1 + (s64)(y0-y1) * (xdiff - x) / xdiff;
}
}

Expand Down Expand Up @@ -220,7 +218,7 @@ class SoftRenderer : public Renderer3D
int shift;
bool linear;

s32 xrecip, xrecip_z;
s32 xrecip_z;
s32 w0n, w0d, w1d;

u32 yfactor;
Expand Down Expand Up @@ -326,20 +324,12 @@ class SoftRenderer : public Renderer3D

s32 x = XVal();

if (XMajor)
{
if (side) Interp.Setup(x0-1, x1-1, w0, w1); // checkme
else Interp.Setup(x0, x1, w0, w1);
Interp.SetX(x);
int interpoffset = (Increment >= 0x40000) && (side ^ Negative);
Interp.Setup(y0-interpoffset, y1-interpoffset, w0, w1);
Interp.SetX(y);

// used for calculating AA coverage
xcov_incr = (ylen << 10) / xlen;
}
else
{
Interp.Setup(y0, y1, w0, w1);
Interp.SetX(y);
}
// used for calculating AA coverage
if (XMajor) xcov_incr = (ylen << 10) / xlen;

return x;
}
Expand All @@ -350,14 +340,7 @@ class SoftRenderer : public Renderer3D
y++;

s32 x = XVal();
if (XMajor)
{
Interp.SetX(x);
}
else
{
Interp.SetX(y);
}
Interp.SetX(y);
return x;
}

Expand Down

0 comments on commit 5f9e7e1

Please sign in to comment.