代码之家  ›  专栏  ›  技术社区  ›  Jesse Beder

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

  •  2
  • Jesse Beder  · 技术社区  · 15 年前

    这和我的上一次有关 question . 要获取此图像:

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

    1. 我画了一个白色的背景(颜色= (1, 1, 1, 1) )

    2. 我渲染为用颜色对左上角的两个方块进行纹理处理= (1, 0, 0, .8) 和混合功能 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ,然后用颜色绘制纹理= (1, 1, 1,1) 和混合功能 (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) .

    3. 我用彩色画右下角的正方形= (1,0,0,.8) 和混合功能 (gl_-src_-alpha,gl_-one_-minus_-src_-alpha) .

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

    .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 回复  |  直到 15 年前
        1
  •  4
  •   Pivot    15 年前

    如果要将混合内容渲染为纹理,并将该纹理合成到屏幕,最简单的方法是在任意位置使用预乘alpha。它相对简单地证明了这对您的情况是有效的:预乘形式的半透明正方形的颜色是(0.8,0,0,0.8),并将其与(0,0,0)混合( GL_ONE , GL_ONE_MINUS_SRC_ALPHA )基本上通过你的方块颜色通过纹理。在不透明白色上混合(0.8、0、0.8)( 格列酮 , gl_one_减_src_alpha )给你(1.0,0.2,0.2,1.0)。请注意,颜色通道与第三个计算相同,但alpha通道仍然是1.0,这是混合对象覆盖的不透明对象所期望的。

    汤姆·福塞思有一个很好的 article 关于预乘alpha。整件事值得一读,但请参阅合成半透明层一节,了解为什么数学在一般情况下是可行的。

        2
  •  0
  •   Jesse Beder    15 年前

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

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

    这似乎与我看到的相符(当我把最后一个方块换成颜色时 (1, .2, .2, .8) ,所有三个方块都显示相同的颜色)。

        3
  •  0
  •   Malte Clasen    15 年前

    关于最后一个问题:用纹理替换场景的一部分并不容易。一个很好的起点是Stefan Jeschke的 PhD thesis .