Handling depth sorting key and hardware instancing

Started by
21 comments, last by Adaline 11 years ago

Hello

(About opaque geometry)

Depending on your scene, sorting opaque geometry in order to avoid pixel overwrites not always results in a gain in performances. Even worse, sorting and then drawing can be slower that directly drawing, without sorting. And if you use a deferred rendering technique, lights, shadows, ... calculations would not be concerned by this, only the g-buffer generation would.

(I tried exactly what you describe, and realized afterwards that not sorting opaque geometry and let the z-buffer doing its job was a better choice in my case !)

FWIW smile.png

Advertisement

Are you sure about this behavior? How can this be assured when multiple primitives are being rasterized in parallel

If this behaviour wasn't true, then whenever you rendered a convex shape with alpha-blending, you'd get random results depending on how the race conditions between overlapping surfaces panned out each frame. This doesn't happen though -- the triangles are blended in the order that they appear in your index buffer, without any race conditions or corruption in the overlapping areas.

It does not work that way. You have no guarantee on the order of execution (much less on the order of completion) inside a single draw-call.

It's really simple. Multiple execution units --> race conditions. You see those GPU blocks on every article each time a new GPU is released.

The only decent way to do order-independant-transparency is using D3D11 linked lists in my opinion.


The order that a primitive is rasterized and written to a render target is the same as the order in which you submit those primitives. This is part of the DX spec, and is guaranteed by the hardware. In fact the hardware has to jump through a lot of hoops to maintain this guarantee while still making use of multiple hardware units. This means that if you were able to perfectly sort all primitives in a mesh by depth, you would get perfect transparency. The same goes for multiple instances in a single draw call. The only case that's totally impossible to handle without OIT is the case of intersecting primitives.

Are you sure about this behavior? How can this be assured when multiple primitives are being rasterized in parallel? There is also some gray area regarding generated primitives too (via tessellation or the geometry shader) as they can be generated in parallel instances of the shaders...

I have always heard that the order is roughly equivalent to the order they are submitted in, but that they are explicitly not guaranteed to be processed in exact order.


Definitely. You're never guaranteed about the order in which vertices/primitives/pixels are processed in the shader units, but the ROPS will guarantee that the final results written to the render target match the triangle submission order (which is often done by buffering and re-ordering pending writes from pixel shaders). This is even true for geometry shaders, which is a big part of what makes them so slow.

That is really good to know, and I was completely unaware of it - thanks for letting me know :) That seems like it would be a big pain in the a$$ for the GPU manufacturer/driver to implement.

Are you sure about this behavior? How can this be assured when multiple primitives are being rasterized in parallel

If this behaviour wasn't true, then whenever you rendered a convex shape with alpha-blending, you'd get random results depending on how the race conditions between overlapping surfaces panned out each frame. This doesn't happen though -- the triangles are blended in the order that they appear in your index buffer, without any race conditions or corruption in the overlapping areas.

But the convex shape itself is not sorted - the depth sort order is based on the view direction, which is not the same every frame. Since the buffer contents remains the same and the viewpoint changes every frame, then this can't be a valid argument about the ROP processing order since sometimes you would be in the reverse order. Or am I thinking about that wrong?

But the convex shape itself is not sorted - the depth sort order is based on the view direction, which is not the same every frame. Since the buffer contents remains the same and the viewpoint changes every frame, then this can't be a valid argument about the ROP processing order since sometimes you would be in the reverse order. Or am I thinking about that wrong?

The view direction doesn't have to change each frame. Pick any one view direction and render the shape from that direction (and optionally vary any other irrelevant details that might influence race conditions, like processing load, other surrounding operations, phase of the moon, etc). You'll get the same result every time regardless of situational details that would influence race conditions. You always see the same triangles drawn over the top of other triangles, with no pixel/block artefacts from threading bugs within triangles. It will appear as if the GPU has rendered the triangles one at a time in the order specified.

In "foliage rendering in pure" they make use of this property in terrain grass rendering, by having a "tile" of 3D grass planes, with 8 index buffers, which each represent the planes as sorted correctly for 8 different viewing directions. When rendering, they pick the index buffer that has the most correct sorting order for the current view direction, which gives them almost correct back-to-front triangle sorting within each batch of grass.

