【问题标题】:Alpha rendering difference between OpenGL and WebGLOpenGL 和 WebGL 的 Alpha 渲染区别
【发布时间】:2018-02-15 23:52:29
【问题描述】:

我使用完全相同的 C++ 代码渲染相同的场景,一次渲染到 Windows 上的原生 OpenGL,一次使用 Emscripten 渲染到 WebGL。场景中的一切看起来都完全相同,除非我使用 alpha != 1.0 渲染某些东西。区别如下所示:

蓝色立方体颜色是(0.0, 0.0, 1.0, 0.5)
用于渲染立方体的着色器除了绘制颜色之外什么都不做。
右边是它在 OpenGL 中的样子,是预期的结果,只是蓝色,半透明。左边是 Emscripten+WebGL 的样子。看起来渲染的颜色实际上是(0.5, 0.5, 1.0, 0.5)

我使用的blend函数是标准的:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

WebGL 中的 alpha 有什么不同吗?什么可能导致这种情况发生?

【问题讨论】:

  • ...关闭为题外话?请解释
  • 它是否可能是预乘与非预乘的 alpha 问题?
  • @WacławJasper 我想过,但我真的不明白如何......预乘 alpha 会使其更暗,而不是更亮,不是吗?
  • @shoosh:这可能是 webgl 帧缓冲区中 alpha 通道的问题。在桌面 GL 中,帧缓冲区本身中的 alpha 值无效,除非您将它们读回或使用取决于目标 alpha 的混合函数,但在 webgl 中,它们实际上可能将画布与背景混合。尝试glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)(并将 alpha 清除为 1)

标签: c++ opengl webgl emscripten


【解决方案1】:

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

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,您可以将其关闭

    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);
    

    如果需要,不要忘记将颜色掩码设置回 all tr​​ue 稍后清除颜色缓冲区

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

    canvas { background-color: #000; }
    

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    相关资源
    最近更新 更多