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

时间:2013-07-19 02:34:56

标签: c++ opengl graphics directx

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

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

任何人都有想法?或任何当前可用的代码?

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

通过像素读取不是现代解决方案,您想要为生产代码做什么,使用输出深度的像素着色器渲染到纹理。那么您可以决定是否要输出均匀深度,线性深度,球形深度,任何深度的世界深度!

如果需要,这种解决方案可以实时执行(每帧一次) 如果需要,您的输出纹理可以是byte R8float R16甚至是float R32(但是由于低端图形卡的带宽限制,请注意性能问题)。

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

然后你也可以输出世界深度或者lienar深度,通过在其w分量中传递一个带有“1”的向量作为变化。

您可以输出球形深度,这在使用透视投影时会产生差异。球形深度是使用长度函数的真实光线追踪深度。你通过取矢量world coordinate of my pixel -> eye position的长度得到这个值。眼睛位置是视图矩阵的第4行(作为统一传递)。 world coordinate of my pixel是光栅化器从顶点着色器退出的变化中插入的值(与线性深度相同,在w中为1)。这个需要以浮点纹理格式输出,否则会遇到很多钳位和精度问题。

现在您渲染了渲染目标,您可以在渲染的第二阶段使用纹理,稍后将其作为采样器插入另一个着色器中。 或者,您可以使用CopyResource将其流回CPU,然后使用staged内存管理的第二个纹理,然后可以maplock,然后只需memcpy到CPU内存。小心这种过程会杀死帧速率,应该避免,或者很少进行,例如屏幕截图或调试。