[solved] 2D Transparency Order

Started by
4 comments, last by PixelPants 12 years, 7 months ago
So... if I've got some textured quads that I want to render in my (completely) 2D application, and they've either got transparent texels or transparent verticles, do I need to sort the quads manually (via the z-axis) or will OpenGL do that for me via the order in which I render the quads?

Doing a search on the forums on this subject found me this:


I guess you question is 'can the hardware do this automagically for me?' and the answer is : no.

When it comes to semi-transparent stuff you have to draw it in back-to-front order with z-testing on but z-writes off.

This is going to put an extra bit of work into your render, as you'll have to sort your tiles into transparent or not groups, render the none transparent and then render the transparents tiles of each layer in the correct order to get the blending right.


but the OP was using the depth-buffer in his application, so I'm not sure if phantom's answer is my answer aswell...
Advertisement
The z-testing is used to discard parts of the transparent objects which are covered by an already rendered opaque one. It isn't used for sorting. He also indeed wrote about drawing the objects from back-to-front which is exactly the transparent sorting you were speaking about.
Alright, I've got depth testing disabled, and I think I've sorted all my quads by Z-order. The way I sorted it was calling this function inside each of my primitive draw functions (drawpoints, drawline, drawquad, etc etc).

[source]
private void SetModelView()
{
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();

double TheTranslate = 0.375; /* for pixel perfect accuracy */
MyOrderZ+=MyStepZ; /* increment Z for proper sorting */
GL.Translate(TheTranslate, TheTranslate, MyOrderZ);
}
[/source]

and here is my ortho and step stuff...
[source]
const double MyStepZ = 0.0000001;
const double MyFarZ = -1;
const double MyNearZ = 1;
[/source]

Yet... something is still wrong, it looks like it's still blending with the background instead of the quad beneath it.. evident by this picture:
picpt.png
That function do not sort anything. What do you mean about using that function to sort the primitives? Are you doing a draw call for each quad/triangle and setting the modelview matrix? That's not how primitives should be sorted. You should sort the draw calls so that the primitives which are in the back are rendered before the primitives in front of them. How have you defined your blending stages?

Ugh, I can't figure this out. Soo lost, lol...


apatriarca, by coincidence, the order in which I render everything is back to front, and (for the most part) opaque to non-opaque; I never make any attempts to render behind something that has already been rendered.

It was my understanding that with the depth buffer disabled, I wouldn't have to specify the Z axis. However, even with a monotonically increasing (or even decreasing) Z-axis value, the blending is still wrong.

In the pic I posted. if near=-1 & far=1, then I render this picture @ [50,50, 1]

repulsionshield.png

and then I render this picture @ [50,50,0.9]

repulsionshieldglow.png

and yet instead of bluring with the opaque quad beneath it, it blended with the background. And that makes no sense.

I've tried this with and without depth-testing, with and without reversing the near/far, and several other ideas that I had, none of which is working.


The blending function is:
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

and it does the blending great, except... the background color of the scene seems to be bleaching in!
I found it, it's the same issue these guys were having:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=143671
http://forum.openframeworks.cc/index.php/topic,1643.0.html

It turns out it has nothing to do with the Z-order sorting / depth testing, contrary to what I thought. The issue is how transparency is retained in an FBO.

[quote name='TomorrowPlusX']
What's happening, as far as I can tell, is this:
I render the tree trunk will full opacity, the alpha channel of the FBO's target texture is set to 1 wherever the trunk fragments go. This is correct behavior.

Then, I render the leaves ( a bunch of textured quads ). The leaves are rendered fully opaque, but the texture has an alpha channel. Wherever the alpha < 1, the alpha channel of the FBO seems to be multiplied by the textured fragment's alpha. E.g., if the fragment's alpha is 0.5, and the destination value is 1, I'm getting 0.5 as a result. If another, at 0.5 is rendered on top, the alpha goes to 0.25, and so on. [/quote]

In my situation, I was able to resolve it by disabling blending when rendering the FBO to the screen.

This topic is closed to new replies.

Advertisement