OpenGL - How to create Order Independent transparency?

被刻印的时光 ゝ 提交于 2019-11-26 02:39:15

问题


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:

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?


回答1:


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:




回答2:


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.




回答3:


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);


来源:https://stackoverflow.com/questions/37780345/opengl-how-to-create-order-independent-transparency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!