WebGL: Why does transparent canvas show clearColor color component when alpha is 0?

淺唱寂寞╮ 提交于 2019-12-10 15:21:41

问题


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>

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

...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

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?


回答1:


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.

You have a few options

  • Tell WebGL your colors are not premultiplied

    gl = canvas.getContext("experimental-webgl", { premultipliedalpha: false });
    
  • Get rid of the alpha channel

    gl = canvas.getContext("experimental-webgl", { alpha: false });
    
  • 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);
    

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.



来源:https://stackoverflow.com/questions/20362023/webgl-why-does-transparent-canvas-show-clearcolor-color-component-when-alpha-is

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!