首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用预乘α读出FBO

用预乘α读出FBO
EN

Stack Overflow用户
提问于 2016-01-22 02:04:11
回答 1查看 675关注 0票数 3

我正在使用这个问题的答案中描述的方法对一个框架缓冲区对象进行笔画:

opengl - blending with previous contents of framebuffer

该方法正确地将不同的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。也就是说,当我使用

glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);

若要将该层绘制为另一个FBO,并使用glReadPixel()读取此FBO的内容,则内容仍然是预乘的。

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

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

以下是将图层直接绘制到屏幕上的正确结果:

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-22 13:48:00

我不知道你所说的“摆脱乘积α”是什么意思。如果您想要图片被非预乘,那么您必须手动取消它在JavaScript或在阴影中使用类似的方法。

代码语言:javascript
复制
gl_FragCoord = vec4(color.a > 0. ? color.rgb / color.a : vec3(0), color.a);

当您在画布上绘图时,它工作的原因是因为默认情况下,画布期望预先乘以alpha。使用1绘制,ONE_MINUS_SRC_ALPHA使用预乘α绘制,并保持结果预乘以

示例:

代码语言:javascript
复制
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。

代码语言:javascript
复制
newPixelRed = Red(0.14) / Alpha(0.2)
newPixelRed = 0.14 / 0.2
newPixelRed = 0.7            <- The original red before it was premultiplied

您只能在着色器或JavaScript中这样做。单靠调合是不行的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34937806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档