这与我的上一篇 question 有关。要获取此图像:
http://img252.imageshack.us/img252/623/picture8z.png
我绘制白色背景(颜色 =
(1, 1, 1, 1)
)。我使用 color =
<(1, 0, 0, .8)
和混合函数(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)< 渲染左上角的两个方 block
,然后使用 color =(1, 1, 1, 1)
和混合函数(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
绘制纹理。我使用 color =
(1, 0, 0, .8)
和混合函数(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
绘制右下正方形。
根据我的计算,渲染到纹理的方 block 应该有颜色
.8 * (1, 0, 0, .8) + (1 - .8) * (0, 0, 0, 0) = (.8, 0, 0, .64)
所以在白色背景上绘制纹理后,它们应该有颜色
(.8, 0, 0, .64) + (1 - .8) * (1, 1, 1, 1) = (1, .2, .2, .84)
右下角的方 block 应该有颜色
.8 * (1, 0, 0, .8) + (1 - .8) * (1, 1, 1, 1) = (1, .2, .2, .84)
看起来应该是一样的!我的推理有错吗?我的计算有误吗?
无论如何,我的目标是缓存一些场景。如何渲染到纹理,然后绘制该纹理,以便它相当于仅内联绘制场景?
最佳答案
如果要将混合内容渲染到纹理并将该纹理合成到屏幕上,最简单的方法是在各处使用预乘 alpha。证明这适用于您的情况相对简单:预乘形式的半透明方 block 的颜色为 (0.8, 0, 0, 0.8),并将其与 (0, 0, 0, 0) 与 (GL_ONE
, GL_ONE_MINUS_SRC_ALPHA
) 本质上是将方 block 的颜色传递到纹理。将 (0.8, 0, 0, 0.8) 与 (GL_ONE
, GL_ONE_MINUS_SRC_ALPHA
) 混合在不透明白色上,得到 (1.0, 0.2, 0.2, 1.0)。请注意,颜色 channel 与您的第三次计算相同,但 Alpha channel 仍然为 1.0,这正是您对被混合对象覆盖的不透明对象所期望的值。
Tom Forsyth 有一个很好的 article关于预乘阿尔法。整篇文章值得一读,但请参阅“合成半透明层”部分,以了解为什么数学在一般情况下有效。
关于opengl - 渲染到纹理时的图像混合问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1317393/