Deferred shading is only a technique to "deffer" the actual shading operation for later stages, this can be great to reduce the number of passes needed (for example) to render 10 lights which needs 10 passes. My point is regardless of the rendering technique you are using there are certain possible rendering optimizations that reduce the number of objects (vertices, normals etc) that your enginerendering pipeline need to process.
Even when using deferred rendering those techniquetechniques apply and are widely used.
Only Objects that are fully or partially included in the view frustum, ever need to be submitted to the rendering pipeline. This is the basic concept of frustum culling, unfortunately checking if a mesh is in/out of the view frustum can be an expensive operation, so instead, engine designers use an approximate bounding volume like an AABB(AABB)Axis Aligned bounding box or a bounding sphere, even though this might not be as accurate as using the actual mesh, the accuracy difference isn't worth the trouble of checking with the actual mesh.
This is a good and a simple technique for a smaller engine, and is almost used in every engine I ever used. I recommend using a "normal" Bounding Volume/Frustum checking without hierarchies if youyour engine does not require rendering very complex scenes.
This is a must, why draw faces that won't be visible anyway? rendering APIAPIs provide an interface to turn on/off back face culling. Unless you have a strong reason why not to turn it on, like some of the CAD applications that need to draw backfaces in certain circumstances, this is a must do thing.
Using the Z-buffer you can solveresolve visibility determination. But the problem is that Z-buffer isn't always great in terms of performance, since Z-buffer can only be resolved at later stages of the pipeline, objects being occluded should be rasterized and might be written to the Z-buffer and the Color buffer before failing the Z test.
A great real world example of such technique is in GTA5, where the skyscrapers are stratigically placed at the center of the city, are not only decorations, theybut they also work as occluders, effectively occluding the rest part of the city and preventing it from being rasterized.
Level of detail is widely used technique, the idea is to use a simpler version of the mesh when the mesh is less contributing to the scene. there are tootwo common implementationsimplementations; one simply switches the mesh with a simpler one when it's no longer greatly contributing, the mesh is selected based on some factor like the distance and the number of pixels (area on the scree) the mesh is occupying. The other version dynamically tessellates the mesh and, this is widely used in terrain rendering.
The first thing you need to do is to Profile your application using a graphics profiler, and determine where the bottleneck is. Keep in mind that the bottle neckbottleneck may change based as the content being rendered change.
Bottlenecks might be also be part of the code running on CPU so you need to measure that too.
After that you need to do some optimizations inon the bottleneck, keep in mind that there is no right answer for this, and will be different from hardware to another.
Some common GPU optimzationoptimization tricks: