Blending

Helo, All.

I have a problem with drawing transqluent objects in 3d.
Redbook advises to:

  1. Draw non-transparent objects (I draw them using depth test)
  2. Make depth buffer read-only and draw transparent objects.

For example, I’m drawing a torus and a cylinder in the torus hole. Both of them are transparent. And now I have a problem - depth testing does not help me - the result of blending depends of object drawing order.

How to solve this problem?

sort the triangles back to front

Hello.

Do you think it’s a real solution???
Should I, using your method, draw part of torus, sphere and again part of torus?

Hello.

Do you think it’s a real solution???
Should I, using your method, draw part of torus, sphere and again part of torus?

What a wonderful approach.
Having meshes of 1ktri as standards right now, I can see where this per-frame, per-view dependant computation is carrying.

As far as I know however, unless you draw everything on a per-triangle base (in the sense of Begin(TRIANGLES) <3 vertices> End()) I don’t think there’s a real safety on relying on rendering order, in the sense that even if the vertex array (because you don’t want to use immediate mode right?) is ordered, you can’t be sure the fragments are generated in the correct, specified order. This is for how mimd works.

Another way because this does not work easily is that the triangles cannot be sorted in some cases. Say two triangles are forming an ‘X’ (when viewed from above). In that case, they cannot be rendered and they should be broken up and tassellated more finely, so an order can be decided.
Uh-oh, that’s quite a bit of work and since FP implementation is prone to errors, it will still have artifacts.

This to say don’t sort triangles.

What the conventional wisdom suggest is that a per-mesh check usually works. For example, get a Bounding box for each transparent mesh and use the farthest point to do comparisons.
This could work for your example.
Obviously enough, it’s still prone to errors.

The best thing if you want perfect transparencies is to have a per-fragment test. This uses a combination of stencil and Z to reject all the fragments “in front” of another fragment, so they can be rendered in the correct order.
It’s slow. It’s also not really easy to make work in a programmable environment because you have to know how much tests you need to get all the fragments.
I admit I never used it. I also spent very little time in understanding so I’ll just tell you to search nVidia’s developer site with the keyword “Order Independant Transparency”. My nV effect browser has a demo under “research” if I’m not wrong.

Originally posted by Obli:
Having meshes of 1ktri as standards right now, I can see where this per-frame, per-view dependant computation is carrying.
What standards? Are you talking about the current generation of first person shooter games? Or strategy games? Military simulations? Aeronautics?

Originally posted by Obli:
As far as I know however, unless you draw everything on a per-triangle base (in the sense of Begin(TRIANGLES) <3 vertices> End()) I don’t think there’s a real safety on relying on rendering order, in the sense that even if the vertex array (because you don’t want to use immediate mode right?) is ordered, you can’t be sure the fragments are generated in the correct, specified order. This is for how mimd works.
First, the API entry point for providing geometry data has little to do with what happens inside. Successive immediate mode calls store geometry in buffers which are in turn processed by the GPU, much like with vertex arrays, but with function calls overhead.

Second, even if fragments issued in a single cycle come from different triangles, they are likely coming from consecutive triangles. If your mesh representation has topology information, like when you use connected primitives, the fragments issued won’t be overlaping in the general case (except for the contour, but that’s a non-issue (look at the contour of a real glass)). The only case when fragments issued by mimd could overlap in the wrong order would be if you send unordered triangles, ie you hop through your list of triangles in a random fashion. But that’s very unlikely seeing that you are very concerned about performance.

Originally posted by Obli:
Another way because this does not work easily is that the triangles cannot be sorted in some cases. Say two triangles are forming an ‘X’ (when viewed from above). In that case, they cannot be rendered and they should be broken up and tassellated more finely, so an order can be decided.
Intersecting triangles are a real issue. They should be avoided within a mesh, and when two meshes intersect, you will have artifacts. Note that even if you tesselate and get the thing to render in the correct order, it will probably look wrong, because you will have a very distinct more opaque zone with sharp edges. We are not used to see that in real life.

Originally posted by Obli:
What the conventional wisdom suggest is that a per-mesh check usually works. For example, get a Bounding box for each transparent mesh and use the farthest point to do comparisons.
This could work for your example.
Obviously enough, it’s still prone to errors.

Sorting by mesh is the obvious first thing to do if transparent meshes don’t intersect and don’t contain each other. In this case, the cylinder is in the middle of the torus. It means that for any viewpoint (except top view of course) half the torus is in front of the cylinder, the other half is behind. Whatever mesh is rendered first, the result won’t be physically correct. It could look good enough (no ‘visible artifact’), since people have trouble defining what’s realistic when it comes to transparency and reflections, except when you explicitely ask them to be careful about it.

Originally posted by Obli:
The best thing if you want perfect transparencies is to have a per-fragment test. This uses a combination of stencil and Z to reject all the fragments “in front” of another fragment, so they can be rendered in the correct order.
It’s slow. It’s also not really easy to make work in a programmable environment because you have to know how much tests you need to get all the fragments.
I admit I never used it. I also spent very little time in understanding so I’ll just tell you to search nVidia’s developer site with the keyword “Order Independant Transparency”. My nV effect browser has a demo under “research” if I’m not wrong.

Depth peeling is an interesting approach, but it has its issues, like everything else.

Originally posted by <gl_newbie>:
[b]Hello.

Do you think it’s a real solution???
Should I, using your method, draw part of torus, sphere and again part of torus?[/b]
Yes, if you want ‘correct’ transparency it is the only option I know, although depth peeling might do the trick in this case.
AFAIK there is no general solution to handle transparency. It all depends upon your needs and you have to balance speed and quality.
If you are using VAs/VBOs you could use different index Arrays/Buffers to store presorted versions of your mesh from different viewpoints and choose the correct one to render at runtime. I never tried this myself but it sounds reasonable and there is not need to update your VA/VBO.

Originally posted by kehziah:
Are you talking about … Aeronautics?
Not really important, just to say that massive triangle meshes could be around, 1k tri seemed enough to have a problematic slowdown. Too much? Too few? Does it really matter?

Originally posted by kehziah:
First, the API entry point for providing geometry data has little to do with what happens inside. Successive immediate mode calls store geometry in buffers which are in turn processed by the GPU, much like with vertex arrays, but with function calls overhead.
True, but I have some good clues to think this order is preserved inside the buffer. I’ll check the spec.
By the way, I don’t flush between transparent surface rendering and everything looks to be fine. If every GPU command could be re-ordered then the things could get really messy.

About the other thing, it’s not clear to me the meaning of what are you saying. Consecutive triangles? In the vertex array or in the index specification order? In the sense they are near and sharing vertices? I don’t get it.
I guess ‘single cycle’ really means ‘single instance’ or ‘single batch’.

Quite happy to see we agree on the overlapping triangles problem.

Originally posted by kehziah:
half the torus is in front of the cylinder, the other half is behind.
Point taken. My fault. I really forgot that while writing down the thing.

Originally posted by kehziah:
Depth peeling is an interesting approach, but it has its issues, like everything else.
What issues? Besides slowing everything down, taking time to implement, requiring to have a “transparency count” needed to render everything correctly, depth peeling is the more fine-grained solution to the transparency problem I know and it seems quite robust to me.