For certain special cases of meshes you can actually pre-sort them to always render in the correct order regardless of viewing direction. For instance, say you have a transparent sphere that you wanted to be "double-sided" so that you can see both the front and the back of the sphere. A common way to do this is to duplicate all of the faces and flip the winding order so that they show up when back-facing. If you duplicate and append them to the end of the index buffer you get the wrong sorting order, since the front will render before the back. But if you append it to the beginning of the index buffer, the back faces will render first and the front faces will render second giving you the correct blending order.

But the convex shape itself is not sorted - the depth sort order is based on the view direction, which is not the same every frame. Since the buffer contents remains the same and the viewpoint changes every frame, then this can't be a valid argument about the ROP processing order since sometimes you would be in the reverse order. Or am I thinking about that wrong?

The view direction doesn't have to change each frame. Pick any one view direction and render the shape from that direction (and optionally vary any other irrelevant details that might influence race conditions, like processing load, other surrounding operations, phase of the moon, etc). You'll get the same result every time regardless of situational details that would influence race conditions. You always see the same triangles drawn over the top of other triangles, with no pixel/block artefacts from threading bugs within triangles. It will appear as if the GPU has rendered the triangles one at a time in the order specified.

In "foliage rendering in pure" they make use of this property in terrain grass rendering, by having a "tile" of 3D grass planes, with 8 index buffers, which each represent the planes as sorted correctly for 8 different viewing directions. When rendering, they pick the index buffer that has the most correct sorting order for the current view direction, which gives them almost correct back-to-front triangle sorting within each batch of grass.

I'm not disputing that transparent convex shapes render properly regardless of view direction. What I don't agree with is the statement that the order of the primitives has anything to do with it. Unless you do something like what MJP mentioned about duplicating the geometry, then I don't think the order of the primitives makes any difference - front faces will be rendered, and back faces will be culled. Even if the pixels were processed in a random fashion, it wouldn't matter to the output rendering.

For non-convex geometry, I think it is a different story - which is why I think the foliage method that you mentioned has different index buffers for different view directions. This is the main assertion that I am trying to make - that convex geometry will render properly either way, but non-convex geometry does need to have properly sorted primitives.

For certain special cases of meshes you can actually pre-sort them to always render in the correct order regardless of viewing direction. For instance, say you have a transparent sphere that you wanted to be "double-sided" so that you can see both the front and the back of the sphere. A common way to do this is to duplicate all of the faces and flip the winding order so that they show up when back-facing. If you duplicate and append them to the end of the index buffer you get the wrong sorting order, since the front will render before the back. But if you append it to the beginning of the index buffer, the back faces will render first and the front faces will render second giving you the correct blending order.

That is a great way to indicate how this works - and it solidifies the concept in my mind. Thanks for the example and the clarification!

Ahh, shoot. The whole time I meant 'concave', so it would have overlapping triangles....

Thank you guys, for pointing this out! This simplifies a lot of things.

Where is this documented? I'm reading some D3D11 documentation but I'm afraid I'm missing the place where it is noted.

Now that you write this, I think I recall a program which actually sorted all its particles.

Previously "Krohm"

Thank you guys, for pointing this out! This simplifies a lot of things.

Where is this documented? I'm reading some D3D11 documentation but I'm afraid I'm missing the place where it is noted.

Now that you write this, I think I recall a program which actually sorted all its particles.

Transparent, non connected geometry that is at different depths will still need to be sorted - only the convex geometry (i.e. one contiguous object) won't have an issue, but separated particles would be a different story since the transparent pixels would likely be blended in different orders depending on the view direction.

Sorry to have misled you... :(

It would work anyway I guess! It's index order only.

In "foliage rendering in pure" they make use of this property in terrain grass rendering, by having a "tile" of 3D grass planes, with 8 index buffers, which each represent the planes as sorted correctly for 8 different viewing directions. When rendering, they pick the index buffer that has the most correct sorting order for the current view direction, which gives them almost correct back-to-front triangle sorting within each batch of grass.

Previously "Krohm"

This topic is closed to new replies.

Advertisement