Jump to content
  • Advertisement
Sign in to follow this  
Ameise

OpenGL Fastest Occlusion method with OpenGL

This topic is 2479 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am currently torn between two different means of handling occlusion in OpenGL, and wanted to get some input before I actually implement either form.

As I see it, there are two (reasonable) means by which to do it:

Delayed Occlusion - You send out an occlusion request, and then read the result of it several frames later. This reduces or eliminates the stall by not requiring a read from the graphics device to occur immediately, but rather after several frames. The drawback is it CAN still stall, and also forces occlusion to be several frames off, causing objects that just 'appear' at the edge of the screen.

Deferred Occlusion - You create a second GL Context within the same process, but in a different thread. You give it its own framebuffer, or possibly use the depth buffer of the primary thread with writing disabled. You do all occlusion testing within that thread, and feed the results back to the primary thread. The advantage SHOULD be no stalling at all, as they use separate framebuffers. I, however, do NOT know how well OpenGL or the graphics device would handle this.

Any thoughts?

Share this post


Link to post
Share on other sites
Advertisement
If I recall correctly, in Battlefield Bad company 2 they used a CPU based occlusion culling. There is a brief description about it here.

Cheers!

Share this post


Link to post
Share on other sites

If I recall correctly, in Battlefield Bad company 2 they used a CPU based occlusion culling. There is a brief description about it here.

Cheers!




That does imply software rendering / rasterization, though. I can see that being significantly slower, particularly with voxels (as I am doing), as they are currently instanced objects for me.

Share this post


Link to post
Share on other sites

Deferred Occlusion - You create a second GL Context within the same process, but in a different thread. You give it its own framebuffer, or possibly use the depth buffer of the primary thread with writing disabled. You do all occlusion testing within that thread, and feed the results back to the primary thread. The advantage SHOULD be no stalling at all, as they use separate framebuffers. I, however, do NOT know how well OpenGL or the graphics device would handle this.

Any thoughts?

is the context really thread bound? I thought OGL is not thread safe at all. I was reading a thread on opengl.org where someone wanted to stream in textures on a separate thread and failed. I'd be surprised if context were thread bound (or do you know of any extension that allows it?)



That does imply software rendering / rasterization, though. I can see that being significantly slower, particularly with voxels (as I am doing), as they are currently instanced objects for me.[/quote]I think it could run quite faster, especially with a dedicated box rasterizer for your voxel. (you can read some statistics in my "One Billion Polys" entry in the gamedev.net gallery)




but I have somehow the feeling like raycasting would be the most efficient and obvious way to cull voxel ( if not even to render them on GPU.), you don't need a perfect check every frame, you could just trace in a seperate thread random rays and keep visible chunks for like 60frames.

Share this post


Link to post
Share on other sites

is the context really thread bound? I thought OGL is not thread safe at all. I was reading a thread on opengl.org where someone wanted to stream in textures on a separate thread and failed. I'd be surprised if context were thread bound (or do you know of any extension that allows it?)


Yes an OpenGL context is bound to a 'current thread' and for any other thread to perform operations on that context it has to release it and the other aquire (in that order, you can not aquire a thread while another has it).

This is a standard thing, has been that way since I first started using GL back in 1999/2000 ;)

As for the OP's issue;

Firstly with occulsion queries you never use an object which is the same size as the object you are testing. Instead you use a bounding box which is bigger than the object. While this results in some false positivies you avoid popping.

Same applies to software solutions; you rasterise to a lower resolution buffer and you only render bounding boxes/quads for the objects themselves.

Share this post


Link to post
Share on other sites

[quote name='Krypt0n' timestamp='1317903203' post='4869750']
is the context really thread bound? I thought OGL is not thread safe at all. I was reading a thread on opengl.org where someone wanted to stream in textures on a separate thread and failed. I'd be surprised if context were thread bound (or do you know of any extension that allows it?)


