首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenGL glReadPixels性能

OpenGL glReadPixels性能
EN

Stack Overflow用户
提问于 2015-09-30 11:59:43
回答 1查看 2.2K关注 0票数 1

我正在尝试实现自动曝光的HDR色调映射,我正在尝试降低成本,以找到我的场景的平均亮度,我似乎遇到了glReadPixels的瓶颈。下面是我的设置:

1:我创建了一个下采样的FBO,以降低在仅使用GL_RED值的GL_BYTE格式使用glReadPixels时的读取成本。

代码语言:javascript
运行
复制
private void CreateDownSampleExposure() {
        DownFrameBuffer = glGenFramebuffers();
        DownTexture = GL11.glGenTextures();
        glBindFramebuffer(GL_FRAMEBUFFER, DownFrameBuffer);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, DownTexture);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RED, 1600/8, 1200/8,
                0, GL11.GL_RED, GL11.GL_BYTE, (ByteBuffer) null);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                GL11.GL_TEXTURE_2D, DownTexture, 0);
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
            System.err.println("error");
        } else {
            System.err.println("success");
        }
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

    }

2:设置ByteBuffers并读取上面FBO纹理的纹理。

代码语言:javascript
运行
复制
Setup(){
byte[] testByte = new byte[1600/8*1000/8];
ByteBuffer testByteBuffer = BufferUtils.createByteBuffer(testByte.length);
testByteBuffer.put(testByte);
testByteBuffer.flip();
}
MainLoop(){
  //Render scene and store result into downSampledFBO texture

   GL11.glBindTexture(GL11.GL_TEXTURE_2D, DeferredFBO.getDownTexture());

  //GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL11.GL_RED, GL11.GL_BYTE,       
  //testByteBuffer); <- This is slower than readPixels. 

  GL11.glReadPixels(0, 0, DisplayManager.Width/8, DisplayManager.Height/8, 
  GL11.GL_RED, GL11.GL_BYTE, testByteBuffer);
  int x = 0;

  for(int i = 0; i <testByteBuffer.capacity(); i++){
        x+= testByteBuffer.get(i);
        }
    System.out.println(x); <-Print out accumulated value of brightness. 
    }
  //Adjust exposure depending on brightness. 

问题是,我可以对我的FBO纹理进行100倍的下采样,所以我的glReadPixels只读取16x10像素,并且几乎没有性能提升。没有下采样会有很大的性能提升,但是一旦我将宽度和高度除以8,它似乎就会下降。看起来仅仅调用这个函数就有很大的开销。在调用glReadPixels时,我是否做错了什么或没有考虑到什么?

EN

回答 1

Stack Overflow用户

发布于 2015-09-30 15:32:19

glReadPixels速度很慢,因为它必须等到图形处理器完成所有渲染后才能给出结果。可怕的同步点。

让glReadPixels变得更快的一种方法是使用某种双/三重缓冲方案,这样你只需要在你期望图形处理器已经完成的渲染到纹理上调用glReadPixels。只有在您的应用程序中可以接受在接收glReadPixels结果之前等待几个帧的情况下,这才是可行的。例如,在视频游戏中,这种延迟可以被解释为对瞳孔对光照条件变化的反应时间的模拟。

但是,对于特定的色调映射示例,您可能只想计算平均亮度,以便将该信息反馈到GPU中以进行另一个渲染过程。不是glReadPixels,而是计算平均值,方法是将图像复制到使用线性过滤(框过滤器)连续半个大小的渲染目标,直到目标降到1x1。

1x1目标现在是包含平均亮度的纹理,并且可以在色调映射渲染过程中使用该纹理。没有同步点。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32857554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档