在 OpenGL 中计算平均场景亮度
Calculating average scene brightness in OpenGL
我目前正在实施自动调整曝光以在 OpenGL 中与 HDR 一起使用。为此,我需要检索前一帧中所有像素的平均亮度。
我还没有找到任何关于如何执行此操作的可靠解释。据我所知,有两种方法可以解决这个问题。
- 使用 glReadPixels 将帧缓冲区复制到内存并在 CPU 上对它们进行平均。这可能会非常慢并且不能很好地利用 GPU。
- 获取帧并使用线性过滤将其渲染到连续较小的 FBO。这让 GPU 可以完成大部分工作,但它需要大量的 FBO(对于 1080p 屏幕大约需要 10 个)。
必须有更好的方法来获得平均场景亮度。有人有什么建议吗?
您的选项 2 与在纹理上使用 glGenerateMipmap
没有太大区别,只是您不需要麻烦处理任何客户端对象,例如 FBO。所以基本上,渲染到纹理的 mipmap 级别 0,让 GL 生成 mipmap 金字塔,然后只读回最高级别的 1x1 图像可能是获得平均颜色值近似值的最简单方法。
我想到了两个选项:
- 使用 glGenerateMipmap,计算 2x2 的平均值 window,让您获得最小级别的平均场景亮度。这可以在着色器中使用 textureLod 函数检索。由于每个 mipmap 级别的大小都是前一个级别的一半,因此正确的级别将是 log2(max),其中 max 是 GL_MAX_TEXTURE_SIZE.
的返回值
- 使用计算着色器做与 glGenerateMipmap 基本相同的事情,但具有更大的 window 大小,这可能会更快(尽管我从未测试过)。
我目前正在实施自动调整曝光以在 OpenGL 中与 HDR 一起使用。为此,我需要检索前一帧中所有像素的平均亮度。
我还没有找到任何关于如何执行此操作的可靠解释。据我所知,有两种方法可以解决这个问题。
- 使用 glReadPixels 将帧缓冲区复制到内存并在 CPU 上对它们进行平均。这可能会非常慢并且不能很好地利用 GPU。
- 获取帧并使用线性过滤将其渲染到连续较小的 FBO。这让 GPU 可以完成大部分工作,但它需要大量的 FBO(对于 1080p 屏幕大约需要 10 个)。
必须有更好的方法来获得平均场景亮度。有人有什么建议吗?
您的选项 2 与在纹理上使用 glGenerateMipmap
没有太大区别,只是您不需要麻烦处理任何客户端对象,例如 FBO。所以基本上,渲染到纹理的 mipmap 级别 0,让 GL 生成 mipmap 金字塔,然后只读回最高级别的 1x1 图像可能是获得平均颜色值近似值的最简单方法。
我想到了两个选项:
- 使用 glGenerateMipmap,计算 2x2 的平均值 window,让您获得最小级别的平均场景亮度。这可以在着色器中使用 textureLod 函数检索。由于每个 mipmap 级别的大小都是前一个级别的一半,因此正确的级别将是 log2(max),其中 max 是 GL_MAX_TEXTURE_SIZE. 的返回值
- 使用计算着色器做与 glGenerateMipmap 基本相同的事情,但具有更大的 window 大小,这可能会更快(尽管我从未测试过)。