mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: upgrade WMO group frustum culling from basic forward-check to proper frustum-AABB testing
Replace the basic forward-vector culling (which only culls when all AABB corners are behind the camera) with proper frustum-AABB intersection testing for more accurate and aggressive visibility culling. This reduces overdraw and improves rendering performance in WMO-heavy scenes (dungeons, buildings).
This commit is contained in:
parent
508b7e839b
commit
a10e3e86fb
1 changed files with 17 additions and 30 deletions
|
|
@ -1952,40 +1952,27 @@ VkDescriptorSet WMORenderer::allocateMaterialSet() {
|
|||
|
||||
bool WMORenderer::isGroupVisible(const GroupResources& group, const glm::mat4& modelMatrix,
|
||||
const Camera& camera) const {
|
||||
// Simple frustum culling using bounding box
|
||||
// Transform bounding box corners to world space
|
||||
glm::vec3 corners[8] = {
|
||||
glm::vec3(group.boundingBoxMin.x, group.boundingBoxMin.y, group.boundingBoxMin.z),
|
||||
glm::vec3(group.boundingBoxMax.x, group.boundingBoxMin.y, group.boundingBoxMin.z),
|
||||
glm::vec3(group.boundingBoxMin.x, group.boundingBoxMax.y, group.boundingBoxMin.z),
|
||||
glm::vec3(group.boundingBoxMax.x, group.boundingBoxMax.y, group.boundingBoxMin.z),
|
||||
glm::vec3(group.boundingBoxMin.x, group.boundingBoxMin.y, group.boundingBoxMax.z),
|
||||
glm::vec3(group.boundingBoxMax.x, group.boundingBoxMin.y, group.boundingBoxMax.z),
|
||||
glm::vec3(group.boundingBoxMin.x, group.boundingBoxMax.y, group.boundingBoxMax.z),
|
||||
glm::vec3(group.boundingBoxMax.x, group.boundingBoxMax.y, group.boundingBoxMax.z)
|
||||
};
|
||||
// Proper frustum-AABB intersection test for accurate visibility culling
|
||||
// Transform bounding box min/max to world space
|
||||
glm::vec3 localMin = group.boundingBoxMin;
|
||||
glm::vec3 localMax = group.boundingBoxMax;
|
||||
|
||||
// Transform corners to world space
|
||||
for (int i = 0; i < 8; i++) {
|
||||
glm::vec4 worldPos = modelMatrix * glm::vec4(corners[i], 1.0f);
|
||||
corners[i] = glm::vec3(worldPos);
|
||||
}
|
||||
// Transform min and max to world space
|
||||
glm::vec4 worldMinH = modelMatrix * glm::vec4(localMin, 1.0f);
|
||||
glm::vec4 worldMaxH = modelMatrix * glm::vec4(localMax, 1.0f);
|
||||
glm::vec3 worldMin = glm::vec3(worldMinH);
|
||||
glm::vec3 worldMax = glm::vec3(worldMaxH);
|
||||
|
||||
// Simple check: if all corners are behind camera, cull
|
||||
// (This is a very basic culling implementation - a full frustum test would be better)
|
||||
glm::vec3 forward = camera.getForward();
|
||||
glm::vec3 camPos = camera.getPosition();
|
||||
// Ensure min/max are correct after transformation (handles non-uniform scaling)
|
||||
glm::vec3 boundsMin = glm::min(worldMin, worldMax);
|
||||
glm::vec3 boundsMax = glm::max(worldMin, worldMax);
|
||||
|
||||
int behindCount = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
glm::vec3 toCorner = corners[i] - camPos;
|
||||
if (glm::dot(toCorner, forward) < 0.0f) {
|
||||
behindCount++;
|
||||
}
|
||||
}
|
||||
// Extract frustum planes from view-projection matrix
|
||||
Frustum frustum;
|
||||
frustum.extractFromMatrix(camera.getViewProjectionMatrix());
|
||||
|
||||
// If all corners are behind camera, cull
|
||||
return behindCount < 8;
|
||||
// Test if AABB intersects view frustum
|
||||
return frustum.intersectsAABB(boundsMin, boundsMax);
|
||||
}
|
||||
|
||||
int WMORenderer::findContainingGroup(const ModelData& model, const glm::vec3& localPos) const {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue