I'm in the process of implementing portals in my engine, and at the moment I'm really trying to decide whether it's worth trying to use occlusion queries to accelerate them.
Using occlusion queries, I can have portals be closed by intermediate geometry, which a frustum check just won't do. There are plenty of cases where portals might be inside the frustum but occluded by intermediate geometry, even in the "optimal" case of all nodes being convex.
The problem with occlusion queries is the near clipping plane; if the portal is between the camera and the near clipping plane, suddenly it's not drawing any pixels, and thus closes. This causes a black flicker when passing through doorways.
Is a multi-step approach the way to go? something like: check if the portal is inside the frustum. If it is and it's very close to the camera, the portal is open. If the portal is inside the frustum but at some distance, an occlusion query is run to determine visibility.
Has anyone had any experience with portals in their engines? Any hints/advice on whether to bother with occlusion queries?
Portal visibility: worth accelerating on the GPU?
Actually that near clipping problem isn't that bad. As you already suggested, just checking the distance to the camera is sufficient.
The real problem is that occlusion queries can stall your command pipeline which will really ruin your performance.
NVidia has an article about exactly this problem.
The real problem is that occlusion queries can stall your command pipeline which will really ruin your performance.
NVidia has an article about exactly this problem.
I'm using occlusion queries and check the result in the next frame. Of course I create a query object for every mesh, as described in an other nVidia article. There's no stall and I'm happy with it at the moment.
I'm in the process of implementing portals in my engine...
The problem with occlusion queries is the near clipping plane; if the portal is between the camera and the near clipping plane, suddenly it's not drawing any pixels, and thus closes. This causes a black flicker when passing through doorways...
Never used occlusion queries but implemented portals\mirrors in my engine 10 years ago. I also had problems with clipping plane but solved this using simple trick: if any vertex of the portal goes over the clip plane, just project it back (using vector Vertex2Camera). This caused the portal be always visible and projection not changed. I tried to catch some bugs moving camera near the portal plane, but could not see any arthefacts. So this problem was closed.
In my engine I use stencil for recursive portals\mirros and 1 clip plane in the pixel shader if model requires this.
The real problem is that occlusion queries can stall your command pipeline which will really ruin your performance.
I'm aware of the possible pipeline stall issues that occlusion queries can cause, and my plan to avoid them is to run each node something like:
- Draw world geometry
- Issue portal queries
- Draw entity geometry
- check portal queries
The elephant in the room on this method is that, since queries are issued *before* entities are drawn, they can't be occluded by an elephant in the room. And it does mean an extra set of gl*Mask calls each frame. My intuition is that those issues will be less of a factor overall than pipeline stall would be, but obviously I'll need to profile it.
'Ohforf said:
The real problem is that occlusion queries can stall your command pipeline which will really ruin your performance.
I'm aware of the possible pipeline stall issues that occlusion queries can cause, and my plan to avoid them is to run each node something like:
- Draw world geometry
- Issue portal queries
- Draw entity geometry
- check portal queries
In the GPU gems 2 article linked above, it outlines exactly how to deal with the issues of stalls and how to avoid these problems listed. Basically, you use the information from the previous frames to continue drawing, not waiting on the results from the GPU, but as soon as the results from the GPU are retrieved, then they are stored so the CPU can make decisions about what to draw. This will work because if an object -- say, a box-- appears on the screen, and the CPU asks the GPU if the box is visible, but doesnt receive the results for 2-3 frames, then there wont be a problem. People will not be able to tell that the box came into the scene 3 frames after it really should have already been in the scene. After that, you can keep drawing the box.
As well as the stalling issues, occlusion queries are actually quite slow and have a lot of overhead (you can't can't perform 10,000 occlusion queries per frame without seeing a huge impact).
There's alternative GPU visibility checking algorithms, such as the HZB presented in the "Rendering with Conviction" presentation.
There's alternative GPU visibility checking algorithms, such as the HZB presented in the "Rendering with Conviction" presentation.
Has anyone had any experience with portals in their engines? Any hints/advice on whether to bother with occlusion queries?
I second the general option that occlusion queries will most likely hurt more than help performance. When you use the occlusion results in the next frame poping could be an issue.
I use a portal engine and I solve the problem by a simple projection of a portal on the "previous" portal starting with camera as first portal (all portals are connected in graph). The CPU overhead is negligible. Considering that the current trend is to use multi CPU system, portal visibility check is a candidate for a secondary thread.
If an area is visible by a portal check but occluded by other geometry, it i most likely that you only have to bear the vertex shader overhead (when rendering sections in the correct order), when using a deferred render , the vertex shader overhead is even more negligible.
I'm a fan of doing it on the CPU as well. Doing overly exact culling can lead to fps instability. For a couple of frames, you may be able to save some work as two trees happen to line up to block a doorway, but the doorway will be visible before and after.
I use box cells with quad portals between them, and quad anti-portals for large occluders ( probably only 2 or 3 per level at most).
I use box cells with quad portals between them, and quad anti-portals for large occluders ( probably only 2 or 3 per level at most).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement