使用 FBO 的 OpenGL 着色管道效率
OpenGL shading pipeline efficiency with FBOs
我一直在努力实现延迟着色,因为我希望我的场景中至少有 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 中,哪个更有效渲染屏幕四边形?
嗯,可能是这样的:
从几何FBO到照明的blit深度缓冲区通过FBO
正如您所指出的,格式转换可能会很慢。但是,由于您为此 blit 操作定义了输入和输出缓冲区,因此它们可能使用相同的深度格式。因此,块传输操作可能会进行得更快。
此外,您可能根本不应该做这种闪电。只需将geometryFBO
的深度/模具缓冲区附加到lightingPassFBO
即可渲染光立方。只需记住在渲染灯光后删除附件(否则,假设您正在从延迟传递中的深度缓冲区读取,则延迟通道将具有未定义的行为)。
至于你关于块传输与全屏四边形的问题,我有一个更好的问题:为什么你在一个场景中积累了20+灯光而不使用高动态范围照明?因为要渲染到屏幕的最终通道也应使用色调映射将 HDR 图像转换为 LDR 以进行显示。
但至于确切的问题,blit 操作应该不比 FSQ 慢,假设没有进行格式转换。如果发生格式转换,那么将内容带到顶点着色器可能会更有效。
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- IPC使用多个管道和分支进程来运行Python程序
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 如何创建函数管道,以便函数一个接一个地运行?
- Gstreamer 管道从命令 lne 到 c 代码
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 代码的效率. 转到和函数调用
- 将旧管道转换为现代 openGL 时出现问题
- 对于循环C++可能效率低下
- 内存效率表示最短路径的方法?
- 如何提高该函数的运行效率?
- 效率:标准::数组与标准::矢量
- 如何使用管道在父级和子级之间来回传递文件
- 在没有管理员权限的情况下连接到同一网络中的命名管道
- 如何提高BST的搜索操作效率?
- 如何测量管道延迟?
- 我如何使用此程序管道多个命令?C++
- 先进先出:一个进程永远不会从管道读取
- 字符串引用参数的效率C++
- 使用 FBO 的 OpenGL 着色管道效率