C++ 如何使用opengl或dx从网格生成深度(高度)图像

C++ 如何使用opengl或dx从网格生成深度(高度)图像,c++,opengl,graphics,directx,C++,Opengl,Graphics,Directx,现在我有了一个网格(.off),我想将网格投影到一个平面,以获得一个 灰度图像 图像中的像素表示从网格模型中的点到平面的深度(可以是正的或负的),并且图像中的(x,y)在网格中是相同的。(注意:不仅投影顶点,而且投影面和边,我们可以使用插值等) 有人有主意吗?或任何当前可用的代码 使用OpenGL,您可以从绘制网格开始。然后使用glReadPixels,指定GL\u DEPTH\u COMPONENT读回像素的深度。一个小细节:您得到的值将映射到范围0..1,因此您几乎总是希望使用浮点类型(例如

现在我有了一个网格(.off),我想将网格投影到一个平面,以获得一个 灰度图像

图像中的像素表示从网格模型中的点到平面的深度(可以是正的或负的),并且图像中的(x,y)在网格中是相同的。(注意:不仅投影顶点,而且投影面和边,我们可以使用插值等)


有人有主意吗?或任何当前可用的代码

使用OpenGL,您可以从绘制网格开始。然后使用
glReadPixels
,指定
GL\u DEPTH\u COMPONENT
读回像素的深度。一个小细节:您得到的值将映射到范围0..1,因此您几乎总是希望使用浮点类型(例如,
GL\u FLOAT


如果确实需要将其转换为从网格到平面的距离,则需要找到最小和最大距离,并使用线性插值将像素值转换回距离。对于大多数用途(包括灰度图像),0..1范围无需进一步变换即可正常工作。

通过像素读取并不是一种现代解决方案,生产代码要做的是使用输出深度的像素着色器渲染到纹理。然后,您可以决定是否要输出均匀深度、线性深度、球形深度、任意深度的世界深度

如果需要,这种解决方案可以实时执行(每帧一次)。
如果需要,您的输出纹理可以是
字节R8
浮点R16
甚至
浮点R32
(但要注意低端图形卡带宽限制导致的性能问题)

同质深度只是将世界位置作为变量从顶点着色器输出到像素着色器(在texcoord中),然后在像素着色器中输出该向量的z。您需要记住,该向量已被顶点着色器和像素着色器之间的光栅化器除以其w分量。此方法获得的是
均匀深度
,这不是线性的,与直接读取深度缓冲区的结果相同

然后,您还可以通过将w分量中带有“1”的向量作为变量传递,来输出世界深度或lienar深度

您可以输出一个球面深度,这在使用透视投影时会有所不同。球面深度是使用长度函数的实际光线跟踪深度。通过获取我的像素的向量
世界坐标->眼睛位置的长度来获得该值。眼睛位置是视图矩阵的第四行(以统一方式传递)。“我的像素的世界坐标”
是光栅化器从顶点着色器退出的变量中插值的值(与线性深度相同,w中为1)。这一个需要以浮点纹理格式输出,否则会遇到很多夹紧和精度问题

现在已渲染渲染目标,可以在渲染的第二阶段使用纹理,方法是稍后将其作为采样器插入另一个着色器中。
或者,您可以使用
CopyResource
将其流回到CPU,以
暂存的
内存管理的第二个纹理,然后
映射
锁定
,然后只需将memcpy存储到CPU内存。请注意,这种过程会降低帧率,应该避免,或者很少进行,例如屏幕截图或调试。

谢谢你的有用建议。所以我必须自己编写线性插值?openGL能自动完成吗?我不知道如何插值面上的点。你需要在网格中找到离平面最近的点和离平面最远的点。然后每个像素的距离将是
最近+像素值*(最远-最近)
。从原始深度缓冲区读取的距离不是线性的,您需要反转投影公式以获得世界深度。