I have a third person camera that contains two matrices: view and projection, and two Vector3's: camPosition and camTarget. I've read up on frustum culling and it makes it seem easy enough for a first person camera, but how would I implement this for a third person camera? I need to take into effect the objects I can see behind me too. How would I implement this into my camera class so it runs at the same time as my update method?
public void CameraUpdate(Matrix objectToFollow)
{
camPosition = objectToFollow.Translation + (objectToFollow.Backward *backward) + (objectToFollow.Up * up);
camTarget = objectToFollow.Translation;
view = Matrix.CreateLookAt(camPosition, camTarget, Vector3.Up);
}
Can I just create another method within the class which creates a bounding sphere with a value from my camera and then uses the culling based on that? And if so, which value am I using to create the bounding sphere from?
After this is implemented, I'm planning on using occlusion culling for the faces of my objects adjacent to other objects. Will using just one or the other make a difference? Or will both of them be better? I'm trying to keep my framerate as high as possible
Answer
First of all, let's talk about culling as a performance optimisation. All the usual rules of performance optimisation apply: you should measure it! Are you below your performance target? And what's hurting your performance?
Basically: no point in including performance optimisations all willy-nilly.
That being said - maybe you've already measured it and you do have a performance problem. Object culling can help you stay within your batch limit. Occlusion culling individual faces is more likely to hurt performance than to help. For the class of performance problems that this optimisation feels like it should solve, early Z or occlusion queries are, perhaps, the correct optimisations to persue.
Now I've got all that out of the way, I have good news: frustum culling for a third-person camera is exactly the same as for a first-person camera. It's the same for basically any kind of camera.
You take your camera's matrix, which is view * project
, and create a BoundingFrustum
(MSDN), which you can then use to perform intersection tests for culling.
You're basically creating a cut-off pyramid extending from the camera - this shape:
http://i.msdn.microsoft.com/dynimg/IC47709.gif
And anything that intersects that shape is what will be visible within your camera volume. That shape is the same between both camera types.
The reason this works is because a camera matrix takes vertices in world space, moves them "in front" of the camera with view
matrix, and then projects them (with your project
matrix) into a region from (-1,-1,0) to (1,1,1) within which the GPU's rasterizer actually performs its rendering.
BoundingFrustum
simply reverses that process - taking the corners of the raster space and unprojecting them back out into world space.
No comments:
Post a Comment