As Metric has progressed, I started running into frame rate drops while debugging. Naturally the game is going to run slower when Visual Studio is debugging it and it’s not a problem when the game is running as a Release. But it showed that our Vertices Engine needed some of those long planned optimizations added in.
One among them was Camera Frustum culling, or essentially, only draw what the Camera sees. The GPU already performs Triangular Culling, cutting out any tri’s that aren’t on the screen, but there are large improvements if only 25% of data needs to be sent to the GPU in the first place each frame.
I looked at the implementation that was talked about over here and it was a good starting point, but decided there were some improvements I could make.
We need Boundaries
First thing to do is to find the bounds of each Model. When each vxEntity3D is first initialized, the model data is used to define the models BoundingSphere and model center.
[gist https://gist.github.com/9b6bc9b3484c73f318579f4307dcd588/]
Then each update call, the center is transformed by the World matrix, which then positions the bounding sphere to the orientation of the Entities Model.
// Reset the Bounding Sphere’s Center Position
BoundingShape.Center = Vector3.Transform(ModelCenter, World);
The result is this:
The Camera’s Point of View
Now that the Entities bounds are defined, next we need to define the Camera Frustum. This turns out not to be too complicated at all. I added a public BoundingFrustum field in the vxCamera3D class which is updated each loop with the view and projection matrices.
// Set the Bounding Frustum
BoundingFrustum.Matrix = View * Projection;
Can you See me?
Now with all the bounding shapes set up, the last thing to do is to put it all together. In each vxEntity3D‘s update loop, it checks to see if the Camera Frustum intersects it’s transformed Bounding Sphere. It then sets the boolean IsInCameraViewFrustum field to the value of whether it intersects the view frustum.
[gist https://gist.github.com/cb3da8add1463452d31bbb4c86f81549/]
Where the Camera.IsInViewFrustum function is simply just:
[gist https://gist.github.com/3094b39052267dd1b83ef0f8b70a1cac/]
Then in the draw calls, the Model is only drawn if the IsInCameraViewFrustum bool is true.
Results?
It was like I plugged in a new GPU. It started running quick and fast at 60 fps only stuttering when the entire scene was in view.
There’s a list of other optimizations I need to implement, mainly to do with the Renderering and ensuring only required info is sent to the GPU each call. But for now, this is a solid first step.
Reblogged this on Virtex Edge Design.
Reblogged this on Virtex Edge Design and commented:
If a tree falls in the woods, but there’s no Camera Frustums around to see it, does it still get rendered?
Check out through the link how we implement Camera Frustum Culling to optimise 3D scenes within the #VerticesEngine.