@cybercser
2015-11-20T14:36:59.000000Z
字数 1729
阅读 96
OpenGL
教程
alpha通道的概念很简单。我们以前的计算结果是RGB值,现在则是RGBA值:
// Ouput data : it's now a vec4
out vec4 color;
前三个分量仍可以通过重组操作符(swizzle operator).xyz访问,最后一个分量通过.a访问:
color.a = 0.3;
与直觉相反,alpha代表的是不透明度;因此alpha = 1代表完全不透明,alpha = 0为完全透明。
这里我们简单地将alpha硬编码为0.3;但更常见的做法是用一个uniform变量表示它,或从RGBA纹理中读取(TGA格式支持alpha通道,而GLFW支持TGA格式)。
结果如下。既然我们能“看透”模型表面,请确保关闭背面剔除(glDisable(GL_CULL_FACE)
)。否则我们就发现模型没有了“背”面。
上一个截图看上去还行,但这仅仅是运气好罢了。
这里我画了一红一绿两个alpha值为50%的正方形。从中可以看出顺序的重要性,最终的颜色显著影响了眼睛对深度的感知。
我们的场景中也出现了同样的现象。试着稍稍改变一下观察点:
原来这还是个十分棘手的问题。您在游戏中也没怎么见过透明的东西,是吧?
常见解决方案即对所有的透明三角形排序。是的,所有的透明三角形。
可以用C语言的qsort
函数或者C++的std::sort
函数来排序。细节就不多说了,因为……
这么做可以解决问题(下一节还会介绍它),但是:
一个足够好的解决方案是:
如果您的引擎确实需要顶级的透明效果,这里有一些值得研究的技术:
注意,即便是《小小大星球》(Little Big Planet)这种刚出炉的、运行在高端主机上的游戏,也只用了一层透明。
要让上述代码运行起来,得设置好混合函数。
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
这意味着
New color in framebuffer =
current alpha in framebuffer * current color in framebuffer +
(1 - current alpha in framebuffer) * shader's output color
上图红色方块居上的效果由如下等式得来:
new color = 0.5*(0,1,0) + (1-0.5)*(1,0.5,0.5); // (the red was already blended with the white background)
new color = (1, 0.75, 0.25) = the same orange
© http://www.opengl-tutorial.org/
Written with Cmd Markdown.