【发布时间】:2013-08-03 02:22:13
【问题描述】:
我正在使用 GLSL 在 OpenGL (3.X) 中实现“景深”。 它工作得很好,着色器(纹理(tex1,vec2(0.5)))占据了中心深度以进行自动对焦。但是使用这样的实现焦点会立即发生。他应该喜欢眼睛——逐渐适应。为此,我需要 CPU 内存一侧中间的深度。 我知道如何使用 PBO,使用它来读取像素/像素颜色工作得非常快(异步运行),但是将 GL_RGB 更改为 GL_DEPTH_COMPONENT 性能会急剧下降。你知道有什么方法可以比较快地读出中心深度是什么颜色吗?
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);
将深度复制到内存:
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);
现在可以运行了,速度要快得多(从 3500 微秒提高到 357 微秒)。 现在还好吗?所有格式?
【问题讨论】:
-
为什么改变景深速度需要CPU干预? CPU 应该提供清晰聚焦的深度。所以这应该只是 CPU 为焦距设置动画的问题。
-
CPU 需要几个先前帧的中心深度才能更改模糊渐变。如何告诉 CPU 一个物体在屏幕中间有多远? (已知最简单的方法,我需要快速完成)要知道如何对焦点进行分级。然后是如何在着色器中模糊。
-
"如何告诉 CPU 一个物体在屏幕中间有多远?:让 GPU/CPU 同步真的值得那个 答案准确吗?我只是根据场景中心附近的物体进行猜测。
-
但是如何在 cpu 上猜到呢?
标签: performance opengl glsl depth