OpenGL - 如何创建订单独立透明度?

时间:2016-06-13 00:10:33

标签: c++ opengl graphics glsl

我一直在研究用于教育目的的游戏引擎,我遇到了这个问题,我似乎无法找到答案:

Alpha通道仅适用于在具有Alpha通道的对象之前已经绘制的对象(例如:在具有3个对象的场景中,假设有猫,狗和瓶子(透明)。猫和狗都在瓶子后面;先拔狗,第二瓶,第三只猫。只有狗可以通过瓶子看到。

以下是此问题的图片: The objects are drawn in the order they appear in the list box

我使用C ++作为引擎,Win32 API用于编辑器,GLSL用于着色:

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

在C ++中:

glEnable(GL_ALPHA_TEST);
glDepthFunc(GL_EQUAL);

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

我认为它与alpha测试的方式有关,或类似的东西。

有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

我正在使用与@RetoKoradi评论链接相似的内容,但我得到了带有纹理的双层透明模型(内外表面都有玻璃),并带有完全坚固的机器和周围的东西。

对于这样的场景我也使用多次通过方法,Z-sorting按照设置正面的顺序完成。

  1. 渲染所有固体对象
  2. 呈现所有透明对象

    这是我设置的第一个棘手的部分

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

    我将几何图层分开存储(内部外部),因此Z-sorting完成如下:

    • 使用glFrontFace(GL_CW);
    • 渲染外层背面
    • 使用glFrontFace(GL_CW);
    • 渲染内层背面
    • 使用glFrontFace(GL_CCW);
    • 渲染内层前面
    • 使用glFrontFace(GL_CCW);
    • 渲染外层前面

    最后恢复

    glDisable(GL_BLEND);
    glDepthFunc(depth_funct);
    
  3. 再次渲染所有实体对象

  4. 这远非完美,但足以满足我的目的:

    example

答案 1 :(得分:3)

我不能鼓励你看看Morgan McGuire的this NVidia paperthe related blog post

这很容易实现,整体效果很好。

答案 2 :(得分:-1)

我不完全确定这会对您的情况有所帮助,但您是否启用了混合和Alpha?如:

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