2013-07-19 24 views
3

現在我有一個網格(.off),並且我想將網格投影到一個平面,以獲得 灰度圖像。如何使用opengl或dx生成網格的深度(高度)圖像

圖像中的像素代表從網格模型中的點到平面的深度(可以是正值或負值),圖像中的(x,y)在網格中相同(注意:不僅僅是項目頂點還有面和邊,我們可以使用插值等)。

任何人都有想法?或任何目前可用的代碼?

回答

3

使用OpenGL,您可以開始繪製網格。然後使用glReadPixels,指定GL_DEPTH_COMPONENT來讀回像素的深度。一個小細節:您得到的值將被映射到範圍0..1,因此您幾乎總是希望使用浮點類型(例如,GL_FLOAT)。

如果您需要需要轉換爲距網格到平面的距離,則需要查找最小距離和最大距離,並使用線性插值將像素值轉換回距離。對於大多數目的(包括灰度圖像),0..1範圍無需進一步轉換即可正常工作。

+0

感謝您的有用建議。所以我必須自己寫線性插值? openGL可以自動執行嗎?我不知道如何在臉上插入點。 – user2597823

+0

您需要找到最接近平面的點和網格中離平面最遠的點。那麼每個像素的距離將是'最接近的+像素值*(最接近的)'。 –

+1

您將從原始深度緩衝區讀取的距離不是線性的,您需要反轉投影公式以獲得世界深度。 –

1

它不是一種現代化的解決方案,通過像素讀取,您想要對生產代碼執行的操作是使用輸出深度的像素着色器渲染到紋理。那麼你可以決定是否要輸出均勻的深度,線性深度,球體深度,任何深度的世界深度!

如果需要,這種解決方案可以實時執行(每幀一次)。
如果您需要,您的輸出紋理可能是byte R8float 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,然後您可以使用maplock,然後將其簡單地存儲到CPU內存中。注意這種過程會殺死幀速率,應該避免,或者很少爲屏幕截圖或調試完成。