Depth tests and alpha blending problems
Hello again everyone! I have been working on a basic 3d engine and I have run into a few problems with the way I am blending/depth testing objects in my game. I am using TGA's for my textures that I want to be transparent, I have blending enabled, depth testing enabled, and I draw everything that does not have transparency first, then I sort the transparent objects in order of depth with the farthest drawn first. This works fine for angles from the front, but the objects are not transparent from the back angle. Is this natural or have I done something wrong? How should I fix this/work around it? Here are the blending functions I am using:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
Thanks in advance for any help!!
Brenton
I'm not sure I really understand what your problem is but usually, when you draw transparent objects, you disable depth writing (yet keep depth testing on) with a glDepthMask( GL_FALSE) call. Don't forget to set it back to GL_TRUE once you draw opaque objects.
are u resorting the triangles ever frame?
ie if u resort them from the front and then go to the back the order is gonna be wrong , they need to be resorted
ie if u resort them from the front and then go to the back the order is gonna be wrong , they need to be resorted
Hello and thanks for your reply! I will try to explain better exactly what my problem is. In my engine, whenever you look at an object from the front that is supposed to have transparent parts to it, everything appears fine. Whenever you walk around to the back side of the object and look at the back side of it, the parts that are supposed to be transparent are not, it blocks the view of other polygons that are located behind it. Whenever I call glDepthMask(GL_FALSE) before drawing transparent objects, it appears to disable all depth testing and the objects that are not so deep in the screen bleed over the ones that are deepest in the screen. Keep in mind that i only have these problems whenever I look at the from behind. I hope that I have clarified my problem a little better.
Thanks again!
Brenton
Thanks again!
Brenton
yea, zedzeek explained whats causing the problem, but not why it occurs..
you need to sort your transparent polygons by depth, ie. rendering backmost to frontmost, and you also need to render all of them AFTER drawing all the non-opaque polygons. this is because when you turn off the depth mask (z-buffer) zvalue's dont get (re)written, but do get re-tested, this somehow messes up the blending :) !!!
-Danu
you need to sort your transparent polygons by depth, ie. rendering backmost to frontmost, and you also need to render all of them AFTER drawing all the non-opaque polygons. this is because when you turn off the depth mask (z-buffer) zvalue's dont get (re)written, but do get re-tested, this somehow messes up the blending :) !!!
-Danu
The previous two posters are correct. The reason that the objects appear opaque from behind is that they are opaque, at least as far as the depth buffer is concerned. The way you have the depth buffer set up now when each object is drawn, the depth value for each pixel in the object is written into the depth buffer. If you draw another object behind an object you have already drawn, it's pixels fail the depth test (since there is already a closer pixel in the buffer) and the display buffer is not updated.
The reason this doesn't cause a problem when the objects are viewed from the front is that you have them sorted from back to front. You start by drawing the farthest object. When you draw an object in front of it, the closer object passes it's depth test and is drawn. This happens for every object since they are sorted, and they are all drawn.
Now when looking from behind the objects are sorted exactly wrong, so the nearest object is drawn first and each object behind it is rejected, making the objects appear opaque.
One solution to this problem would be to turn off depth writting when drawing transparent object. You still want a depth test since you may have other opaque objects in the scene which aren't sorted back to front and you want them to occlude the transparent ones. With the depth write off the closer objects will not occlude the farther ones and will not appear opaque.
However this is not quite enough to get good looking blended objects in the general case. This is because the order of blending is important in determining the final color of a pixel. For this you will have to resort the objects every frame where either they move or the camera moves.
This isn't quite as bad as it sounds because most of the time the objects are already sorted, or almost sorted. Choose a sort algorithim that does well in that case and you can get some savings. Also if your objects don't move very fast you might get away with sorting every few frames, or spreading the sort over several frames. Of course if you are sorting by depth you are not sorting by texture or shader which can involve other penalties.
Finally, if you do have correctly sorted objects you will get visually correct results even with depth writting on. However this writting will not affect the scene at all so you might as well save the time by turning it off anyway.
The reason this doesn't cause a problem when the objects are viewed from the front is that you have them sorted from back to front. You start by drawing the farthest object. When you draw an object in front of it, the closer object passes it's depth test and is drawn. This happens for every object since they are sorted, and they are all drawn.
Now when looking from behind the objects are sorted exactly wrong, so the nearest object is drawn first and each object behind it is rejected, making the objects appear opaque.
One solution to this problem would be to turn off depth writting when drawing transparent object. You still want a depth test since you may have other opaque objects in the scene which aren't sorted back to front and you want them to occlude the transparent ones. With the depth write off the closer objects will not occlude the farther ones and will not appear opaque.
However this is not quite enough to get good looking blended objects in the general case. This is because the order of blending is important in determining the final color of a pixel. For this you will have to resort the objects every frame where either they move or the camera moves.
This isn't quite as bad as it sounds because most of the time the objects are already sorted, or almost sorted. Choose a sort algorithim that does well in that case and you can get some savings. Also if your objects don't move very fast you might get away with sorting every few frames, or spreading the sort over several frames. Of course if you are sorting by depth you are not sorting by texture or shader which can involve other penalties.
Finally, if you do have correctly sorted objects you will get visually correct results even with depth writting on. However this writting will not affect the scene at all so you might as well save the time by turning it off anyway.
I could be wrong, but from the way you described your situation, it sounds like you are sorting your triangles by their z-values (depth along the z-axis) instead of their distances from the camera's position. Unless you are specifically rotating objects around the origin (instead of using a camera object), you need to sort them relative to how far they are away from the camera, not how far the are along the negative z axis they are. I hope that helps. Forgive me if I misunderstood your methods of sorting.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement