PyOpenGL - 获取绘制图像的深度图



我从特定的角度(使用视图和投影矩阵(绘制了一个特定的场景。我使用了三角形的 VBO,等等。 我可以使用以下命令获取图像的 RGB:

data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
data = np.frombuffer(data, dtype=np.uint8).reshape(width, height, 3)[::-1]
cv2.imwrite(r"c:tempimage1.png", data)

但是获取深度图会得到一些奇怪的结果,主要由 255 组成:

data2 = glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE)
data2 = np.frombuffer(data2, dtype=np.uint8).reshape(width, height)[::-1]
cv2.imwrite(r"c:tempimage2.png", data2)

我尝试替换GL_UNSIGNED_BYTE->GL_FLOATuint8->float32

但这并没有帮助

深度图由 1.0 初始化,如果将其读取到GL_UNSIGNED_BYTE缓冲区,则会导致 255。注意,深度图在 [0.0, 1.0] 范围内,如果读取到GL_UNSIGNED_BYTE,则此范围映射到 [0, 255]。

在透视投影中,z 坐标不会线性映射到深度缓冲区。深度值迅速增加,接近远平面的几何图形将导致值深度值为 255。

如果深度值在 [0.0, 1.0] 范围内,并且您要计算视图(眼睛(空间 z 坐标,则必须将深度值转换为归一化设备z坐标拳头 (z_ndc(:

z_ndc = 2.0 * depth - 1.0;

这个坐标可以通过以下公式转换为眼空间z坐标(z_eye(:

z_eye = 2.0 * n * f / (f + n - z_ndc * (f - n));

其中n是近平面,f是远平面。

请注意,此转换仅适用于透视投影。

在正交投影中,z坐标线性映射到深度。所以向后变换要简单得多:

z_eye = depth * (f-n) + n; 

参见 如何在现代 OpenGL 中使用片段着色器中的 gl_FragCoord.z 线性渲染深度?

最新更新