- Fix depth values written by sloped planes

This commit is contained in:
Magnus Norddahl 2018-04-08 02:22:01 +02:00
parent c15328de2f
commit 7f25913b2d
3 changed files with 41 additions and 12 deletions

View file

@ -289,6 +289,8 @@ namespace swrenderer
float idepth;
};
// #define DEPTH_DEBUG
class DepthSpanCommand : public DrawerCommand
{
public:
@ -297,6 +299,9 @@ namespace swrenderer
y = args.DestY();
x1 = args.DestX1();
x2 = args.DestX2();
#ifdef DEPTH_DEBUG
dest = (uint32_t*)args.Viewport()->GetDest(0, args.DestY());
#endif
}
FString DebugInfo() override { return "DepthSpanCommand"; }
@ -314,9 +319,16 @@ namespace swrenderer
if (idepth1 == idepth2)
{
float depth = idepth1;
#ifdef DEPTH_DEBUG
uint32_t gray = clamp<int32_t>((int32_t)(1.0f / depth / 4.0f), 0, 255);
uint32_t color = MAKEARGB(255, gray, gray, gray);
#endif
for (int x = x1; x <= end; x++)
{
values[x] = depth;
#ifdef DEPTH_DEBUG
dest[x] = color;
#endif
}
}
else
@ -325,6 +337,12 @@ namespace swrenderer
float step = (idepth2 - idepth1) / (x2 - x1 + 1);
for (int x = x1; x <= end; x++)
{
#ifdef DEPTH_DEBUG
uint32_t gray = clamp<int32_t>((int32_t)(1.0f / depth / 4.0f), 0, 255);
uint32_t color = MAKEARGB(255, gray, gray, gray);
dest[x] = color;
#endif
values[x] = depth;
depth += step;
}
@ -334,6 +352,9 @@ namespace swrenderer
private:
int y, x1, x2;
float idepth1, idepth2;
#ifdef DEPTH_DEBUG
uint32_t *dest;
#endif
};
void SWPixelFormatDrawers::DrawDepthSkyColumn(const SkyDrawerArgs &args, float idepth)

View file

@ -89,11 +89,10 @@ namespace swrenderer
auto viewport = Thread->Viewport.get();
DVector3 worldNormal = pl->height.Normal();
double worldD = pl->height.fD();
planeNormal.X = worldNormal.X * viewport->viewpoint.Sin - worldNormal.Y * viewport->viewpoint.Cos;
planeNormal.Y = worldNormal.X * viewport->viewpoint.Cos + worldNormal.Y * viewport->viewpoint.Sin;
planeNormal.Z = worldNormal.Z;
planeD = worldD + planeNormal.Z * viewport->viewpoint.Pos.Z;
planeD = -planeNormal.Z * (pl->height.ZatPoint(viewport->viewpoint.Pos.X, viewport->viewpoint.Pos.Y) - viewport->viewpoint.Pos.Z);
drawerargs.SetSolidColor(3);
@ -213,24 +212,23 @@ namespace swrenderer
void RenderSlopePlane::RenderLine(int y, int x1, int x2)
{
drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
if (r_models)
{
// Calculate normalized device coordinates for the span
// 1.5 is not a typo. The range is [x1,x2]
double devY = -(y + 0.5 - Thread->Viewport->CenterY) / Thread->Viewport->InvZtoScale / Thread->Viewport->viewwindow.FocalTangent;
double devX1 = (x1 + 0.5 - Thread->Viewport->CenterX) / Thread->Viewport->CenterX;
double devX2 = (x2 + 1.5 - Thread->Viewport->CenterX) / Thread->Viewport->CenterX;
double viewZ = 1.0;
double viewX1 = Thread->Viewport->ScreenToViewX(x1, viewZ);
double viewX2 = Thread->Viewport->ScreenToViewX(x2 + 1, viewZ);
double viewY = Thread->Viewport->ScreenToViewY(y, viewZ);
// Find depth values for the span
float zbufferdepth1 = (float)-planeD / (planeNormal | DVector3(devX1, 1.0, devY));
float zbufferdepth2 = (float)-planeD / (planeNormal | DVector3(devX2, 1.0, devY));
float zbufferdepth1 = (float)(-planeD / (planeNormal | DVector3(viewX1, viewZ, viewY)));
float zbufferdepth2 = (float)(-planeD / (planeNormal | DVector3(viewX2, viewZ, viewY)));
drawerargs.SetDestX1(x1);
drawerargs.SetDestX2(x2);
drawerargs.SetDestY(Thread->Viewport.get(), y);
drawerargs.DrawDepthSpan(Thread, 1.0f / zbufferdepth1, 1.0f / zbufferdepth2);
}
drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap);
}
}

View file

@ -68,7 +68,17 @@ namespace swrenderer
else
return FocalLengthY / (screenY + 0.5 - CenterY) * planeHeight;
}
double ScreenToViewX(int screenX, double viewZ) const
{
return (screenX + 0.5 - CenterX) / FocalLengthX * viewZ;
}
double ScreenToViewY(int screenY, double viewZ) const
{
return (CenterY - screenY - 0.5) / FocalLengthY * viewZ;
}
private:
void InitTextureMapping();
void SetupBuffer();