Incomplete transparency problem.

Hi, I have a tree composed of two surfaces on each of which a 32-bit texture is mapped. The alpha channel is the transparent channel and works fine for one of the faces but not for the other, as you can see. The second face’s transparent pixels show the colour of the background but not the colour of the surface directly behind. Any clues?

Many thanks,

Keer :confused:

Simple. The problem is the zbuffer gets written even if the texture is fully transparent.

Transparency is order dependant. Z-buffer only hold the nearest depth value, so you need to draw from back to front. That is why one side is correct and the other not in your example.

By the way you need to split your 2 quads in 4 quads, with vertices at the ‘trunk’.

With alpha testing, edges are pixelated, but there is no problem with drawing order.

http://www.opengl.org/resources/faq/technical/transparency.htm

Paragraph: 15.070

Thank you for this. Dumb question: how do I sort my objects from back to front? Do I labourously measure each object’s distance and re-arrange them or is there some nifty opengl function that does that?

Keer

>> is there some nifty opengl function that does that?

:slight_smile: normally it is done with the zbuffer… So you have to do it yourself. Do a search in these forum, there have been discussion about this in the past few months.

The solution is to not generate fragments at the transparent places, no fragments means no depth values there. This is done with the GL_ALPHA_TEST and glAlphaFunc. You can keep depth testing on and don’t need to blend at all.
You should also be careful with the lighting. It looks weird that the left part of the tree in the picture is brighter than the right. glTexEnv with its default GL_MODULATE does this in your case.

Thanks Relic, I added the following and the results are better but not perfect. there is still a sky-coloured border around one of my tree planes, but not the other…

	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0f);

Any way to get rid of this border?

You could increase the alpha ref, you have it set at 0.0f but you’ll start to eliminate the soft blend and introduce aliasing around the tree edge as you increase this.

You could also look into using multisample antialiasing and using alpha to coverage mask to get order independent transparency but the quality is limited by the number of samples.

The only other approach involves sorting which in your case would also require splitting the tree polygons since their interpenetration makes a sort impossible without splitting at least one of them. Transparency doesn’t play well with the zbuffer, this is a well known problem.

P.S. It’s good to have a thread with pictures we can point people at now :slight_smile:

Well I split my polygons. The tree looks something like this:

[img]http://www.christov.com/ogl/tree_wf.png[/img] 

But I still don’t get how to do simple sorting. I thought opengl did back to front sorting by default? If this is the case a simple command should invert the order shouldn’t it?

>>Any way to get rid of this border? <<

All of the tree parts have these, it’s only the order of drawing which shows it.
The left front quarter is drawn first and blends with the background, the depth values of the border pixels block the back left tree quarter which is drawn later.

As I said, don’t use blending. The edges get sharper but you have no seams then.

OK it works without blending but my edges are non-antialiased…

Will back-to-front sorting allow me to use blending and have perfect anti-aliased edges?

I was thinking of doing it this way:

int array_of_tri_indeces[NUMBER_OF_TRIS];

void render_loop()
{
   // Check distance from back plane for each triangle
   // Sort triangles in back to front order
   // Store ordered triangle indeces in array_of_tri_indeces
   for ( a = 0; a < numTri; a++ )
   {
      render_tri(triangle[array_of_tri_indeces[a]]);
   }
}

Is this what we mean by sorting triangles, or am I completely off track?

hey keermalec, you could store an order map for a quick sort lookup. say you have 4 quads set in a cross, as viewed from above

          * eye position in quadrant 0
      1
  1   |   0 quadrant number
      |  
2-----*-----0 quad number      
      |
  2   |   3
      3

to find the quadrant you’re in, all you need to do is subtract the tree center from the eye position, then examine the signs of the result.

(+x,+y) then quadrant = 0
(-x,+y) then quadrant = 1
(-x,-y) then quadrant = 2
(+x,-y) then quadrant = 3

once you have the quadrant, you look up the order in an array:

int order[4][4] = 
{
//  quad number
    2,3,0,1, // eye is in quadrant 0
    3,0,1,2, // eye is in quadrant 1
    0,1,2,3, // eye is in quadrant 2
    1,2,3,0  // eye is in quadrant 3
};

i’ve never actually tried this, but it seems reasonable, at least after a pot and a half of coffee!

hope this helps!

>> Will back-to-front sorting allow me to use blending and have perfect anti-aliased edges?

Yes.

Thanks people, I finally understand the importance of back to front sorting.

Will do.

Keer :slight_smile:

Just split ONE tree poly along the intersection with the other poly. Then test the eye position against the plane equation of the unsplit poly, this will tell you which half of the split poly to draw in before the unsplit poly and which after.