From 83dda7b5ae7741f4397bf71a29e7912ca85e64ab Mon Sep 17 00:00:00 2001 From: MarcelineVQ Date: Sat, 11 Apr 2026 13:41:34 -0700 Subject: [PATCH] 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. --- src/weirdperformance/silicon_sse.zig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/weirdperformance/silicon_sse.zig b/src/weirdperformance/silicon_sse.zig index b596acb..ebf33a7 100644 --- a/src/weirdperformance/silicon_sse.zig +++ b/src/weirdperformance/silicon_sse.zig @@ -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; }