gpt4 book ai didi

javascript - 使用预乘 Alpha 读出 FBO

转载 作者:行者123 更新时间:2023-11-29 16:52:36 25 4
gpt4 key购买 nike

我正在使用这个问题的答案中描述的方法向帧缓冲区对象绘制笔触:

opengl - blending with previous contents of framebuffer

此方法正确 alpha - 将不同的 OpenGL 绘图操作混合到一个 FBO 中并确保 alpha 保持正确。

它使用

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

将 OpenGL 绘图操作(在我的例子中是笔触)混合到 FBO 中并使用

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

将最终的 FBO(在我的例子中是类似 Photoshop 的层)绘制回屏幕,这会删除该方法中使用的预乘 alpha。将 FBO 传送到屏幕时,这对我来说效果很好。

但是,当我想读出 FBO 的内容时,我无法摆脱预乘的 alpha。 IE。当我使用

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

将层绘制到另一个FBO中,而不是使用glReadPixel()读出这个FBO的内容,内容仍然是预乘的。

换句话说,当我将 FBO 绘制到屏幕上时,混合并移除 prem。 alpha 工作,当做同样的事情并绘制到 FBO 时,它失败了。

这是我读出 FBO 时产生的(错误的)图像:

enter image description here

下面是直接在屏幕上绘制图层时的正确结果:

enter image description here

感谢您的帮助。

最佳答案

我不确定“摆脱预乘 alpha”是什么意思。如果您希望图片不预乘,则必须在 JavaScript 或着色器中手动取消预乘,例如

gl_FragCoord = vec4(color.a > 0. ? color.rgb / color.a : vec3(0), color.a);

当您在 Canvas 上绘制时它起作用的原因是因为默认情况下 Canvas 需要预乘 alpha。 Rendering with ONE,ONE_MINUS_SRC_ALPHA 使用预乘 alpha 绘制并保持结果预乘

例子:

Un-premultiplied    Red = 0.7  Alpha = 0.2

convert to premultiplied Red = Red * Alpha

Premultiplied Red = 0.14 Alpha = 0.2

blend with ONE,ONE_MINUS_SRC_ALPHA

DstRed = 0.0 DstAlpha = 0.0

newPixelRed = Red(0.14) * ONE + DstRed(0.0) * (1 - Alpha(0.2))
newPixelRed = 0.14 + 0.0 * 0.8
newPixelRed = 0.14

newPixelAlpha = Alpha(0.2) * ONE + DstAlpha(0.0) * (1 - Alpha(0.2))
newPixelAlpha = 0.2 + 0.0 * 0.8
newPixelAlpha = 0.2

因此 newPixelRednewPixelAlpha 区域与您绘制之前的区域完全相同。

newPixelRed 回到其未预乘状态的唯一方法是除以 alpha

newPixelRed = Red(0.14) / Alpha(0.2)
newPixelRed = 0.14 / 0.2
newPixelRed = 0.7 <- The original red before it was premultiplied

您只能在着色器或 JavaScript 中执行此操作。单独混合是不行的。

关于javascript - 使用预乘 Alpha 读出 FBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34937806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com