本文介绍了WebGL:为什么透明画布在 alpha 为 0 时显示 clearColor 颜色分量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简单的峰值显示我的问题:

Here's a simple spike showing my problem:

<html>
<head>
    <title>Clear Color</title>
    <style type="text/css">
        #stage {
            background-color: rgba(127,127,127,1);
        }
    </style>
</head>
<body>
    <canvas id="stage" width="100", height="100"></canvas>
    <script type="text/javascript">
        var options = {
            alpha: true,
            premultipliedAlpha: true
        };
        var ctx = document.getElementById("stage").getContext("webgl", options);
        ctx.clearColor(1, 0, 0, 0);
        ctx.enable(ctx.BLEND);
        ctx.blendFuncSeparate(
            ctx.SRC_ALPHA, ctx.ONE_MINUS_SRC_ALPHA,
            ctx.ONE, ctx.ONE_MINUS_SRC_ALPHA
        );
        ctx.clear(ctx.COLOR_BUFFER_BIT);
    </script>
</body>
</html>

blendFunc 是这样的:
(sR*sA) + (dR*(1-sA)) = rR
(sG*sA) + (dG*(1-sA)) = rG
(sB*sA) + (dB*(1-sA)) = rB
(sA*1) + (dA*(1-sA)) = rA

The blendFunc is this:
(sR*sA) + (dR*(1-sA)) = rR
(sG*sA) + (dG*(1-sA)) = rG
(sB*sA) + (dB*(1-sA)) = rB
(sA*1) + (dA*(1-sA)) = rA

...翻译成这个(我认为):
(1*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*1) + (1.0*(1-0)) = 1.0

...which translates to this (I think):
(1*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*1) + (1.0*(1-0)) = 1.0

为什么我看到的是浅粉色画布,而不是 CSS 声明的灰色?粉色明显是我的clearColor出来的,但是为什么alpha分量为0的时候显示红色呢?

Why am I seeing a light pink canvas instead of just the grey that the CSS declares? The pink is obviously coming from my clearColor, but why is it showing the red when the alpha component is 0?

推荐答案

WebGL 默认要求您的颜色使用预乘 alpha.1,0,0,0 是无效颜色,因为 (1,0,0) * (0) 的 alpha = 0,0,0 而不是 1,0,0 的 rgb 所以它是无效颜色,并且规范未定义无效的颜色.结果在不同浏览器上会有所不同.

WebGL by default requires your colors to use premultiplied alpha. 1,0,0,0 is an invalid color because rgb of (1,0,0) * alpha of (0) = 0,0,0 not 1,0,0 so it's an invalid color and the spec is undefined for invalid colors. The results will be different on different browsers.

你有几个选择

  • 告诉 WebGL 你的颜色没有预乘

  • Tell WebGL your colors are not premultiplied

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

  • 摆脱 Alpha 通道

  • Get rid of the alpha channel

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

  • 预乘你的 alpha

  • Premultiply your alpha

    var r = 1;
    var g = 0;
    var b = 0;
    var a = 0;
    gl.clearColor(r * a, g * a, b * a, a);
    

    类似地,在您的着色器中,要么传入预乘颜色,要么在最后进行预乘.

    similarly in your shaders either pass in premultiplied colors or premultiply at the end.

    gl_FragColor = vec4(color.rgb * color.a, color.a);
    

  • 您的混合设置无效.它们仅在您调用 gl.drawXXX 时使用,当画布与背景合成时不会使用它们.

    Your blending settings have no effect. They only used when you call gl.drawXXX, they are not used when the canvas is composited with the background.

    这篇关于WebGL:为什么透明画布在 alpha 为 0 时显示 clearColor 颜色分量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-20 04:10