Drawing order with blending

Post: #1
Hi folks,

here's my problem:

In my GL app there is a wall in front of the player, say -2 on the z-axis. And there is another wall which is also in front of the player, about -1 on the z-axis. The near wall is a glass wall which uses blending.
If I draw the back wall first and then the blending wall, it looks correct. But if I draw the blending wall first and then the back wall, the back wall is not used for the blending (it's invisible).

Now my question is:

Do I always have to draw everything behind a blended polygon first or is there some sort of GL method which does this automatically?

Thanks for your help,

Posts: 5,143
Joined: 2002.04
Post: #2
There is no "easy" solution. OpenGL doesn't do this for you. The standard algorithm is:

* draw all opaque surfaces (approximately in nearest-to-furthest order is good for modern 3D cards).
* draw all transparent surfaces in furthest-to-nearest order.
Posts: 45
Joined: 2006.11
Post: #3
A couple of other details:
->draw all opaque surfaces, preferably in front to back order
->turn off writing to the depth buffer but don't turn off depth testing
->draw all transparent surfaces, preferably in back to front order

The reason why the back wall won't get drawn if you draw the transparent front wall first is that even though the wall is transparent, drawing the wall causes a solid polygon to be drawn in the depth buffer. Then, when you try to draw the back polygon, the depth test fails and the wall isn't even processed. Whenever you draw transparent objects, you have to disable drawing to the depth buffer, so that the polygon is drawn to the screen, but not to the depth buffer. That way, if you have to draw something else and it happens to be behind the transparent polygon you just drew, it will still pass the depth test and get processed and blended (although it won't get blended quite right. it should look "good enough" if you don't want to figure out how to sort your polygons and draw them in the right order).
Unless you come across a couple of conditions, sorting polygons exactly and drawing them all in back to front order will let you draw everything correctly even without a depth buffer. Eliminating the depth buffer would eliminate a lot of pixel processing and the clearing of an entire buffer each frame. Both are potentially huge performance improvements, but sorting polygons is not fun, and unless youíre really careful to avoid certain situations, canít be done correctly in some cases. It doesn't work if you have polygons that intersect or that overlap like the flaps of a cardboard box when you try to close it without tape (each flap is under the flap to the left and over the flap to the right). Also, it's difficult and sometimes costly to sort your polygons in the right order, but there are a couple of situations that you want to do this.
First of all, it's a performance optimization to draw solid polygons in front to back order, because polygons in the front are likely to cover up polygons in the back. The 3D card doesn't have to process pixels that donít pass the depth test. If you draw a polygon in the back its pixels are processed onto the screen. If you then later draw another polygon in the front that covers the back polygon, you draw new pixels over the pixels you drew before, so you wasted time drawing the pixels of the polygon in the back.
Secondly, the reason you try to draw transparent polygons in back to front order is that blending is more accurate this way. When you're blending (depending on the type of blending you do) two transparent polygons together, they will look differently if they are drawn in a different order. The correct way is to draw the polygon in the back first, and then blend in the polygon in the front later. The reasoning is that the light will hit the polygon in the back first, and then go through the polygon in the front and then to the viewer's eye. For example, say you have a blue ball behind a green piece of glass. The light from a white lamp above both the ball and the piece of glass first bounces off of the ball and becomes blue. This blue light then goes through the green glass. To draw the ball, you start with white light and make it blue, the color of the ball. To draw the part of the glass that is directly in front of the ball, you start with blue, and blend it with green. If you draw the glass first and then blend in the green, it could still potentially look like a blue ball behind a piece of green glass, but it might look kinda funky. For OpenGL, most of the time it looks ìgood enoughî not to worry about it too much.
Sorting polygons takes some time - A considerable amount of time depending on the complexity of your scene. Sorting by polygon may eliminate or severely deplete the speed improvements you get from drawing solid polygons front to back. If, however, you use a space-partitioning scheme, you can detect if one partition is in front of another partition fairly quickly. So, rather than sort polygon by polygon, you simply draw sectors in the front before sectors in the back. It's sort of a compromise. Another option you could take is to only sort the sector the camera is in by polygon, and then draw all other visible sectors in whatever order they happen to be within your geometry structure. This way, things close to the camera are drawn accurately while things far away will be drawn with less accuracy.
Post: #4
Smile Thanks for all the info. It helps me a lot.
For improved performance I'm now sorting blended particles by their distance to the viewer, but I still had trouble with polys that where very near to each other. There was some kind of flickering, but with the disabling of the depth buffer writing this is no longer a problem.
But I will probably not sort opaque polys from near to far very soon. In the current state of the engine such a test would probably need even more time than without. Thanks again,

Thread Closed 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL graphical data storage order question. WhatMeWorry 3 5,536 May 4, 2007 12:13 PM
Last Post: tigakub
  general blending versus texture blending questions WhatMeWorry 2 7,654 Dec 7, 2006 02:43 PM
Last Post: arekkusu
  glMultMatrixf(): rotation order? Feanor 4 11,467 Jul 13, 2002 09:19 AM
Last Post: codemattic