The one important thing I forgot to mention is that my script, this page, and an example .blend are avaliable at http://www.oocities.org/z3r0_d/files/sortFaces.zip
Translucent faces in blender are rendered in the order they appear in an object. (The order different objects are rendered currently cannot be controlled. ) Ideally they would be rendered furthest to nearest, so that if they were all opaque only the nearest faces would be visible, and if they were not they would appear to overlap correctly.
Example of incorrect ordering in game engine | Example of correct ordering | Explanation |
![]() |
![]() |
In both images the mesh is the same, but the
ordering of the faces is different. To emphasize this the faces at
the bottom are less green than the faces nearing the top.
In the left image the faces are ordered from the top to bottom. Notice how the faces at the bottom are rendered on top of (after) the faces of a lighter green. This is not happening in the image on the right because the faces are being drawn from the bottom to the top, and therefore the faces that are higher up seem on top of the faces lower down. More problemsif the faces in this example were made to exist only once, and all set to twoside (double sided) problems would be encountered from some points of view, and not others. The tree on the left would appear correct from the bottom, and the tree on the right incorrect from the bottom, so in the end neither would be completely correct. |
My solution is to find an order that will work from all points of view, by considering that faces are only visible from one side, and sorting the faces in a manner that would always have the translucent faces overlapping correctly.
The abstract of my algorithm is that it finds the faces that needs to be drawn before a particular face (they are behind, and that face is in front of), and puts the faces back into the mesh in an order that allows all required faces to be drawn before a particular face.
The aqua lines are the face normals, and each face is only visible from the side in which the normal points. I will be referencing the faces by the blue letters. They are extruded along the axis perpendicular to the screen.
Ponder this:
or to my script:
There is a problem with this which there is no (reasonable) solution for.
My script creates a list of faces that need to be drawn before each face which may make this problem easier to understand. The top row is the face, the second is the face that needs to be drawn before for this mesh to render correctly.
Face | A | B | C | D |
Draw before | C | D | B | A |
... or not. This table simply shows the face that needs to be drawn before another face because it MIGHT be visible through it. For example Face C can be visible through Face A. From some points of view it isn't, but from some it is.
So what is the problem here? It ends up happening that face A must be drawn before C which must be drawn before B which must be drawn before D which must be drawn before A, which is not possible. This stuff can get complex quick.
This one is pretty simple. Part of face B is visible through face A, and part of face A is visible through face B. Yet again this will not work, but this one is easier to spot, and easier to avoid.
The simplest solvable case is one only a little more complex than the tree shown above.
A table of faces that must be drawn before looks like so:
Face | A | B | C | D |
Draw Before | B | C | D | |
C | D | |||
D |
or in other words:
So the order the faces should be drawn is D, C, B, A.
I would like to continue rambling on my script again, as this is a good transition. Notice how face D requires no faces to be drawn before it. This is how my script puts the faces back into the object in the correct order (when possible). If face D were added back into the object, and each reference to it as being needed to be drawn before were removed the result would be this:
Face A B C Draw Before B C C
Notice how face C now has no faces required to be drawn before it, so I repeat for face C, which yields face B, for which I do the same, yielding face A, and my proper order. D, C, B, A.
This one can be more easily explained in an abstract manner. If the camera were inside the innermost triangle of faces (A, B, C) it would not be able to see faces X, Y, Z because they are oriented away from that area. If the camera were outside of X, Y, Z it would be able to see some of A, B, C, but it would always be behind [the visible faces of] triangle X, Y, Z. This creates the solution that faces A, B, C must be drawn, then X, Y, Z. The table for these faces would look like:
Face | A | B | C | X | Y | Z |
Draw Before | B | A | A | |||
C | C | B |
Running through the same algorithm mentioned above for adding faces would do what I desire.
the situations I have shown to not work, and to work on a plane also apply in three dimensions. For example the inside/outside situation applies in spheres, one with normals pointing inwards, the other outwards.
Also, the spaces I have put in are there merely to aide in making my point visible. The previous example would work just as well if the inside triangle appeared to share edges with the outer triangle.
It is all pretty simple. First your object must be prepared. This involves a few steps
If it works, good, if it doesn't try to think about why. There are many more reasons it could fail that I have mentioned here, but I believe these are the most likely.
The one important thing I forgot to mention is that my script, this page, and an example .blend are avaliable at http://www.oocities.org/z3r0_d/files/sortFaces.zip