Apply the correct culling epsilons both in fastcull and in software transform. Fixes NBA again.

This commit is contained in:
Henrik Rydgård
2026-06-05 00:18:06 +02:00
parent 392a862be2
commit 19d6850789
2 changed files with 10 additions and 3 deletions
+5 -1
View File
@@ -410,7 +410,11 @@ static bool TestBoundingBoxFast(const float *cullMatrix, const void *vdata, cons
Vec4F32 planeDistXY = posXY * planesXY + posW;
insideMaskXY |= planeDistXY.CompareGe(Vec4F32::Zero());
Vec4F32 posZ = clipPos.ShuffleZZZZ(); // This means that we compute the Z sides twice. Oh well.
Vec4F32 planeDistZ = posZ * planesXY + posW;
// We need to add the same culling epsilons as when setting up the cull distances in the vertex shader,
// so we don't over-cull here. We could also cull looser, but I can't figure out how to do so accurately.
// It's a bit unnecessary to take four reciprocals here, let's see if we can avoid that later.
Vec4F32 deltaZ = posW.RecipApprox() * 0.0000304f;
Vec4F32 planeDistZ = posZ * planesXY + posW + deltaZ;
anyOutsideMaskZ |= planeDistZ.CompareLt(Vec4F32::Zero());
insideMaskZ |= planeDistZ.CompareGe(Vec4F32::Zero());
const float projZ = vpZScale * clipPos[2] / clipPos[3];
+5 -2
View File
@@ -737,12 +737,15 @@ static SoftwareTransformAction ProjectClipAndExpand(SoftwareTransformParams &par
// First, check inside/outside directions for each index.
// We are still in clip space here, so we can cull aggressively in Z.
// TODO: This is so cheap now that we can probably avoid the buffer and just do the work below.
// See the comment in VertexShader for the epsilons
for (int i = 0; i < vertexCount; ++i) {
float z = transformed[indsIn[i]].z;
float w = transformed[indsIn[i]].pos_w;
if (z > w) {
const float delta = 0.0000304f / w;
if (z > w + delta) {
outsideZ[i] = 1;
} else if (z < -w) {
} else if (z < -(w + delta)) {
outsideZ[i] = -1;
} else {
outsideZ[i] = 0;