混合如何与WebGL中的GLSL ES片段着色器配合使用



我正在尝试使用WebGL来获得一个简单的显示效果。当然,这意味着我使用的是GLSL ES 1.0规范中定义的片段着色器语言。

我正在使用的代码大部分是从其他来源复制的。它设置一个正方形,并使用片段和顶点着色器来确定像素颜色。以下代码将只显示一个白色方块。

gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);

但是,如果我将alpha组件更改为1.0,那么它将显示一个黑色正方形。

gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); // displays a black square

我假设片段着色器输出的颜色必须与以前的某个颜色组合。如何确保只有最后一种颜色(无论其alpha值如何)才是实际选择的要显示的颜色?

或者,也许我把订单弄错了。也许有一个后期阶段,它与碎片着色器中的颜色组合以生成白色。无论如何,我知道正在进行某种混合,因为当我将alpha值更改为0.5时,我会得到一个灰色正方形。我只是想知道,白色是从哪里来的?我该如何摆脱它?

据我所知,问题与混合函数无关。代码在GitHub上。在Google Chrome或Firefox中尝试一下。

白色不是来自任何WebGL混合操作。之所以会发生这种情况,是因为canvas DOM元素与它们所在的网页组合在一起。将canvas DOM元件的背景色设置为黑色可以解决此问题。这个现象已经在这里写过了。然而,最明确的答案来自WebGL规范。可以通过设置WebGLContextAttributes对象的各种属性来定义合成行为。引用规范:

可选的WebGLContextAttributes对象可以用于更改或者是否定义缓冲器。它可以也用于定义颜色缓冲区将包括一个alpha频道如果已定义,则alpha通道由HTML合成器用于将颜色缓冲区与其他缓冲区组合页面的。

因此,另一种不涉及将画布背景设置为黑色的解决方案是使用以下Javascript代码请求WebGL上下文

gl = canvas.getContext("experimental-webgl", { alpha: false } );

如果你发布了代码,这会很有帮助,但看起来很像是在将碎片颜色与白色背景混合。

一个可能的罪魁祸首是一些WebGL初始化代码,看起来像:

    gl.clearColor(1.0, 1.0, 1.0, 1.0);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.BLEND);

其将颜色缓冲区透明颜色初始化为白色并启用阿尔法混合。

因此,要解决您的问题,请不要启用混合。换句话说,丢失gl.enable(gl.BLEND);语句。

更新:既然你已经发布了你的代码,听起来你的问题与我的猜测相反。假设你希望黑色背景根据你设置的阿尔法显示出来,你应该用代替你的gl.disable(gl.BLEND)

    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.BLEND);

我对这个主题一无所知(glsl、webgl等),但你说的是alpha,这让我觉得这是RGBA值。因此,0.0, 0.0, 0.0, 0.0是黑色的,具有0.0的alpha覆盖率。换句话说,完全透明。

0.0, 0.0, 0.0, 1.0是黑色的,具有1.0阿尔法覆盖。换句话说,完全不透明。听起来输出是100%正确的。

让我澄清一下,以防以上内容不清楚(我觉得很困惑)。

最后一个数字只是影响颜色的透明度,前三个数字分别影响红色、绿色和蓝色。

我不确定它们的最大/最小值,但在网络浏览器(我的知识领域)中,颜色从0到255。其中0不是那种颜色,255是那种颜色。

因此,在您的情况下,您请求一个包含0个红色、0个绿色和0个蓝色(仅为黑色)的正方形。但是,当将透明度(alpha通道)设置为零时,它会渲染为白色(或者更可能是透明的,它后面的东西都是白色)。当您将alpha透明度设置为.5时,它会渲染为黑色(如0,0,0应该),但只有一半可见。将alpha透明度设置为1.0时,它将渲染一个完全不透明的黑色正方形。

有道理吗?

最新更新