我一直在努力实现延迟着色,因为我想在我的场景中至少有 20 盏灯。我在使它足够快时遇到了问题(现在仍然如此),但后来我做了一个我认为会使其变慢的更改,但实际上几乎是我的帧速率的两倍。
初始代码:
geometryPassFBO = createFBO(); // position texture, normal texture, colour texture and depth buffer
while (1)
{
bind geometryPassFBO.
allObjects.draw();
bind systemFBO();
for each light
send light info
draw light sphere sampling from position, normal and colour textures.
blit depth buffer from geometryFBO to systemFBO
for each light
light.draw(); // draw a cube to represent the light
2DObjects.draw(); // frame rate, etc...
}
我正在设置模板测试,如果在几何传递期间设置像素(即背景正常 = 0,0,0 和位置 = 0,0,0 和颜色 = 0 ,0,0。
但是,我很难将组合的深度/模板缓冲区复制到默认的深度/模板缓冲区。显然这不是很好,因为我们不知道系统深度/模板缓冲区采用什么格式。所以我读到最好设置另一个FBO,我们可以在其中指定深度/模板缓冲区格式,渲染到这个,然后blit或渲染一个屏幕四边形以将其输出到屏幕上。
因此,在添加任何模板材料之前,我只是添加了新的 FBO 以使该位工作。
我的新代码现在看起来像:
geometryPassFBO = createGeometryFBO(); // position texture, normal texture, colour texture and depth buffer
lightingPassFBO = createLightingFBO(); // colour texture and depth buffer
while (1)
{
bind geometryPassFBO.
allObjects.draw();
bind lightingPassFBO();
for each light
send light info
draw light sphere sampling from position, normal and colour textures.
blit depth buffer from geometryFBO to lightingPassFBO
for each light
light.draw(); // draw a cube to represent the light
2DObjects.draw(); // frame rate, etc...
bind systemFBO;
render screen quad sampling from colour texture.
}
这按预期工作。出乎意料的是,我的帧速率从 25 FPS 跃升至 45 FPS。
为什么是这样?必须为屏幕四边形执行额外的着色器通道如何比不执行更有效?
快速跟进问题。哪个更有效地使用简单的顶点和片段着色器渲染屏幕四边形以基于 gl_FragCoord 对纹理进行采样,或者将颜色附件直接传送到系统 FBO?