我实现了一个简化的延迟着色(我不计算点光源的边界),其中在填充g-buffer之后,我只使用了一个用于计算照明的全屏四边形。我使用混合(glBlendFunc(GL_ONE,GL_ONE))。然后,glClearColor中的rgb值应设置为0,以获得正确的结果。填充g缓冲区时glClearColor可以是任何颜色(某些颜色可能只会改变最终图像中的背景颜色)。现在我想知道我应该如何在最终图像中设置背景颜色。一种方法是在填充g-buffer期间使用glClearColor(0,0,0),然后在片段着色器中使用以下if语句:
if((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
{
fragColor = vec4(1, 0, 0, 1); // here we can set a background color
}
else
{
fragColor = computeLighting(worldPos, normal, diffM, specM, specMS);
}
它工作正常,但若语句可能会导致一些性能损失。这是唯一的设置方式吗背景色?
不确定我是否理解问题所在,但这里有一些想法和许多假设。
你正在考虑做这样的事情?:
- 使用所需的背景颜色清除gbuffer中的漫反射附件(但是……您不想使用该值清除其他纹理,例如法线!)
- 填充gbuffer后,任何未被几何体覆盖的对象都应该仍然具有背景色(在漫反射附件中)
- 如果没有为片段定义法线,则在最后阶段手动编写硬编码颜色
我假设渲染器正在执行以下操作:
- 填充gbuffer(具有多个附件的FBO中的漫反射、法线、深度等)
- 对于每种灯光,都会将全屏四元相加混合渲染到单独的FBO(灯光累积缓冲区)中
- 最后,将gbuffer中的漫反射附件与光累积缓冲区结合起来,将最终结果渲染到屏幕上
确实没有理由让着色器负责编写这样的背景色。实际上,我也会渲染背景中的内容,并始终清除0值的gbuffer。我想,当你在最后一个阶段结合漫射和光时,事情可能会出错,所以采用下面解释的模版方法可能会更简单。就我个人而言,我将材质索引存储在漫反射颜色的alpha通道中,然后上传纹理中的所有材质属性。
在我的材料中,我有两个标量(以及更多…):
- 环境重量
- 轻量级
当组合漫射缓冲和光缓冲时(大大简化):
FinalColor = Diffuse * AmbientWeight + Diffuse * Light * LightWeight
如果背景使用AmbientWeight=1和LightWeight=0的材质0,则FinalColor将始终是漫反射缓冲区中的原始值。
许多简单的延迟渲染器只是这样计算最终结果:
FinalColor = Diffuse * Light
(来自扩散缓冲液的片段*来自光缓冲液的碎片)
在你的情况下,这当然会导致你的背景颜色消失,因为这些碎片永远不会被点燃。(Diffuse * 0
始终是结果)可以使用漫反射缓冲区中的alpha通道作为AmbientWeight以获得一些快速结果。
FinalColor = Diffuse * Diffuse.a + Diffuse * Light
谈到性能:
这真的很难预测。跳过着色器中的最终灯光计算可能会有所帮助,但在进入此阶段之前,您已经完成了所有gbuffer读取和解包。无论着色器返回什么,混合操作最终都会影响整个灯光缓冲区,并读取每个灯光的整个gbuffer。检查法线缓冲区中的所有组件是否为0将只触发没有几何体的区域。当每盏灯使用全屏四元显示器时,你会遇到很多瓶颈。
首先读取位置缓冲区(或从深度缓冲区重建位置),然后确定点光源是否无法到达碎片,并在执行其他操作之前将其丢弃,这可能会有所帮助。对于较小的灯光,您最终不会读取每个片段的gbuffer中的所有内容。这实际上取决于gbuffer有多胖,渲染的是什么,灯光有多大,渲染的灯光有多少。
动态分支也会影响性能,但有时可能是"较小的害处"。我尽量避开它。
额外:
当谈到"背景色"时,我个人使用模版缓冲区来填充天空框或类似的背景。在写入漫反射缓冲区时,在使用反向遮罩渲染背景时,构建模具遮罩,以便仅影响背景片段(不进行深度测试或深度写入)。如果我的整个场景都被几何体覆盖,就不会有碎片被写出来。这假设您正在将最终结果写入使用与gbuffer相同深度附件的第三个FBO。(深度24+模版8缓冲液)
您也可以使用带有灯光信息的UBO发送阵列,而不是使用全屏四边形(带混合)绘制每个灯光。然后用一个全屏四边形绘制所有点光源。你最终会做同样数量的光计算,但读写的数量总是恒定的。(UBO仍然有大小限制)
您还可能会发现感兴趣的Tiled Deferred Shading可能是下一步:http://www.cse.chalmers.se/~olaolss/main_frame.php?contents=发布&id=波浪形着色(你只从gbuffer读取一次,只为光通道写入一个片段)
纸张:http://www.cse.chalmers.se/~uff/tiled_shading_preprint.pdf