I am working on a 3d project using openGL. I am looking for a way to optimize my renderings. Is there a way to tell if an object is behind another object and thus not visible to not waste time rendering it ? I am already working on a frustrum culling implementation to not display what is not visible because out of the viewing frustrum, but I didn't find a way to know if an object in located behind another object. Can any of you help me about this, please ?
1 Answer
If you aren't doing any depth testing, then you can use the OpenGL depth test functionality to prevent further away texels from getting filled in (relative to the view port), this way only the texels that are closest to the view frustum are rendered.
To do this you execute:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
And when you clear your screen at the start of every frame, also perform this line (after the lines posted above)
glClear(GL_DEPTH_BUFFER_BIT);
Further, if you render this scene to an custom Frame Buffer Object (FBO) (rather than your default FBO), and employ a deferred shading technique, you could substantially improve performance by only applying fragment shader calculations to the physical 2D image of your scene stored in the FBO.
That technique can be used like this:
- render the scene to an FBO
- Output fragment world positions to a texture, only closest fragments to the camera get used
- Output scene textures merged into a screen-space texture
- render a quad in front of the camera
- quad's fragment shader sample's from the screen-space texture given the positions in the position texture
That technique is quite useful for when there is lighting and other effects going on, as the lighting calculations are bounded to areas on influence and only occur on the small regions of pixels that actually make it to the screen.
-
1\$\begingroup\$ But doing this won't prevent the occluded objects from going through the process of rendering and the generation of their fragments. \$\endgroup\$ Commented Oct 6, 2015 at 3:52
-
1\$\begingroup\$ Assuming he has anything other than just sampling a texture during his rendering phase (actually uses lights or something), then a combination of this + deferred shading could also be useful. \$\endgroup\$ Commented Oct 6, 2015 at 4:05
-
\$\begingroup\$ Ok so this looks like a very interesting solution for when I get to shading. I am going to take a look at custom FBO implementation. This plus the Culling Occlusion that was advised as a comment solves my problem. Thank you a lot. \$\endgroup\$– NdnaCommented Oct 6, 2015 at 18:07
-
\$\begingroup\$ @Ndna In that case, I recommend following the tutorial series on Ogldev.atspace.co.uk in particular ogldev.atspace.co.uk/www/tutorial35/tutorial35 for deferred shading \$\endgroup\$ Commented Oct 6, 2015 at 18:10
-
\$\begingroup\$ @Ndna and one further note, if you're quite new to 3D rendering in general, I wouldn't quite worry about performance yet. As you progress through tutorials you will learn new things and different ways of rendering. For example, performance can be enhanced by uploading textures per object when said object is created, rather than doing so every frame. The same thing goes for the objects vertices, those too can be bound to the OpenGL context in vertex buffer objects (VBO's) and accessed every frame, rather than uploading the whole vertex array every frame. \$\endgroup\$ Commented Oct 6, 2015 at 19:01