Yes an OpenGL context is bound to a 'current thread' and for any other thread to perform operations on that context it has to release it and the other aquire (in that order, you can not aquire a thread while another has it).

This is a standard thing, has been that way since I first started using GL back in 1999/2000 ;)

As for the OP's issue;

Firstly with occulsion queries you never use an object which is the same size as the object you are testing. Instead you use a bounding box which is bigger than the object. While this results in some false positivies you avoid popping.

Same applies to software solutions; you rasterise to a lower resolution buffer and you only render bounding boxes/quads for the objects themselves.
[/quote]

Would you recommend the delayed solution, the deferred solution, or the software solution, though?

With the software, I'd almost want to render spheres (circles) for the objects, as that is the simplest to raster, otherwise you need to handle transformations in software.

Share this post


Link to post
Share on other sites
This might be worth a read: http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/

It's rather nice, especially if (like pretty much everyone) you either lay down Z first or use some kind of deferred or light-prepass thingie. It's conservative, so the worst thing to happen is to draw a few fragments too many twice. Even if you don't already have Z laid down in some way, you can render to a much smaller (e.g. 1/16 size) rendertarget in the same frame, which saves fillrate at the expese of some accuracy.

Share this post


Link to post
Share on other sites

This might be worth a read: http://rastergrid.co...lusion-culling/

It's rather nice, especially if (like pretty much everyone) you either lay down Z first or use some kind of deferred or light-prepass thingie. It's conservative, so the worst thing to happen is to draw a few fragments too many twice. Even if you don't already have Z laid down in some way, you can render to a much smaller (e.g. 1/16 size) rendertarget in the same frame, which saves fillrate at the expese of some accuracy.


Doesn't Hi-Z function on fragments, though? My application is somewhat vertex-bound.

Share this post


Link to post
Share on other sites
Ah ok, I didn't read about vertex-bound... sorry. No, in that case it won't help.

If you are vertex bound, drawing fewer vertices and fewer objects is obviously the only thing that helps, which leaves few options but occlusion queries (and possibly LOD). Software culling is likely much more complicated and slower (less accurate, transfers and state changes at inopportune times needed).

Occlusion culling is actually quite nice, especially on newer versions of OpenGL (with binary queries and conditional render). I never quite understood what you need binary queries for, they are (at first sight) totally useless. However, at second sight, they allow the driver to do some hefty optimizations and avoid stalls with conditional rendering. The moment the first fragment passes, it can signal the query object and it knows that a subsequent conditional render will go the "yes" route. Indeed, it does not even need to actually render all the fragments, it could in principle finish the current warp once a fragment goes through and discard all other warps.

True, occlusion queries can stall, and will sometimes. But most of the time it just works nicely (and you can still opt to draw anyway for queries that are not ready or try to put some other processing in between).

Share this post


Link to post
Share on other sites

Ah ok, I didn't read about vertex-bound... sorry. No, in that case it won't help.

If you are vertex bound, drawing fewer vertices and fewer objects is obviously the only thing that helps, which leaves few options but occlusion queries (and possibly LOD). Software culling is likely much more complicated and slower (less accurate, transfers and state changes at inopportune times needed).

Occlusion culling is actually quite nice, especially on newer versions of OpenGL (with binary queries and conditional render). I never quite understood what you need binary queries for, they are (at first sight) totally useless. However, at second sight, they allow the driver to do some hefty optimizations and avoid stalls with conditional rendering. The moment the first fragment passes, it can signal the query object and it knows that a subsequent conditional render will go the "yes" route. Indeed, it does not even need to actually render all the fragments, it could in principle finish the current warp once a fragment goes through and discard all other warps.

True, occlusion queries can stall, and will sometimes. But most of the time it just works nicely (and you can still opt to draw anyway for queries that are not ready or try to put some other processing in between).


Isn't that why the actual occluded draw is not done until later? Test now, draw, then check the results later? Otherwise, even with conditional render, it could incur a stall (unless you use NO_WAIT, which invalidates the use of an occlusion query anyways...).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!