gpt4 book ai didi

performance - 从深度缓冲区快速读取值

转载 作者:行者123 更新时间:2023-12-04 04:47:12 34 4
gpt4 key购买 nike

我正在使用 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);

复制深度到 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);

它现在正在运行,速度要快得多(从 3500 微秒变为 357 微秒)。
现在好吗?所有格式?

最佳答案

glReadPixels(a/2, b/2, 1, 1, GL_DEPTH_COMPONENT, GL_BYTE, 0); // WORKS SLOOOW - around 3500 ns
glReadPixels(a/2, b/2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, 0); // WORKS SLOOOW- around 3500 ns

他们当然很慢。一般来说,深度缓冲区既不是 8 位字节也不是 32 位浮点值。您对颜色的复述工作很快的原因是因为您的 pixel transfer format and type匹配您的帧缓冲区。而且由于您在回读中非常明智地使用 PBO,因此必须对值进行基于 CPU 的转换会降低您的性能。

所以你需要在这里做同样的事情:将像素传输参数与帧缓冲图像相匹配。

如果您正在阅读 FBO,那么您应该知道图像的确切位深(您使用的是 sized internal formats ,对吗?)。所以简单地匹配:
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_DEPTH_COMPONENT24 .您可能只使用 GL_UNSIGNED_INT有了这个,但是OpenGL在写入数据时必须将数据扩展到32位的可能性很大。

这是您应该使用 GL_DEPTH24_STENCIL8 的原因之一相反。对于那个,你可以这样做:
GL_DEPTH24_STENCIL8 -> GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8

您必须将每个 32 位值右移 8 位,并在需要深度值时屏蔽掉前 8 位。但它应该工作。

如果您正在阅读 default framebuffer ,这有点棘手。很有可能,当你设置你的渲染上下文时,你告诉 OpenGL 你想要在你的帧缓冲区中的位深度。但你可能没有得到它们,所以你需要问。

为此,您需要 employ glGetFramebufferAttachmentParameter .有了这个,你可以查询 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE​来自 GL_DEPTH附件和 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE​来自 GL_STENCIL附件。测试这两个很重要;如果您同时拥有深度和模板位,则需要使用深度/模板读取。

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

关于performance - 从深度缓冲区快速读取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18006299/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com