2
\$\begingroup\$

I tried to render using different render configurations (GL_BLEND_FUNC()) but I couldn't get the back object to render in certain angles. The first screenshot here shows one angle where the back object is not visible through the front one. In th second screenshot, I looked at the blocks from 180 degrees.

problem from angle 1

no problems here from angle 2

Is there a way I could render them through? Or would I have to implement a sorting algorithm?

\$\endgroup\$
1
\$\begingroup\$

You need to render them back to front relative to the camera in order for transparency to correctly work, check painters algorithm, and depth buffering.

The rational behind this, is that because how depth tests work. The "usual" case for OpenGL is to test fragments for depth, once a fragment passes the depth test it will be written to the frame buffer overwriting any fragment that was written in the same frame buffer position, in other words when your scene have only opaque objects the depth buffer is enough to sort your rendered objects because it only keeps fragments that are near the camera.

When transparency comes into play, this is no more the case, and you need more info than the only nearest fragment. The depth test will still make near fragments overwrite far ones in the frame buffer, even though transparency says otherwise.

GL_BLEND_FUNC() (deprecated btw you should switch to shaders) can only blend fragments using a certain fixed equation, has nothing to do with the order pixels are written and have no control over the depth buffer. So it will apply the blending equation regardless of how the depth buffer sorted them. So the only practical option is to draw far then near objects.

Order-independent transparency on the other hand exist but they are particularly hard to implement.

As a side note opaque only objects (unlike transparent) should be draw front to back to avoid over-draw.

\$\endgroup\$
1
\$\begingroup\$

There are techniques for order-indepdendent transparency, but they all require a lot of work. The two techniques I am most familiar with are depth peeling and stencil routed A buffering and they both have a lot of overhead. There are also some new techniques made possible with compute shaders by building a linked-list of fragments, but I have not fooled around with them.

In an engine that only draws cubes like this, sorting your geometry is probably your best bet - you only need to depth sort the centroids for each cube and assuming you cannot rotate the cubes you do not have to worry about objects that intersect throwing off the sort validity. Remember to transform your centroids using the modelview matrix before sorting by Z, you generally want to sort in view-space such that Z represents depth.

\$\endgroup\$
1
\$\begingroup\$

I actually wrote an article on a simple algorithm I designed a little while ago to handle this.

http://evergreen-game.tumblr.com/post/72616811569/transparent-object-sorting]

Basically it's a quicksort (or mergesort) that uses a collision detection as its comparison function. If a convex object A's volume created by sweeping it away from the camera plane intersects another convex object B, A is in front of B (and thus the comparison function returns that A is greater than B). In terms of implementation, I'd use a GJK raycast test.

A's volume intersects B

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.