silicon_sse: fix over-cull of straddling objects in frustumCullBBox

si_frustumCullBBox (0x686000, center+radius variant) was culling any
bounding volume whose center had view-space z < 0, but an object whose
center is behind the camera can still have its front extent inside the
frustum (think of standing next to a big WMO -- the building's center
can be a few units behind you while its front wall is still in frame).

Use the bounding sphere rather than the center point: only cull when
the closest point of the sphere is itself behind the camera, i.e.
center.z + |radius| < 0. Straddling cases now fall through to the
near-plane passthrough and get rendered.

si_frustumCullBBox8 (0x686180, 8-corner variant) already does the
right thing here -- it only returns "all behind" when every transformed
corner has z < 0, which is a true convex-hull test for an AABB.
This commit is contained in:
MarcelineVQ
2026-04-11 13:41:34 -07:00
parent 27b9254ab8
commit 83dda7b5ae
+5 -2
View File
@@ -577,9 +577,12 @@ pub fn si_frustumCullBBox(bbox: u32, flags: u32, radius_bits: u32) callconv(FC)
// z=0, so skip col2 term
const extent = @mulAdd(V4, rv, loadV4(m2 + 16), @mulAdd(V4, rv, loadV4(m2), loadV4(m2 + 48)));
// Behind-camera check (unless flags & 8)
// Behind-camera check (unless flags & 8). Use the bounding sphere, not
// just the center: an object whose center is behind the camera can still
// have its front extent in frame. Cull only if the entire sphere is
// behind the camera (closest point still has z < 0).
if ((flags & 0x8) == 0) {
if (center[2] < 0.0) return 2;
if (center[2] + @abs(radius) < 0.0) return 2;
if (center[2] < @as(*align(1) const f32, @ptrFromInt(0x80FED4)).*) return 0;
}