11

I've been working on a game engine for educational purposes and I came across this issue I cannot seem to find an answer for:

Alpha channel only works for objects that have already been drawn before the object that has the alpha channel (For example: in a scene with 3 objects, let's say a cat, a dog and a bottle(transparent). both the cat and the dog are behind the bottle; the dog is drawn first, the bottle second, the cat third. only the dog will be seen through the bottle).

Here's a picture of this issue: The objects are drawn in the order they appear in the list box

I used C++ for the engine, Win32 API for the editor and GLSL for shading:

// some code here
vec4 alpha = texture2D(diffuse, texCoord0).aaaa;
vec4 negalpha = alpha * vec4(-1,-1,-1,1) + vec4(1,1,1,0);

vec4 textureComponentAlpha = alpha*textureComponent+negalpha*vec4(1,1,1,0);//(texture2D ( diffuse, texCoord0 ) ).aaaa;

gl_FragColor = (textureComponentAlpha + vec4(additiveComponent.xyz, 0)) * vec4(lightingComponent.xyz, 1);

In C++:

glEnable(GL_ALPHA_TEST);
glDepthFunc(GL_EQUAL);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

I assume it has something to do with the way the alpha test is made, or something like that.

Could anyone help me fix this, please?

laurGanta
  • 145
  • 1
  • 12
  • 1
    I'm not sure what you are asking for. Order independent transparency is neither cheap nor easy to implement, certainly beyond the scope of an answer on this site. – Quinchilion Jun 13 '16 at 02:09
  • I have faced the same problem, and my solution involved recursive multi-pass rendering, stencilling, clipping, and a lot of maths. Books could be written on such techniques, and indeed may have been. OpenGL doesn’t just magically do it all for you. If you’re looking for a simple solution, I’m afraid there isn’t one. – Entropy Jun 13 '16 at 04:15
  • I wrote an overview of some simple transparency rendering approaches in an answer here: http://stackoverflow.com/questions/23280692/opengl-es2-alpha-test-problems. – Reto Koradi Jun 13 '16 at 04:25
  • here link to new related question about [Dual depth peeling](https://stackoverflow.com/q/71928616/2521214) – Spektre Apr 20 '22 at 08:47

3 Answers3

16

I am using something similar to that answer linked by @RetoKoradi comment but I got double layered transparent models with textures (glass with both inner and outer surface) with fully solid machinery and stuff around.

For such scenes I am using also multi pass approach and the Z-sorting is done by sequence of setting front face.

  1. render all solid objects
  2. render all transparent objects

    This is the tricky part first I set

    glGetIntegerv(GL_DEPTH_FUNC,&depth_funct);
    glDepthFunc(GL_ALWAYS);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_CULL_FACE);
    

    I got the geometry layers stored separately (inner outer) so The Z-sorting is done like this:

    • Render outer layer back faces with glFrontFace(GL_CW);
    • Render inner layer back faces with glFrontFace(GL_CW);
    • Render inner layer front faces with glFrontFace(GL_CCW);
    • Render outer layer front faces with glFrontFace(GL_CCW);

    And lastly restore

    glDisable(GL_BLEND);
    glDepthFunc(depth_funct);
    
  3. render all solid objects again

It is far from perfect but enough for my purposes it looks like this:

example

Spektre
  • 45,598
  • 10
  • 100
  • 347
8

I cannot encourage you enough to have a look at this NVidia paper and the related blog post by Morgan McGuire.

This is pretty easy to implement and has great results overall.

cmourglia
  • 2,241
  • 1
  • 15
  • 33
1

Im not entirely sure this will help your situation, but do you have blending and alpha enabled? As in :

    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Nebulous39
  • 21
  • 3