Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 从深度缓冲区快速读取值_Performance_Opengl_Glsl_Depth - Fatal编程技术网

Performance 从深度缓冲区快速读取值

Performance 从深度缓冲区快速读取值,performance,opengl,glsl,depth,Performance,Opengl,Glsl,Depth,我正在用GLSL在OpenGL(3.X)中实现“场上深度”。 它工作得非常好,中心深度由着色器(纹理(tex1,vec2(0.5))来自动聚焦。但是使用这样一个实现焦点会立即发生。他应该喜欢眼睛——逐渐适应。为此,我需要在CPU内存侧中间的深度。 我知道如何使用PBO,使用它读取像素/像素颜色工作得非常快(异步运行),但是将GL_RGB更改为GL_DEPTH_组件性能会急剧下降。你知道有什么方法可以比较快地读出中心深度是什么颜色吗 glReadPixels(a/2, b/2, 1, 1,

我正在用GLSL在OpenGL(3.X)中实现“场上深度”。 它工作得非常好,中心深度由着色器(纹理(tex1,vec2(0.5))来自动聚焦。但是使用这样一个实现焦点会立即发生。他应该喜欢眼睛——逐渐适应。为此,我需要在CPU内存侧中间的深度。 我知道如何使用PBO,使用它读取像素/像素颜色工作得非常快(异步运行),但是将GL_RGB更改为GL_DEPTH_组件性能会急剧下降。你知道有什么方法可以比较快地读出中心深度是什么颜色吗

    glReadPixels(a/2, b/2, 1, 1, GL_RGB , GL_BYTE, 0); // WORKS FINE - 30 ns
    glReadPixels(a/2, b/2, 1, 1, GL_DEPTH_COMPONENT, GL_BYTE, 0); // WORKS SLOOOW - around 3500 microseconds
    glReadPixels(a/2, b/2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, 0); // WORKS SLOOOW- around 3500 microseconds
@编辑: 已创建FBO纹理:

glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT32F , sett.framebuffer_width,  sett.framebuffer_height, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
下载深度:

index = (index + 1) % 2;// for ping-pong PBO
nextIndex = (index + 1) % 2;// for ping-pong PBO
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]);
glReadPixels(w/2, h/2, 1, 1, GL_DEPTH_COMPONENT , GL_FLOAT, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
将深度复制到ram:

GLfloat tabc[10];
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]);
GLfloat* srccccc = (GLfloat*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
tabc[0]=*srccccc;
std::cout<<"Depth center: "<<tabc[0]<<std::endl;//only to check is that correct
glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);     
GLfloat-tabc[10];
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB,pboIds[nextIndex]);
GLfloat*SRCCCC=(GLfloat*)glMapBuffer(GLU像素块缓冲区,GLU只读);
tabc[0]=*SRCCCC;
标准::cout
当然他们很慢。一般来说,深度缓冲区既不是8位字节,也不是32位浮点值。颜色的回读之所以能够快速工作,是因为您的颜色与帧缓冲区匹配。而且,由于您非常明智地在readback中使用PBO,因此必须根据该值进行基于CPU的转换,这将降低您的性能

因此,您需要在这里执行相同的操作:将像素传输参数与帧缓冲区图像匹配

如果您是从FBO处读取,那么您应该知道图像的确切位深(您正在使用,对吗?)。因此,只需匹配:

GL_DEPTH_COMPONENT16  -> GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT
GL_DEPTH_COMPONENT32  -> GL_DEPTH_COMPONENT, GL_UNSIGNED_INT
GL_DEPTH_COMPONENT32F -> GL_DEPTH_COMPONENT, GL_FLOAT
还有一种纯粹的深度缓冲格式:
GL\u depth\u component 24
。您可能只需使用
GL\u UNSIGNED\u INT
,但很可能OpenGL在写入数据时必须将数据扩展到32位

这就是您应该使用
GL_DEPTH24_模具8
的原因之一。对于这个,您可以这样做:

GL_DEPTH24_STENCIL8 -> GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8
您必须将每个32位值右移8位,并在需要深度值时屏蔽掉前8位。但它应该起作用

如果你是从报纸上读的,那就有点棘手了。很有可能,当您设置渲染上下文时,您会告诉OpenGL您希望在帧缓冲区中使用的比特深度。但是你可能还没有得到它们,所以你需要问一下

要做到这一点,你需要。有了它,您可以查询
GL\u帧缓冲区\u附件\u深度\u大小​
GL\u深度
attachment和
GL\u FRAMEBUFFER\u attachment\u STENCIL\u大小​
GL_模具
附件。重要的是,你要测试这两个方面;如果同时具有深度和模具位,则需要使用深度/模具读取


一旦有了位深度,就假装它们是上述内部格式之一,然后按正常方式进行。

为什么更改景深的速度需要CPU干预?CPU应该提供事物处于清晰焦点的深度。所以这应该只是CPU设置焦距动画的问题。CPU需要前几帧的中心深度才能改变模糊度。如何告诉CPU在屏幕中间有一个物体有多远?(最简单的方法是已知的,我需要做得很快)知道如何给焦点打分。然后介绍如何在着色器中进行模糊。“如何告诉CPU在屏幕中间有多远?”:GPU/CPU同步是否真的值得一个答案?我只是根据场景中心附近的对象进行猜测。但是如何在cpu上进行猜测呢?以下是我的深度纹理创建:GLTEXAGE2D(GL_纹理_2D,0,GL_深度_组件,settings.framebuffer_width,settings.framebuffer_height,0,GL_深度_组件,GL_FLOAT,0)@Skides:停止使用未调整大小的内部格式。告诉OpenGL你想要什么;不要让它猜测。主要帖子更新-它是正确的(所有格式)?377微秒-从3500下降,所以更好
GL_DEPTH24_STENCIL8 -> GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8