为什么透明像素在 WebGL 中不能正确混合

Why are the transparent pixels not blending correctly in WebGL

我的代码结果:

基本上,问题是我图像的透明部分与之前绘制的部分没有正确混合。我知道我可以做

if(alpha<=0){discard;}

在片段着色器中,唯一的问题是我计划拥有大量片段并且不希望移动设备上的每个片段都有 if 语句。

这是我与 alpha 和深度测试相关的代码:

var gl = canvas.getContext("webgl2",
{
    antialias : false,
    alpha : false,
    premultipliedAlpha: false,
}
);

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.GREATER);   

此外,这些是有纹理的 gl.POINTS 我正在画画。如果我改变两个图像在缓冲区中绘制的顺序,问题就不存在了。它们将在程序运行期间动态旋转,因此这不是一个选项。

如果没有更多代码就不清楚你的问题是什么,但它看起来像是一个深度测试问题。

假设我理解正确,您正在绘制 2 个矩形?如果你在蓝色之前绘制红色,那么根据你的深度测试设置,当绘制 X 区域时,蓝色将无法通过深度测试。

您通常通过对绘制的内容进行排序来解决此问题,确保先绘制更远的东西。

对于 "tiles" 的网格,您通常可以通过在正确的方向上移动网格本身而不是 "sorting"

来排序

另一方面,如果您的所有透明度都是 100% 绘制或不绘制,则丢弃有其优势,您可以从前到后绘制。原因是因为在这种情况下从前到后绘制,在通过深度测试绘制蓝色四边形时,红色四边形绘制(未丢弃)的像素将被拒绝。深度测试通常被优化为在 运行 为某个像素设置片段着色器之前发生。如果深度测试表明像素不会被绘制,那么没有理由甚至 运行 该像素的片段着色器,节省时间。不幸的是,一旦您有任何不是 100% 不透明或 100% 透明的透明度,您就需要排序并拉回到前面。 this article

中涵盖了其中一些问题

一些注意事项:

  1. 您在代码示例中提到了移动设备和 WebGL2。 iOS

  2. 上没有 WebGL2
  3. 你说你是用点画的。规范说只需要 1 个像素大小的 POINTS。 It looks like you're safe up to points of size 60 but to be safe it's generally best to draw with triangles as there are other isses with points

  4. 您可能还对

  5. 感兴趣