现在我有一个网格(.off),我想将网格投影到一个平面上,以获得灰度图像。
图像中的像素表示网格模型中的点到平面的深度(可能为正或负),图像中的(x,y)在网格中是相同的。(注意:不仅投影顶点,而且面和边缘,我们可以使用插值左右)。
有人有想法吗?或者任何当前可用的代码?
使用 OpenGL,您可以从绘制网格开始。然后使用glReadPixels
, 指定GL_DEPTH_COMPONENT
读取像素的深度。一个小细节:您获得的值将映射到范围 0..1,因此您几乎总是希望使用浮点类型(例如,GL_FLOAT
)。
如果您确实需要将其转换为从网格到平面的距离,则需要找到最小和最大距离,并使用线性插值将像素值转换回距离。对于大多数用途(包括灰度图像),0..1 范围无需进一步转换即可正常工作。
它不是通过像素读取进行的现代解决方案,您想要为生产代码执行的操作是使用输出深度的像素着色器渲染到纹理。然后您可以决定是否要输出均匀深度、线性深度、球面深度、世界深度以及任何您想要的深度!
如有必要,这种解决方案可以实时执行(每帧一次)。
您的输出纹理可能是byte R8
或float R16
什至float R32
是您需要的(但请注意由于低端显卡的带宽限制导致的性能问题)。
同质深度只是在您从顶点着色器输出时将世界位置作为变量传递到像素着色器(在 texcoord 中),然后在像素着色器中输出该向量的 z。你需要记住这个向量已经被顶点着色器和像素着色器之间的光栅化器除以它的 w 分量。此方法获取您的homogeneous depth
,它不是线性的,与您直接读取深度缓冲区的结果相同。
那么您还可以通过将其 w 分量中带有“1”的向量作为变量传递来输出世界深度或线性深度。
您可以输出球形深度,这在使用透视投影时会有所不同。球面深度是使用长度函数的真实光线追踪深度。您可以通过获取向量的长度来获得此值world coordinate of my pixel -> eye position
。眼睛位置是您的视图矩阵的第 4 行(作为统一传递)。并且world coordinate of my pixel
是由光栅化器从顶点着色器退出的变量中插值的值(与线性深度相同,w 中为 1)。这需要以浮点纹理格式输出,否则您会遇到很多钳位和精度问题。
现在您已经渲染了渲染目标,您可以在渲染的第二阶段使用纹理,稍后将其作为采样器插入另一个着色器中。CopyResource
或者,您可以使用内存管理的第二个纹理将其流式传输回 CPU staged
,然后您可以map
或lock
然后简单地 memcpy 到 CPU 内存。小心这种过程会杀死帧率,应该避免,或者很少这样做,例如屏幕截图或调试。