OpenGL - How to create Order Independent transpare

2019-01-04 03:40发布

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?

3条回答
男人必须洒脱
2楼-- · 2019-01-04 04:15

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楼-- · 2019-01-04 04:35

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

查看更多
我只想做你的唯一
4楼-- · 2019-01-04 04:36

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);
查看更多
登录 后发表回答