这与我的上一个问题有关。要获取此图像:
http://img252.imageshack.us/img252/623/picture8z .png
-
我绘制了一个白色背景 (color = (1, 1, 1, 1)
)。
-
我使用 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)
绘制纹理。
-
我使用 color = (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)
看起来相同的颜色!我的推理有错吗?我的计算有错误吗?
无论如何,我的目标是缓存一些场景。如何渲染到纹理,然后绘制该纹理,以便它相当于仅内联绘制场景?
This is related to my last question. To get this image:
http://img252.imageshack.us/img252/623/picture8z.png
-
I draw a white background (color = (1, 1, 1, 1)
).
-
I render-to-texture the two upper-left squares with color = (1, 0, 0, .8)
and blend function (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
, and then draw the texture with color = (1, 1, 1, 1)
and blend function (GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
.
-
I draw the lower-right square with color = (1, 0, 0, .8)
and blend function (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
.
By my calculation, the render-to-texture squares should have color
.8 * (1, 0, 0, .8) + (1 - .8) * (0, 0, 0, 0) = (.8, 0, 0, .64)
and so after drawing that texture on the white background, they should have color
(.8, 0, 0, .64) + (1 - .8) * (1, 1, 1, 1) = (1, .2, .2, .84)
and the lower-right square should have color
.8 * (1, 0, 0, .8) + (1 - .8) * (1, 1, 1, 1) = (1, .2, .2, .84)
which should look the same! Is my reasoning wrong? Is my computation wrong?
In any case, my goal is to cache some of my scene. How do I render-to-texture and then draw that texture so that it is equivalent to just drawing the scene inline?
发布评论
评论(3)
如果要将混合内容渲染到纹理并将该纹理合成到屏幕上,最简单的方法是在各处使用预乘 alpha。证明这适用于您的情况相对简单:预乘形式的半透明方块的颜色为 (0.8, 0, 0, 0.8),并将其与 (0, 0, 0, 0) 与 (< code>GL_ONE,
GL_ONE_MINUS_SRC_ALPHA
) 本质上是将方块的颜色传递到纹理。将 (0.8, 0, 0, 0.8) 与 (GL_ONE
,GL_ONE_MINUS_SRC_ALPHA
) 混合在不透明白色上,得到 (1.0, 0.2, 0.2, 1.0)。请注意,颜色通道与您的第三次计算相同,但 Alpha 通道仍然为 1.0,这正是您对被混合对象覆盖的不透明对象所期望的值。Tom Forsyth 有一篇很好的文章 关于预乘 alpha。整篇文章值得一读,但请参阅“合成半透明层”部分,以了解为什么数学在一般情况下有效。
If you want to render blended content to a texture and composite that texture to the screen, the simplest way is to use premultiplied alpha everywhere. It’s relatively simple to show that this works for your case: the color of your semi-transparent squares in premultiplied form is (0.8, 0, 0, 0.8), and blending this over (0, 0, 0, 0) with (
GL_ONE
,GL_ONE_MINUS_SRC_ALPHA
) essentially passes your squares’ color through to the texture. Blending (0.8, 0, 0, 0.8) over opaque white with (GL_ONE
,GL_ONE_MINUS_SRC_ALPHA
) gives you (1.0, 0.2, 0.2, 1.0). Note that the color channels are the same as your third calculation, but the alpha channel is still 1.0, which is what you would expect for an opaque object covered by a blended object.Tom Forsyth has a good article about premultiplied alpha. The whole thing is worth reading, but see the “Compositing translucent layers” section for an explanation of why the math works out in the general case.
糟糕,我的计算错误了!第二行应该
确实看起来与我所看到的相符(当我将最后一个方块更改为颜色
(1, .2, .2, .8)
时,所有三个方块都显示相同的颜色) 。Whoops, my computation is wrong! the second line should be
which indeed seems to match what I see (when I change the last square to color
(1, .2, .2, .8)
, all three squares appear the same color).关于你的最后一个问题:用纹理替换部分场景并不是一件小事。 Stefan Jeschke 的 博士论文。
Regarding your last question: Replacing parts of the scene by textures is not trivial. A good starting point is Stefan Jeschke's PhD thesis.