OpenGL著色器中原六仔平臺搭建程序解析--3D拾取
阿新 • • 發佈:2018-07-07
深度測試 bbs 教程 code 三級 索引數據 程序 情況 進入 3D拾取指的是中原六仔平臺搭建論壇:haozbbs.com Q1446595067 將鼠標在屏幕上點擊的位置匹配到3d遊戲場景中的某個圖元上,該圖元投影到屏幕上的像素恰好就是鼠標點擊的像素。3D場景在很多交互情境中有重要作用,使開發者的應用能夠將用戶的點擊對應到場景空間中的物體上。例如:用戶可以通過點擊選中某個物體或者物體的某一部分進行刪除等後續操作。在這個教程中的demo中,我們將渲染幾個物體,並且展示如何使用紅色標記選中的三角形圖元使其突出顯示。
源代碼詳解
為了實現3D拾取,我們將用到第23章陰影貼圖教程中介紹的OpenGL特性:幀緩存對象(FBO)。之前我們使用FBO只用作深度緩沖,因為我們感興趣的是從不同角度來比較像素的深度。而在3D拾取中,我們將既使用深度緩沖又要使用顏色緩沖,來存儲渲染的三角形的索引值。
3D拾取背後的技巧很簡單,對每一個三角形在程序運行時附加一個索引,並讓片段著色器輸出每個像素所在三角形的索引值。結果是我們將得到一個顏色緩沖,但是並不包含顏色值,而是像素所在的圖元的索引值。當鼠標點擊在窗口上,我們將根據鼠標的點擊位置來獲得這個索引並將這個三角形渲染成紅色。由於有深度測試,所以能夠保證當片元之間相互覆蓋時也可以得到最頂部的片元的索引(離相機最近的)。
上面就是3D拾取的概念和原理了,下面在進入代碼之前,我們需要做一些設計上的決策。例如,如何處理多物體的情況?如何處理一個物體多次draw call渲染的情況?我們需要為每個物體設置遞增的圖元索引使場景中每一個圖元都有唯一的索引,還是為每一個物體都重置其索引?
這篇教程的代碼采用了一種普遍的方法,可以根據需要進行簡化,會為每一個像素渲染三級索引:
第一級是像素所在物體的索引值,場景中的每一個物體都會得到一個唯一的索引;
物體的draw call的索引,這個索引會在開始渲染新物體時重置;
每個draw call中圖元的索引值,每次新的draw call開始時該索引會重置。
在我們讀取每個像素的索引時實際上我們就將獲取到上面的三級索引數據了。之後我們將對特定的圖元進行相應的處理。
我們需要渲染場景兩次。一次叫做“紋理拾取”,紋理包含圖元索引數據。另一次則直接渲染到實際的顏色緩沖。因此,住渲染循環會有一個拾取的階段和一個渲染階段。
註:這裏的demo中使用的蜘蛛模型來自於Asssimp的資源包。它包含多個VB,可以幫助我們測試這裏的例子。
見原文。
OpenGL著色器中原六仔平臺搭建程序解析--3D拾取