WebGL中的透明纹理行为

时间:2012-01-06 19:50:50

标签: transparency textures webgl

环境:WebGL,Chrome。使用透明png作为模型的纹理时,我有以下行为:

  1. 图像A - 树隐藏在它后面的建筑物,我看到世界框纹理。它也隐藏自己(后面的分支不可见)
  2. 同时 - 图像B - 工作正常,窗口透明,我看到背后的内容
  3. 答:Tree over house B:Window transparency

    两张截图都是在同一场景中同时从不同的相机位置拍摄的。纹理由相同的算法生成。

    我无法理解窗口和分支透明度之间的区别。我的主要问题是 - 如何修复分支以便不隐藏它们后面的对象?着色器代码是:

    gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
    

    我使用启用/禁用混合和depth_test,有时会获得所需的结果,但不确定这是否是正确的做事方式。

3 个答案:

答案 0 :(得分:30)

您遇到深度缓冲问题,它与着色器或混合模式无关。

正在发生的事情是,渲染透明几何体的顺序会影响您在其后面渲染的能力。这是因为深度缓冲区没有透明或不透明的概念。因此,即使它们在视觉上没有对场景做出贡献,这些透明像素仍会将自己写入深度缓冲区,之后,您在其后面绘制的任何像素都将被丢弃,因为它们“不可见”。但是,如果您首先在透明对象后面绘制几何图形,它将正确显示,因为它会在透明深度放置到位之前写入框架中​​以丢弃它。

这甚至是大型商业游戏引擎在某种程度上仍然存在的问题,所以不要因为它而感到不舒服而导致一些混乱。 :)

这个问题没有“完美的解决方案”,但它真正归结为尝试如此构建你的场景:

  1. 渲染按州排序的任何不透明几何体(着色器/纹理/等)
  2. 接下来渲染任何透明几何体。如果可能的话,按深度排序,以便首先从相机中绘制最远的一个。
  3. 只需标记透明的几何体位并在其他所有内容之后渲染它们,您将解决此问题的90%,但问题可能仍然存在于重叠的透明对象。这对你来说可能不是问题,取决于你的场景,但是如果它仍然造成了文物,你需要在绘制之前按深度对透明对象进行排序。

答案 1 :(得分:4)

丢弃低于α的片段,例如0.5可能有帮助(当然,有副作用)。

if(gl_FragColor.a< 0.5)    丢弃;

AlphaFunctions in WebGL?

答案 2 :(得分:0)

我是webgl的新手,并且总体上使用图形。但是也许theoricall在每个实例处调用drawElements两次或两次以上也可以解决问题? 还有一篇关于字体几乎相同问题的文章,作者解决了它,只需设置参数 {alpha:false} 对我来说,这没有任何意义,但是它有效。