mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +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,
|
bool WMORenderer::isGroupVisible(const GroupResources& group, const glm::mat4& modelMatrix,
|
||||||
const Camera& camera) const {
|
const Camera& camera) const {
|
||||||
// Simple frustum culling using bounding box
|
// Proper frustum-AABB intersection test for accurate visibility culling
|
||||||
// Transform bounding box corners to world space
|
// Transform bounding box min/max to world space
|
||||||
glm::vec3 corners[8] = {
|
glm::vec3 localMin = group.boundingBoxMin;
|
||||||
glm::vec3(group.boundingBoxMin.x, group.boundingBoxMin.y, group.boundingBoxMin.z),
|
glm::vec3 localMax = group.boundingBoxMax;
|
||||||
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)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Transform corners to world space
|
// Transform min and max to world space
|
||||||
for (int i = 0; i < 8; i++) {
|
glm::vec4 worldMinH = modelMatrix * glm::vec4(localMin, 1.0f);
|
||||||
glm::vec4 worldPos = modelMatrix * glm::vec4(corners[i], 1.0f);
|
glm::vec4 worldMaxH = modelMatrix * glm::vec4(localMax, 1.0f);
|
||||||
corners[i] = glm::vec3(worldPos);
|
glm::vec3 worldMin = glm::vec3(worldMinH);
|
||||||
}
|
glm::vec3 worldMax = glm::vec3(worldMaxH);
|
||||||
|
|
||||||
// Simple check: if all corners are behind camera, cull
|
// Ensure min/max are correct after transformation (handles non-uniform scaling)
|
||||||
// (This is a very basic culling implementation - a full frustum test would be better)
|
glm::vec3 boundsMin = glm::min(worldMin, worldMax);
|
||||||
glm::vec3 forward = camera.getForward();
|
glm::vec3 boundsMax = glm::max(worldMin, worldMax);
|
||||||
glm::vec3 camPos = camera.getPosition();
|
|
||||||
|
|
||||||
int behindCount = 0;
|
// Extract frustum planes from view-projection matrix
|
||||||
for (int i = 0; i < 8; i++) {
|
Frustum frustum;
|
||||||
glm::vec3 toCorner = corners[i] - camPos;
|
frustum.extractFromMatrix(camera.getViewProjectionMatrix());
|
||||||
if (glm::dot(toCorner, forward) < 0.0f) {
|
|
||||||
behindCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all corners are behind camera, cull
|
// Test if AABB intersects view frustum
|
||||||
return behindCount < 8;
|
return frustum.intersectsAABB(boundsMin, boundsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WMORenderer::findContainingGroup(const ModelData& model, const glm::vec3& localPos) const {
|
int WMORenderer::findContainingGroup(const ModelData& model, const glm::vec3& localPos) const {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue