feat(rendering): aabb-based frustum checks

This commit is contained in:
maelstrom 2025-10-10 22:05:37 +02:00
parent 99d97b7507
commit 6c2650c0f7
2 changed files with 33 additions and 6 deletions

View file

@ -10,13 +10,13 @@ FrustumPlane::FrustumPlane(Vector3 point, Vector3 normal) : normal(normal.Unit()
Frustum::Frustum(const Camera cam, float aspect, float fovY, float zNear, float zFar) {
const float halfVSide = zFar * tanf(fovY * 0.5f);
const float halfHSide = halfVSide * aspect;
const glm::vec3 frontMultFar = zFar * cam.cameraFront;
const glm::vec3 frontMultFar = zFar * -cam.cameraFront;
// Don't forget to normalize!!!
glm::vec3 camRight = glm::normalize(glm::cross(cam.cameraFront, -cam.cameraUp)); // Technically this is left, but whatever
glm::vec3 trueCamUp = glm::cross(cam.cameraFront, camRight);
near = { cam.cameraPos + zNear * cam.cameraFront, cam.cameraFront };
far = { cam.cameraPos + frontMultFar, -cam.cameraFront };
glm::vec3 camRight = glm::normalize(glm::cross(cam.cameraFront, cam.cameraUp)); // Technically this is left, but whatever
glm::vec3 trueCamUp = glm::cross(-cam.cameraFront, camRight);
near = { cam.cameraPos + zNear * -cam.cameraFront, -cam.cameraFront };
far = { cam.cameraPos + frontMultFar, cam.cameraFront };
right = { cam.cameraPos,
glm::cross(frontMultFar - camRight * halfHSide, trueCamUp) };
left = { cam.cameraPos,
@ -28,7 +28,20 @@ Frustum::Frustum(const Camera cam, float aspect, float fovY, float zNear, float
}
bool FrustumPlane::checkPointForward(Vector3 point) {
return (normal.Dot(point) - distance) < 0;
return (normal.Dot(point) - distance) > 0;
}
bool FrustumPlane::checkAABBForward(Vector3 center, Vector3 extents) {
// Not entirely sure how this algorithm works... but hey, when has that ever stopped me?
// https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling
// https://gdbooks.gitbooks.io/3dcollisions/content/Chapter2/static_aabb_plane.html
// Compute the projection interval radius of b onto L(t) = b.c + t * p.n
extents = extents * 0.5f;
const float r = extents.X() * std::abs(normal.X()) +
extents.Y() * std::abs(normal.Y()) + extents.Z() * std::abs(normal.Z());
return -r <= (normal.Dot(center) - distance);
}
bool Frustum::checkPoint(Vector3 point) {
@ -41,4 +54,16 @@ bool Frustum::checkPoint(Vector3 point) {
&& top.checkPointForward(point)
&& bottom.checkPointForward(point)
;
}
bool Frustum::checkAABB(Vector3 center, Vector3 extents) {
return true
// TODO: Near and far are broken for some reason
// && near.checkAABBForward(center, extents)
// && far.checkAABBForward(center, extents)
&& left.checkAABBForward(center, extents)
&& right.checkAABBForward(center, extents)
&& top.checkAABBForward(center, extents)
&& bottom.checkAABBForward(center, extents)
;
}

View file

@ -14,6 +14,7 @@ struct FrustumPlane {
FrustumPlane() = default;
bool checkPointForward(Vector3);
bool checkAABBForward(Vector3 center, Vector3 extents);
};
struct Frustum {
@ -26,4 +27,5 @@ struct Frustum {
Frustum(const Camera cam, float aspect, float fovY, float zNear, float zFar);
bool checkPoint(Vector3);
bool checkAABB(Vector3 center, Vector3 extents);
};