glReadPixels()读取GL_DEPTH_COMPONENT很慢

4
我的应用程序依赖于从帧缓冲区中读取深度信息。我已经使用glReadPixels(0, 0,width,height,GL_DEPTH_COMPONENT,GL_FLOAT,&depth_data)实现了这一点。
但是,这种方法运行得非常慢,会使我的应用程序从平滑的30fps变成卡顿的3fps。如果我尝试读取其他维度或数据,则它的运行速度是可以接受的。
总体来说:
- 没有glReadPixels -> 30帧每秒 - glReadPixels(0, 0,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&depth_data)-> 20帧每秒,可以接受 - glReadPixels(0, 0,width,height,GL_RED,GL_FLOAT,&depth_data)-> 20帧每秒,可以接受 - glReadPixels(0, 0,width,height,GL_DEPTH_COMPONENT,GL_FLOAT,&depth_data)-> 3帧每秒,不可接受
为什么最后一个比其他调用慢得多?有没有办法解决这个问题?
width x height大约是100 x 1000,随着尺寸的增加,调用变得越来越慢。
我还尝试过使用像素缓冲对象,但对性能没有显著影响,只是将缓慢延迟到glMapBuffer()调用。
(我在MacBook Air nVidia 320m图形OS X 10.6上进行了测试,奇怪的是我的旧MacBook Intel GMA x3100读取深度缓冲区时能够达到约15fps。)
更新:将GLUT_MULTISAMPLE选项从glutInitDisplayMode选项中删除后,应用程序重新变得流畅,达到了20fps。我不知道该选项首先是做什么的,有人可以解释一下吗?

我知道这不是一个答案,但如果FPS很重要,不要使用glRead *或glGet *!如果您仅想要深度信息以供渲染目的,则最好编写自定义着色器,该着色器具有对深度缓冲区的读取访问权限。如果您真的需要这些深度信息来支持您的应用程序/游戏逻辑,我强烈建议重新考虑整体方法。 - Jonas Bötel
3个回答

3
如果您的主帧缓冲区启用了MSAA(存在GLUT_MULTISAMPLE),则会创建2个实际的帧缓冲区-一个具有MSAA,另一个是常规的。
第一个帧缓冲区是必需的,以便您进行填充。它包含前面和后面的颜色表面,加上深度和模板。第二个帧缓冲区必须仅包含由解决相应的MSAA表面产生的颜色。
但是,当您尝试使用glReadPixels读取深度时,驱动程序被强制解析启用MSAA的深度表面,这可能导致您的减速。

1
你选择的深度缓冲区存储格式是什么?
如果不是GLfloat,那么在读取时,你要求GL将深度缓冲区中的每个深度转换为浮点数。(对于第三个项目,使用GL_RED也是一样的。你的颜色缓冲区是浮点缓冲区吗?)

我不知道,我没有指定并使用了GLUT的默认值。我尝试了glReadPixels文档中的每种类型,它们都运行缓慢(除了那些会导致无效参数错误的类型)。 - Paul Wagener

0
无论是GL_FLOAT还是GL_UNSIGNED_BYTE,glReadPixels仍然非常慢。如果您使用PBO获取RGB值,则速度将非常快。 当使用PBO处理RGB值时,CPU使用率为4%。但是在处理深度值时,它将增加到50%。我已经尝试过GL_FLOAT,GL_UNSIGNED_BYTE,GL_UNSIGNED_INT,GL_UNSIGNED_INT_24_8。因此,我可以得出结论,PBO对于读取深度值是无用的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接