渲染到纹理时的图像混合问题

时间:2009-08-23 00:12:45

标签: opengl alphablending render-to-texture

这与我上一次question有关。要获得此图像:

http://img252.imageshack.us/img252/623/picture8z.png

  1. 我画了一个白色背景(color = (1, 1, 1, 1))。

  2. 我使用color = (1, 0, 0, .8)和混合函数(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)渲染纹理两个左上角的正方形,然后使用color = (1, 1, 1, 1)绘制纹理并混合功能(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

  3. 我使用color = (1, 0, 0, .8)绘制右下方,并混合函数(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

  4. 根据我的计算,渲染到纹理的方块应该有颜色

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

    并且右下方应该有颜色

    .8 * (1, 0, 0, .8) + (1 - .8) * (1, 1, 1, 1) = (1, .2, .2, .84)
    

    应该看起来一样!我的推理错了吗?我的计算错了吗?

    无论如何,我的目标是缓存一些场景。如何渲染到纹理,然后绘制该纹理,使其等同于仅内联绘制场景?

3 个答案:

答案 0 :(得分:4)

如果要将混合内容渲染到纹理并将该纹理合成到屏幕上,最简单的方法是在任何地方使用预乘alpha。显示这适用于您的情况相对简单:预乘形式的半透明正方形的颜色为(0.8,0,0,0.8),并将其(0,0,0,0)与({{ {1}},GL_ONE)基本上将正方形的颜色传递给纹理。使用(GL_ONE_MINUS_SRC_ALPHAGL_ONE)在不透明白色上混合(0.8,0,0,0.8)可得到(1.0,0.2,0.2,1.0)。请注意,颜色通道与第三次计算相同,但alpha通道仍然是1.0,这是混合对象覆盖的不透明对象所期望的。

Tom Forsyth对预乘alpha有一个很好的article。整个过程值得一读,但请参阅“合成半透明层”部分,以解释为什么数学在一般情况下有效。

答案 1 :(得分:0)

哎呀,我的计算错了!第二行应该是

(.8, 0, 0, .64) + (1 - .64) * (1, 1, 1, 1) = (1, .36, .36, .84)

确实与我看到的相匹配(当我将最后一个方格改为颜色(1, .2, .2, .8)时,所有三个方块都显示相同的颜色)。

答案 2 :(得分:0)

关于你的上一个问题:用纹理替换部分场景并非易事。一个很好的起点是Stefan Jeschke的PhD thesis