Alpha rendering difference between OpenGL and WebGL

时间:2016-02-12 21:14:23

标签: c++ opengl webgl emscripten

I'm rendering the same scene using the same exact C++ code, once to native OpenGL on windows and once using Emscripten to WebGL. Everything in the scene looks exactly the same, except when I'm rendering something with alpha != 1.0. The difference looks like this: enter image description here

The blue cube color is ... Symbol *symbol = lookup_helper(key, current); if (symbol != nullptr) return symbol; ....
The shader used for rendering the cube does nothing except draw the color.
On the right is how it looks with OpenGL and is the expected result, just blue with half transparency. On the left is how it looks with Emscripten+WebGL. It looks like the color which is rendered is actually (0.0, 0.0, 1.0, 0.5)

The blend function I use is the standard:

(0.5, 0.5, 1.0, 0.5)

Is there some kind of difference with alpha in WebGL? What can possibly cause this to happen?

1 个答案:

答案 0 :(得分:11)

您是否将画布设置为非预乘?

gl = someCanvas.getContext("webgl", { premultipliedAlpha: false });

WebGL的默认值为true。大多数OpenGL应用程序的默认值为false

最重要的是,WebGL与页面的其余部分合成。至少是画布的背景颜色或其内部的任何颜色(文档的正文)。

要查看这是否是问题,请尝试将画布的背景颜色设置为紫色或将会突出显示

<canvas ... style="background-color: #F0F;"></canvas>

或在css

canvas { background-color: #F0F; }

OpenGL应用程序很少被合成,因为WebGL应用程序总是有效地合成。

一些解决方案

  • 关闭alpha

    如果目的地不需要alpha,可以将其关闭

    gl = someCanvas.getContext("webgl", { alpha: false });
    

    现在alpha实际上将是1

  • 在帧的末尾将alpha设置为1

    // clear only the alpha channel to 1
    gl.clearColor(1, 1, 1, 1);
    gl.colorMask(false, false, false, true);
    gl.clear(gl.COLOR_BUFFER_BIT);
    

    如果需要,请不要忘记将颜色遮罩设置为全部 稍后清除颜色缓冲区

  • 将画布的背景颜色设置为黑色

    canvas { background-color: #000; }
    

如果可能,我会选择关闭alpha。如果是alpha的原因设置为关闭它可能浏览器可以在将画布绘制到浏览器时关闭混合。根据GPU,速度可能会提高10-20%或更多。不能保证任何浏览器都能进行优化,只能说它可以做到,而其他2个解决方案则不可能或至少不太可能