OpenGL 和 WebGL 之间的 Alpha 渲染差异
我正在使用完全相同的 C++ 代码渲染相同的场景,一次是在 Windows 上的原生 OpenGL,一次是使用 Emscripten 到 WebGL.场景中的所有内容看起来都完全相同,除非我使用 alpha != 1.0 渲染某些内容.区别如下:
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:
蓝色立方体颜色为(0.0, 0.0, 1.0, 0.5)
用于渲染立方体的着色器除了绘制颜色之外什么都不做.
右边是它在 OpenGL 下的样子,是预期的结果,只是蓝色半透明.左边是 Emscripten+WebGL 的样子.看起来渲染的颜色实际上是 (0.5, 0.5, 1.0, 0.5)
我使用的混合函数是标准的:
The blend function I use is the standard:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
与 WebGL 中的 alpha 有什么区别吗?什么可能导致这种情况发生?
Is there some kind of difference with alpha in WebGL? What can possibly cause this to happen?
推荐答案
您是否将画布设置为非预乘?
Did you set the canvas to be non-premultilied?
gl = someCanvas.getContext("webgl", { premultipliedAlpha: false });
WebGL 的默认值为 true.大多数 OpenGL 应用程序的默认设置为 false
The default for WebGL is true. The default for most OpenGL apps is false
在此之上,WebGL 与页面的其余部分组合在一起.至少那是画布的背景颜色或它里面的任何东西(文档的正文).
On top of that WebGL is composited with the rest of the page. At a minimum that's the background color of the canvas or whatever it's inside (the body of your document).
要查看这是否是问题,请尝试将画布的背景颜色设置为紫色或会突出的颜色
To see if this is the problem try setting your canvas's background color to purple or something that will stick out
<canvas ... style="background-color: #F0F;"></canvas>
或在 css 中
canvas { background-color: #F0F; }
OpenGL 应用很少在任何东西上进行合成,而 WebGL 应用总是有效地合成.
OpenGL apps are rarely composited over anything where as WebGL apps effectively are ALWAYS composited.
一些解决方案
关闭 alpha
Turn off alpha
如果您的目的地不需要 alpha,您可以将其关闭
If you don't need alpha in your destination you can turn it off
gl = someCanvas.getContext("webgl", { alpha: false });
现在 alpha 将有效地为 1
Now the alpha will effectively be 1
在帧结束时将 alpha 设置为 1
Set the alpha to 1 at the end of a frame
// 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);
如果需要,不要忘记将颜色掩码设置回全部为真稍后清除颜色缓冲区
don't forget to set the color mask back to all true if you need to clear the color buffer later
将画布的背景色设置为黑色
Set the canvas's background color to black
canvas { background-color: #000; }
如果可能,我会选择关闭 alpha.如果将 alpha 设置为关闭,则浏览器可能会在将画布绘制到浏览器中时关闭混合.根据 GPU 的不同,速度可能会提高 10-20% 或更多.不能保证任何浏览器都会进行这种优化,只是有可能做到,而使用其他 2 个解决方案则不可能或至少不太可能
If possible I'd pick turning off alpha. The reason if is alpha is set to off it's possible the browser can turn off blending when drawing the canvas into the browser. That could be a 10-20% or more increase in speed depending on the GPU. There's no guarantee that any browser makes that optimization, only that it's possible to does whereas with the other 2 solutions it's not possible or at least far less likely
相关文章