C++ 如何使用opengl或dx从网格生成深度(高度)图像
现在我有了一个网格(.off),我想将网格投影到一个平面,以获得一个 灰度图像 图像中的像素表示从网格模型中的点到平面的深度(可以是正的或负的),并且图像中的(x,y)在网格中是相同的。(注意:不仅投影顶点,而且投影面和边,我们可以使用插值等)C++ 如何使用opengl或dx从网格生成深度(高度)图像,c++,opengl,graphics,directx,C++,Opengl,Graphics,Directx,现在我有了一个网格(.off),我想将网格投影到一个平面,以获得一个 灰度图像 图像中的像素表示从网格模型中的点到平面的深度(可以是正的或负的),并且图像中的(x,y)在网格中是相同的。(注意:不仅投影顶点,而且投影面和边,我们可以使用插值等) 有人有主意吗?或任何当前可用的代码 使用OpenGL,您可以从绘制网格开始。然后使用glReadPixels,指定GL\u DEPTH\u COMPONENT读回像素的深度。一个小细节:您得到的值将映射到范围0..1,因此您几乎总是希望使用浮点类型(例如
有人有主意吗?或任何当前可用的代码 使用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能自动完成吗?我不知道如何插值面上的点。你需要在网格中找到离平面最近的点和离平面最远的点。然后每个像素的距离将是最近+像素值*(最远-最近)
。从原始深度缓冲区读取的距离不是线性的,您需要反转投影公式以获得世界深度。