How to cull Sprite3D if it is out of bounds of camera view #158
Unanswered
lovelle-cardoso
asked this question in
Q&A
Replies: 2 comments 1 reply
-
Let me get back to you, I'll see if I can find a solution. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Think I got something. I used the implementation from https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling but converted to TypeScript obviously. The function below checks if a sphere is inside the camera frustum. Only works with a perspective camera. function planeFromPositionAndNormal(position: Point3D, normal: Point3D) {
return new Plane(normal, Point3D.dot(position, normal.normalize()))
}
function isSphereInCameraFrustum(center: Point3D, radius: number) {
let camera = Camera.main
const aspect = app.renderer.width / app.renderer.height
const halfVSide = camera.far * Math.tan(camera.fieldOfView * 0.5 * DEG_TO_RAD)
const halfHSide = halfVSide * aspect
let near = planeFromPositionAndNormal(
Point3D.add(
camera.worldTransform.position,
Point3D.scale(camera.worldTransform.forward, camera.near)
),
camera.worldTransform.forward
)
if (Point3D.dot(center, near.normal) - near.distance < 0) {
return false
}
let far = planeFromPositionAndNormal(
Point3D.add(
camera.worldTransform.position,
Point3D.scale(camera.worldTransform.forward, camera.far)
),
camera.worldTransform.backward
)
if (Point3D.dot(center, far.normal) - far.distance < 0) {
return false
}
let right = planeFromPositionAndNormal(
camera.worldTransform.position,
Point3D.cross(
Point3D.subtract(
Point3D.scale(camera.worldTransform.forward, camera.far),
Point3D.scale(camera.worldTransform.right, halfHSide)
),
camera.worldTransform.up
)
)
if (Point3D.dot(center, right.normal) - right.distance < -radius) {
return false
}
let left = planeFromPositionAndNormal(
camera.worldTransform.position,
Point3D.cross(
camera.worldTransform.up,
Point3D.add(
Point3D.scale(camera.worldTransform.forward, camera.far),
Point3D.scale(camera.worldTransform.right, halfHSide)
)
)
)
if (Point3D.dot(center, left.normal) - left.distance < -radius) {
return false
}
let bottom = planeFromPositionAndNormal(
camera.worldTransform.position,
Point3D.cross(
camera.worldTransform.right,
Point3D.subtract(
Point3D.scale(camera.worldTransform.forward, camera.far),
Point3D.scale(camera.worldTransform.up, halfVSide)
)
)
)
if (Point3D.dot(center, bottom.normal) - bottom.distance < -radius) {
return false
}
let top = planeFromPositionAndNormal(
camera.worldTransform.position,
Point3D.cross(
Point3D.add(
Point3D.scale(camera.worldTransform.forward, camera.far),
Point3D.scale(camera.worldTransform.up, halfVSide)
),
camera.worldTransform.right
)
)
if ((Point3D.dot(center, top.normal) - top.distance) < -radius) {
return false
}
return true
} You can use the function like this: let radius = 1
myCulledSprite.renderable = isSphereInCameraFrustum(myCulledSprite.position, radius) |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Is there a simple way to check if a Sprite3D is outside the bounds of a camera's near and far plane? I'd like to cull these sprites so they aren't rendered.
I believe it's something like this:
But this doesn't account for the direction the camera is facing.
Beta Was this translation helpful? Give feedback.
All reactions