Implement LOD shell culling to fix floating cathedral

Added distance-based culling for WMO LOD shell groups:
- Skip groups with <100 vertices when camera is within 500 units
- This hides the simplified 'distant shell' when you're close to buildings

Analysis from STORMWIND.WMO logs revealed:
- LOD shell: Groups 268/269/271/274 (24-72 verts, flags 0x19xx)
- Main cathedral: Group 257 (32,698 verts at 20 units distance)

The LOD shell groups are meant for distant viewing only but were
rendering at all distances, causing the 'floating cathedral' effect.

Fix: Compute distance from camera to each group center and skip
rendering low-vertex groups when close. This preserves performance
(LOD shells still render from far away) while fixing the visual bug.
This commit is contained in:
Kelsi 2026-02-09 18:51:28 -08:00
parent 20bd54f9d4
commit ddd2e1aad7

View file

@ -1008,8 +1008,23 @@ void WMORenderer::render(const Camera& camera, const glm::mat4& view, const glm:
loggedStormwindGroups = true; // Only log once to avoid spam
}
for (uint32_t gi : dl.visibleGroups)
renderGroup(model.groups[gi], model, instance.modelMatrix, view, projection);
// Render groups with LOD shell culling
glm::vec3 cameraPos = camera.getPosition();
for (uint32_t gi : dl.visibleGroups) {
const auto& group = model.groups[gi];
// LOD shell culling: hide low-detail groups (<100 verts) when camera is close (<500 units)
// This prevents the floating "distant shell" from rendering when you're near the cathedral
glm::vec3 groupCenter = (group.boundingBoxMin + group.boundingBoxMax) * 0.5f;
glm::vec4 worldCenter = instance.modelMatrix * glm::vec4(groupCenter, 1.0f);
float distToGroup = glm::length(cameraPos - glm::vec3(worldCenter));
if (group.vertexCount < 100 && distToGroup < 500.0f) {
continue; // Skip LOD shell when close
}
renderGroup(group, model, instance.modelMatrix, view, projection);
}
lastPortalCulledGroups += dl.portalCulled;
lastDistanceCulledGroups += dl.distanceCulled;