0

我一直在努力实现延迟着色,因为我想在我的场景中至少有 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?

4

1 回答 1

2

嗯,大概是这样的:

从geometryFBO到lightingPassFBO的blit深度缓冲区

正如您所指出的,格式转换可能很慢。但是由于您为此 blit 操作定义了输入和输出缓冲区,它们可能使用相同的深度格式。因此,blitting 操作可能会进行得更快。

此外,您甚至可能根本不应该这样做。在渲染光立方之前,只需将geometryFBO的深度/模板缓冲区附加到。lightingPassFBO请记住在渲染灯光后移除附件(否则您的延迟通道将具有未定义的行为,假设您正在从延迟通道中的深度缓冲区读取)。

至于您关于 blitting 与全屏四边形的问题,我有一个更好的问题:您为什么要在一个场景中累积 20 多个灯光而不使用高动态范围照明?因为渲染到屏幕的最后一遍也应该使用色调映射将您的 HDR 图像转换为 LDR 以进行显示。

但至于确切的问题,假设没有进行格式转换,blit 操作不应该比 FSQ 慢。如果发生格式转换,那么将内容带到顶点着色器可能会更有效。

于 2016-01-24T19:35:39.023 回答