模板陰影理論概述

 


陰影 體積 平面 模板  前身  深度 

討論使用模板陰影卷的幾種方法,包括每種陰影卷的優點和缺點。


介紹

陰影以前只是一個變暗的紋理,通常是圓形的形狀,它被投射到遊戲中的字符或對象之下的地板上。一個人必須不知情或天真地認爲,我們仍然可以在未來的3D遊戲中擺脫這種粗暴的“黑客”。曾經是一個時間,陰影太貴了,無法實時渲染,但隨着圖形硬件的不斷增加的力量,未能提供適當的陰影不再意味着平庸的實現,它接受犯罪罪未充分利用可用的圖形硬件。

有許多不同的陰影技巧和方法來實施陰影,打下一個“最好的”解決方案是困難的。爲了瞭解所有的方法,欣賞他們的差異,優勢和劣勢,我強烈建議您閱讀任何有關3D影像的內容。我們不應該限制自己只是研究陰影體積技術; 任何影像技術都值得一看。[13]第6章對大多數已知的影像技術進行了精彩的高級別討論。爲了限制本文的範圍,我們將僅討論使用Microsoft的Direct3D API的模板陰影卷的理論和實現問題。這也是很好的理解,模具陰影體積只是不是“結束所有”陰影技術。

     參考遊戲設置,可以在[4]中找到關於不同陰影技術的優勢的討論。剛剛,Eric Lengyel [11]還在Gamasutra網站上提供了一個關於在OpenGL中實現陰影卷的非常完整的文章[17]。Lengyel的文章的數學推導可以在[12]中找到。回溯幾年,有着名的“Cameack On Shadow Volumes”文本文件[6],

     這不僅僅是來自John Carmack的id Software的電子郵件,Nvidia的Mark Kilgard關於深度故障陰影卷的推導實現。有趣的是,卡馬克獨立地發現了深度失敗的方法,而比爾比洛德和麥克·鬆y [7]也提出了類似的陰影卷方法。因此,深度失敗方法現在通常被稱爲“Carmack的反向”。

模具陰影卷概念

弗蘭克·烏鴉[8]首先提出了在1977年使用陰影卷影的想法。Silicon Graphics的Tim Heidmann [5]通過在IRIX GL中狡猾地利用模板緩衝區進行陰影體積計數來實現了Crow的陰影體積。讓我們來看看原始模具陰影卷技術的工作原理。

附加圖片:image001.gif
圖1:遮罩體和陰影體積

按照常規慣例,投射陰影的場景中的任何對象都稱爲封閉器。如上圖1所示,我們有一個簡單的二維視圖(自上而下)的場景,一個球體作爲閉塞器。球體右側的矩形是影子接收器。爲了簡單起見,我們不考慮矩形創建的陰影卷。陰影區域表示由封堵器創建的2D中的陰影體積。陰影體積是將剪影邊緣從光源的視點擠出到有限或無限遠的結果。

附圖:image002.gif
圖2:閉塞器的剪影

圖2示出了從光源的觀察位置產生的球體的可能輪廓。輪廓簡單地由每個由兩個頂點組成的邊緣組成。然後將這些邊沿如源自光源的虛線箭頭所示的方向擠壓。通過擠出剪影邊緣,我們有效地創建了陰影卷。在這個時間點應該注意,陰影體積擠出對於不同的光源是不同的。對於點光源,輪廓邊緣精確地擠出點。對於無限定向光源,輪廓邊緣拉伸到單個點。我們將介紹確定輪廓邊緣和影子卷創建的細節。擠出的大小可以是有限的或無限的。從而,

附加圖片:image003.gif
圖3:深度通孔模板操作

圖3顯示了場景中玩家的衆多可能的觀看方向。箭頭末尾的數字是渲染陰影卷後留在模版緩衝區中的值。具有非零模板值的片段被認爲是陰影。在模板緩衝區中生成值是以下模板操作的結果:

  • 渲染陰影卷的正面。如果深度測試通過,增加模板值,否則不執行任何操作。禁止繪製到幀和深度緩衝區。
  • 渲染陰影卷的背面。如果深度測試通過,減少模板值,否則不執行任何操作。禁止繪製到幀和深度緩衝區。

上述算法也被稱爲深度通過模板陰影卷技術,因爲我們僅在深度測試通過時操縱模板值。深度通常也被稱爲z-pass。

假設在上述模板操作之前,我們已經將對象渲染到幀緩衝區上。這意味着如果您喜歡,深度緩衝區將被設置爲深度測試或z測試的正確值。來自眼睛位置的2個最左側的光線不會影響陰影體積的任何部分(灰色),因此所得到的模板值爲0,這意味着由該兩條光線表示的片段不在陰影中。現在讓我們從左邊跟蹤第三條光線。當我們渲染陰影卷的正面時,深度測試將通過,模板值將增加到1.當我們渲染陰影卷的背面時,深度測試將失敗,因爲陰影卷的背面位於封堵器後面。因此,由該光線表示的片段的模板值保持爲1.這意味着片段處於陰影中,因爲它的模板值不爲零。

陰影卷計數是否適用於多個影子卷?是的,它確實。陰影卷計數是否適用於多個影子卷?是的,它確實。陰影卷計數是否適用於多個影子卷?是的,它確實。

附圖:image004.gif
圖4:多個陰影卷計數

上面的圖4顯示,即使對於多個相交的陰影卷,使用模板緩衝區的計數仍然可以工作。

有限體積無限量

參考圖1,您可以看到陰影體積應該拉伸到無窮大。這實際上並非嚴格要求。我們將陰影體積發送到無限遠,以避免光源非常接近封堵器的尷尬局面。

附加圖片:image005.gif
圖5:有限陰影卷無法影響其他對象

在靠近物體A的光線上,有限的陰影體積可能不足以到達物體B.從眼睛到物體B的射線將以片段模板值0結束,實際上應該是非零!無限陰影卷將確保無論物體對閉塞器的接近程度如何,所產生的陰影卷將覆蓋場景中的所有對象。我們將討論如何將頂點拉伸到無限遠。

Carmack的反向

爲什麼John Carmack,Bill Bilodeau和Mike Songy甚至打擾他們的頭腦,出來一個替代的模板算法,因爲深度傳遞技術似乎很好嗎?深度傳遞真的很好,至少大部分時間。但是當眼睛點進入陰影體積時,所有的地獄都會鬆動。

附圖:image006.gif
圖6:當眼點在陰影卷內時,深度穿孔模板操作失敗

如上圖6所示,當眼點在陰影體積內時,深度通過技術完全失敗。這意味着我們不可能有那麼大的壞角子的收割者從你身後偷偷摸摸,而在他陰影的擴大的黑暗中吞沒你。約翰·卡馬克永遠不會這樣!以下是深度失敗(也稱爲卡馬克反向)算法:

  • 渲染陰影卷的背面。如果深度測試失敗,則增加模板值,否則不執行任何操作。禁止繪製到幀和深度緩衝區。
  • 渲染陰影卷的正面。如果深度測試失敗,減少模板值,否則不執行任何操作。禁止繪製到幀和深度緩衝區。

附圖:image007.gif
圖7:即使眼點在陰影中,深度失敗也能起作用

深度失敗通常也稱爲z-fail。圖7顯示了即使眼點處於陰影中,深度失效技術也能正常工作。如果您考慮眼睛位置在陰影體積之外的場景,則深度失效技術也應該起作用。但是,真的,在某些情況下失敗了。我們將盡快討論這些情況; 只要記住,深度傳遞和深度失敗技術都不完美。事實上,我們需要組合不同的方法來爲影子卷提供強大的解決方案。[11]和[10]包含了一些關於強大的模板陰影體積解決方案的很好的討論。

限制深度失敗

爲了將非零值放入模板緩衝區,深度故障技術取決於渲染陰影卷的失敗“ 相對於眼睛位置的背面。這意味着陰影卷必須是封閉的卷; 陰影體積必須在前端和後端都加蓋(即使後端處於無限遠)。沒有封頂,深度失效技術會產生錯誤的結果。令人驚訝的是,它可能聽起來,但是,即使在無窮大的情況下,也可以遮住陰影體積。

附圖:image008.gif
圖8:卷影陰影體積

如圖8所示,前蓋和後蓋(粗線)創建一個閉合陰影卷。前蓋和後蓋都被認爲是從兩個眼睛位置的背面。使用深度故障模板操作,上限將創建正確的非零模板值。有幾種方法可以創建前蓋和後蓋。Mark Kilgard [2]描述了創建前蓋的一種不尋常的方法。該方法基本上涉及將閉塞器的背面幾何形狀投影到近夾子平面上,並使用這些幾何形狀作爲前蓋。或者,我們可以通過相對於光源重新使用正面三角形來構建前蓋。然後可以將前蓋中使用的幾何形狀擠出,並將其順序顛倒,以產生後蓋。反轉排序是爲了確保後蓋從陰影卷向外。事實上,我們必須始終確保,在我們的例子中,定義整個陰影卷的三角形的圖元是向外的,如圖9所示。必須注意的是,渲染封閉的陰影卷比使用深度傳遞更昂貴陰影體積上限。除了陰影卷的較大的原始數量外,還需要額外的計算資源來計算前蓋和後蓋。我們會盡快詳細介紹一下封影影子的細節。必須注意的是,渲染閉合陰影卷比使用深度傳遞而沒有陰影卷封頂要貴一些。除了陰影卷的較大的原始數量外,還需要額外的計算資源來計算前蓋和後蓋。我們會盡快詳細介紹一下封影影子的細節。必須注意的是,渲染閉合陰影卷比使用深度傳遞而沒有陰影卷封頂要貴一些。除了陰影卷的較大的原始數量外,還需要額外的計算資源來計算前蓋和後蓋。我們會盡快詳細介紹一下封影影子的細節。

附圖:image009.gif
圖9:陰影體積必須向外

把它

放在一起我們來整理我們已經學到的東西,並嘗試在我們處理所討論的技術的所有缺陷之前,提出所有需要的步驟去做模具陰影卷。實施模板陰影卷的步驟的一般列表將是:

  • 使用環境照明和任何其他表面陰影屬性渲染所有對象。渲染不應該依賴於任何特定的光源。確保深度緩衝區被寫入。
  • 從光源開始,清除模板緩衝區,並計算所有封堵器相對於光源的輪廓。
  • 將剪影從光源拉出到有限或無限的距離,以形成陰影卷,並且如果使用深度失效技術,則生成封蓋。(無限陰影體積擠壓並不是強制性的)
  • 使用所選技術渲染陰影卷。深度差或深度失敗。
  • 使用更新的模板緩衝區,執行對應於非零模板值的碎片的照明通道(使其變暗)。
  • 對場景中的所有燈重複步驟2到5。

從上面的步驟列表中,應該顯而易見的是,有更多的燈光意味着有更多的通過,這可以在你的幀率口袋裏燒一個漂亮的洞。事實上,我們必須非常有選擇性地決定哪些燈應用於投射陰影。文章[4]對由多個光源照亮的場景中選擇陰影投射燈進行了很好的討論。想象一下,您的遊戲角色站在體育場的中間,四個巨大的電池照亮了現場。由於4個不同方向的陰影投射,應該至少有4個陰影的遊戲角色在地板上形成十字。在這裏只選擇1個光源將使場景看起來很奇怪。擁有多個燈光可以讓您獲得漂亮逼真的柔和陰影,但還有其他方式可以僞造,而不需要使用多個光源。軟陰影是一個巨大的話題,不在本文的範圍內,所以讓我們從這裏放下吧。經驗法則:始終選擇場景中的主要光源。使用觀察平截頭體來選擇光源可能非常危險,因爲您的頭頂部可能會有一個不錯的巨大的1000兆瓦光子破壞點。這不是在你的視野中,但它將對您將在現場看到的最明顯的陰影負責。只要記住,燈光數量越少,循環次數越多,渲染速度越快,可以節省其他視覺上更重要的效果。所以小心選擇!

從即將推出的Doom3引擎的屏幕截圖,我估計id軟件將限制任何場景中的陰影投射燈的數量,最多可以說是4或5.那麼我們會知道Doom3在明年打架。

剪影確定

構建陰影卷的第一步是確定封堵器的輪廓。模板陰影算法要求閉塞器閉合三角形網格。這意味着模型中的每個邊緣只能由2個三角形共享,因此不允許任何會暴露模型內部的孔。我們只對面向光源的三角形共享的邊緣和麪向遠離光源的另一個三角形感興趣。有很多方法來計算輪廓邊緣,這些方法中的每一個都是CPU週期飢餓的。假設我們正在使用索引的三角形網格。

附圖:image010.gif
圖10:輪廓確定的邊緣消除

圖10示出了由具有一致的逆時針繞組的四個三角形組成的盒子的一側。虛線表示冗餘的內部邊緣,因爲我們只對形成框的輪廓的實線感興趣。冗餘內部邊緣被兩個三角形共享的索引兩次。我們利用這個屬性來提出一種確定輪廓邊緣的簡單方法。

  • 循環遍歷所有模型的三角形
  • 如果三角形面向光源(點積> 0)
  • 將三個邊(一對頂點)插入邊緣堆疊
  • 檢查每個邊緣的上一次發生,或者在堆疊中反向
  • 如果在堆疊中找到邊或反向,則刪除兩個邊
  • 以新的三角形開始

上述算法將確保內部邊緣將最終從堆棧中移除,因爲它們被多於一個三角形索引。

Eric Lengyel [11]提出了另一種輪廓確定算法,利用一致的繞組(逆時針)頂點。該方法需要在模型的所有三角形上進行2遍,以便在三角形對共享的所有邊緣中進行過濾。所得到的邊緣列表然後進行點積運算,以獲得由面向三角形和不面向光的三角形共享的邊。

重要的是要注意,輪廓確定是模具陰影體積執行中兩個最昂貴的操作之一。另一個是陰影卷渲染通過更新模板緩衝區。這兩個領域是積極優化的主要候選者,我們將在本文的結尾部分詳細討論。

生成陰影體積上限

請記住,陰影體積上限僅適用於深度失敗技術。進行陰影體積上限的目的是確保我們的陰影體積關閉,即使在無限遠時也必須關閉陰影體積。有趣的是,點光源和無限定向光源的幾何擠壓是不同的。點光源將拉伸剪影邊緣精確地指向點,而無限定向光源將所有剪影邊緣拉伸到無限遠的單個點。這意味着陰影體積的背封對於無限定向光源來說將是多餘的,因爲它已經關閉。

產生前蓋和後蓋的理想時間將是在輪廓生成期間,因爲我們已經產生了光矢量和邊緣之間的角度。對於前蓋,我們只需要複製所有正面幾何,並使用這些幾何形狀進行擠壓以形成背蓋。請注意,後蓋僅適用於點光源。

附圖:fig1.png
圖11:具有點光源的閉陰影體積

圖11示出了使用不同幾何形狀來關閉陰影體積的兩組圖像。第一行描繪了由正面和背面覆蓋重複使用的幾何形狀的光形成的封閉陰影體積。第二行顯示了一個封閉的陰影體積,前蓋具有重複使用面向封堵器幾何形狀的光和由擠壓輪廓邊緣構成的三角形風扇後蓋。應該使用三角形風扇後蓋,因爲它會導致較少的幾何形狀,因此需要更少的內存和渲染時間。當重複使用封堵器的正面幾何形狀時,我們應該非常小心渲染陰影體積,因爲陰影體積的前蓋幾何體與封堵器的正面幾何形狀物理共面。多數情況下,精確問題將導致陰影卷的前蓋幾何形狀呈現在封堵器前面幾何形狀的前面,導致整個封堵器被吞入其自身的陰影體積。我們可以利用的D3DRS_ZBIAS在Direct3D的標誌D3DRENDERSTATETYPE迫使封堵器的前端面的幾何形狀,它的影子量前蓋的面前呈現。只需在設置渲染狀態時使用D3DRS_ZBIAS標誌(例如pd3dDevice-> SetRenderState(D3DRS_ZBIAS,value))。我們將標誌值設置爲更高的封閉器幾何形狀值,其陰影卷的值越小。這將確保陰影卷的前蓋呈現在封堵器前面幾何的後面。

將幾何擠壓到無窮遠

如前所述,我們需要將輪廓邊緣拉伸到無窮遠,以避免圖5所示的情況,其中有限的陰影體積擠壓不能覆蓋場景中的所有陰影接收器。然而,如果我們能夠確保圖5中的情況從來沒有發生在我們的場景中,那麼將剪影邊緣拉伸到無窮遠是不是必須的。在實際的情況下,一個很大的價值通常是不夠的。

Mark Kilgard [2]介紹了使用均勻座標的w值渲染半無限頂點的技巧。在4D同構座標中,我們用(x,y,z,w)表示一個點或向量,其中w是第四座標。對於點,w等於1.0。對於向量,w等於0.0。均勻符號對於轉換兩個點和向量非常有用。由於翻譯只對點而不是向量有意義,所以w的值在僅轉換點而不是頂點上起重要作用。這可以容易地推斷,因爲變換矩陣的平移值是在任一4 個列或4 根據所述矩陣行慣例。通過將無窮大限制的頂點的w值設置爲0.0,我們將均勻的表示從3D點的變化改爲3D向量。矢量(w = 0.0)在剪輯空間中的渲染將是半無限的。重要的是要注意,我們只能在轉換爲剪輯空間後將w值設置爲0.0。在Direct3D中,這意味着世界的聯合轉型,視圖和投影矩陣。這是因爲當我們將靈活的頂點格式設置爲D3DFVF_XYZRHW時,我們繞過Direct3D的轉換和照明管道。Direct3D假設我們已經轉換並點亮了頂點。理想情況下,幾何的擠出應該在頂點程序中完成,因爲我們已經在頂點着色器中的剪貼空間中工作。事實上,頂點着色器和模板陰影卷是在天堂做的一個匹配。我們將在本文末尾討論在頂點程序中執行陰影卷的好處。

當將幾何體擠出很大的距離或無窮大有助於避免有限陰影體積覆蓋的問題時,它也產生另一個問題。想象一下地牢“第一人稱射擊”(FPS)遊戲中的兩名玩家,在相鄰的房間漫遊,被一塊堅實的磚牆隔開。檯燈在其中一個房間中,其中一個玩家將陰影投射到分隔房間的磚上。另一個房間的玩家將看到檯燈投下的陰影因爲陰影體積被擠出到無限遠。堅實的磚牆突然變得像一塊薄薄的紙,上面有一個“鬼影”。幸運的是,我們可以通過使用遮擋剔除技術剔除陰影投射玩家的頭像來避免這種情況。圖12顯示了一種更爲尷尬的情況,即相機在地形的另一側看到封堵器和封堵器的鬼影。這種情況是非常有可能的,特別是對於飛行模擬或空中作戰遊戲。避免有限陰影體積覆蓋(圖5)和鬼影(圖12)的唯一可能的解決方案是對場景中光源和遮擋物的放置施加限制。

附圖:image015.gif
圖12:由於擠出距離大而產生的鬼影效應

查看平坦度剪輯 - 終極邪惡

現在是時候面對模具陰影卷中最大的邪惡:查看截錐體剪輯。裁剪是任何3D渲染技術的潛在問題,因爲我們依靠3D世界的透視投影視圖。視錐體需要近剪切距離和遠的剪切距離,用於創建近剪輯平面和遠剪輯平面。深度通過和深度失敗技術都受到視錐截面問題的困擾。如圖13所示,深度傳遞技術在與相鄰剪輯平面交叉之後剪切陰影體積時會遇到錯誤。紅色箭頭表示一種情況,由此,由於陰影卷的剪切,關聯片段的模板值將錯誤前臉

附圖:image016.gif
圖13:在靠近剪切平面處剪切的影子體積導致深度通過錯誤

另一方面,深度失敗技術由於使用遠剪輯平面剪切陰影體積而產生錯誤。由於遠剪輯平面距離眼睛位置有一定距離,所以當陰影體積在遠平面處被剪切時,深度失敗技術幾乎肯定會產生錯誤的結果。圖14中的紅色箭頭表示深度失敗技術將產生誤差的情況,因爲陰影體積的背面已經在遠平面處被剪切。

附圖:image017.gif
圖14:在遠剪切平面處剪切的影子體積導致深度錯誤錯誤

我們可以通過調整裁剪平面來解決裁剪問題,但並不總是這樣做。例如,移動近剪切平面將極大地影響深度精度,並可能對使用深度緩衝區的其他操作產生負面影響。

Mark Kilgard [2]提出了一個有趣的想法,即當陰影卷與近剪輯平面相交時,處理兩種可能的情況。這個想法是“遮蓋”近剪輯平面處的陰影體積,以便以前剪切的正面幾何形狀現在可以在近剪輯平面渲染。第一種情況是封閉器輪廓的所有頂點投射到近剪切平面。在這種情況下,從閉塞器輪廓內的所有正面頂點生成四邊形環。然後將四邊形環路投影到近剪輯平面上,從而形成陰影體積的封蓋。

第二種情況發生在只有部分陰影卷投影到近剪輯平面上時。這證明比以前的情況要難得多。爲了他的信用,Kilgard設計了一個精心製作的系統來濾除應該投影到近剪輯平面上的三角形頂點(面向遠離光源),以遮蓋陰影體積。靠近剪切平面處的陰影卷的封頂產生另一個問題:深度精度。靠近剪輯平面的渲染幾何類似於沿着剃刀的邊緣滾動硬幣; 硬幣可以輕鬆地放下兩面。這意味着近平面仍然可以剪切旨在覆蓋陰影卷的頂點。爲了克服這個問題,Kilgard設計出另一種方法,從眼點到近平面構建深度範圍“凸緣”。這個想法是將陰影體積從0.0到1.0的深度範圍渲染,而正常的場景渲染髮生在0.1到1.0的深度範圍內。通過操縱透視投影矩陣,可以將凸起構建成視錐體。一旦到位,陰影卷的近剪輯平面覆蓋的深度值爲0.05,這是邊框的一半。這個想法確實是原創的,但並不能完全解決問題。近平面陰影帽中的裂縫或“孔”非常頻繁地發生,導致錯誤的結果。近剪輯平面問題的結論是確實沒有微不足道的解決方案。至少,在撰寫本文時,沒有知道這個問題的萬無一失的解決方案。這使得深度通過技術非常不希望。

幸運的是,有一個優雅的解決方案來解決深度故障技術的遠距離切割問題。問題的解決辦法就是使用無限透視圖投影或簡單的無限觀察平截頭體。通過將一個遠的平面投影到無限遠,當我們渲染陰影體積時,沒有數學上的機會被遠處的平面剪切。即使陰影體積被擠壓到無限遠,無窮遠的遠處仍然不會夾住它!Eric Lengyel在[11]中介紹了OpenGL透視投影矩陣的數學推導。我們將在這裏處理Direct3D透視投影矩陣。

附圖:image019.gif

(1)

變量:
n:近平面距離
f:遠平面距離
fov w:以弧度表示的水平視野
fov h:以弧度表示的垂直視野

無限遠的平面意味着遠平面距離需要接近¥。因此,當遠平面距離達到無限極限時,我們得到以下透視投影矩陣:

附圖:image021.gif

(2)

公式(2)定義了從近平面到無窮遠的遠平面延伸的透視投影圖。但是,我們是否絕對確定使用4D均勻矢量擠壓到無窮遠的頂點不會被限制在無窮遠處?可悲的是,由於硬件精度有限,我們不能100%確定。實際上,圖形硬件有時產生具有大於1的歸一化z座標的點。然後,這些值被轉換成整數以用於深度緩衝器。由於我們的模板操作完全取決於深度值測試,這將會受到破壞。幸運的是,有這個問題的解決方法。解決方案是將我們的歸一化設備座標的z座標值從[0,1]的範圍映射到[0,1-e],其中e是一個小的正常數。這意味着我們試圖將無限遠點的z座標映射到標準化設備座標中略小於1.0的值。讓Рž是原來的z座標值和𢠞是映射z座標。可以使用下面所示的等式(3)來實現映射:

附圖:image023.gif

(3)

現在,我們利用等式(2)將點A從相機空間(cam)轉換成剪輯空間(剪輯)。請注意,相機空間通常也稱爲眼睛空間。

附圖:image025.gif

哪個會給我們

附圖:image027.gif

(4)

讓我們通過更換因素所需的範圍映射到等式(3)ð Ž附圖:image029.gif 和𢠞附圖:image031.gif :

附圖:image033.gif

(5)

通過使用等式(4)給出的值來簡化方程(5),得到:

附圖:image035.gif

(6)

使用等式(6),我們可以將我們的範圍映射強制到由等式(2)給出的投影矩陣$中,得到以下結果:

附圖:image037.gif

(7)

因此,我們可以使用等式(7)給出的透視投影矩陣,而不用擔心在無限遠處發生的陰影體的遠平面限幅!你可能會想,將視錐體積拉伸到無窮遠是否會影響深度緩衝精度。答案是,它確實影響精度,但是精度的損失真的可以忽略不計。只有在將遠平面擴展到無限遠時,數值範圍的數量損失量附圖:image039.gif 。說我們原來的近夾子飛機是在0.1米,遠的夾子是在100米。該範圍對應於[-1.0,1.0]的深度範圍。然後我們將遠平面距離延伸到無限遠。現在,從0.1米到100米的範圍將對應於[-1,0.999]的深度範圍。從100米到無窮遠的範圍將對應於[0.999,1.0]的深度範圍。深度緩衝精度的損失根本不是很大的影響。nf值之間的差越大,深度緩衝器精度的損失越小。你可以在Eric Lengyel的書中找到上面的推導和許多其他相關的數學推導[12]。應該注意的是,使用無限視角截錐體意味着我們必須繪製更多的幾何。這可能會造成潛在的性能問題。

無限視角平截頭體投影真的只是一個軟件解決方案的遠平面裁剪問題。Mark Kilgard和Cass Everitt [10]提出了一個解決問題的硬件解決方案,而不是使用無限視角截面。較新的圖形硬件現在支持一種稱爲“深度鉗位”的技術。實際上,深度夾緊延伸,NV_depth_clamp特別添加到Nvidia的GeForce3及以上顯卡,以解決陰影卷的遠平面裁剪問題。當活動時,深度夾緊將迫使所有超過遠剪切平面的物體被繪製在具有最大深度值的遠剪切平面處。這意味着我們可以將封閉的陰影體積投影到任意距離,而不用擔心被遠處的平面夾住,因爲硬件將正確處理圖形。通過圖形硬件的自動支持,深度故障陰影卷變得非常容易實現。我們可以將陰影體積擴展到無限遠,同時使用我們的有限視角截面呈現,並且仍然獲得正確的深度失真模板值!那麼權衡是硬件依賴。如果我們希望深度故障陰影卷適用於任何圖形卡(具有模板支持),我們將不得不使用無限視角平截頭體投影而不是深度夾緊擴展。

深度通過或深度失敗

我們已經運行了深度傳遞和深度失敗技術的大多數方法和實現問題,用於執行模板陰影卷。那麼我們應該在遊戲中使用哪種方法?讓我們來看看這兩種技術的利弊。深通 那麼我們應該在遊戲中使用哪種方法?讓我們來看看這兩種技術的利弊。深通 那麼我們應該在遊戲中使用哪種方法?讓我們來看看這兩種技術的利弊。

深通

  • 優點
    • 不需要卷影影子卷
    • 較少的幾何渲染
    • 更快的兩種技術
    • 如果我們忽略近平面限幅問題,更容易實現
    • 不需要無限透視投影
  • 缺點
    • 由於不可靠的近平面限幅問題而不健壯

深度失敗

  • 優點
    • 強大的解決方案,遠距平面裁剪問題可以優雅地解決
  • 缺點
    • 需要封頂才能形成封閉的陰影卷
    • 由於封頂造成更多的幾何圖形

    • 兩種技術較慢
    • 稍微更難實施
    • 需要一個無限的透視投影

看來深度通過是兩者的更好的技術,但是我們必須記住,當我們的相機進入一個陰影卷時,它將完全失敗。直到有一個可行的解決方案爲近平面裁剪問題,如果需要一個穩健的實現,仍然需要深度失敗技術。兩種技術之間的選擇在很大程度上取決於我們正在開發的遊戲的限制。如果需要陰影投射自頂向下或等距視圖遊戲,如暗黑破壞神,深度傳球技術就足夠了。另一方面,對於FPS遊戲,幾乎不可能避免相機進入陰影體的情況。在這種情況下,深度失效技術是唯一可行的解​​決方案。當然,我們也不要忘記其他的影子技術,比如陰影映射。在某些情況下,場景中的陰影腳輪太小,無法顯示任何自我陰影,只需使用投影陰影映射就會更加明智。對於逼真的軟陰影,也可以使用陰影貼圖更便宜地完成。

總的來說,將其他技術與陰影卷結合起來可以實現更好的質量陰影。這種混合實現的一個例子是Power Render X [16]遊戲引擎,它使用陰影卷生成陰影,然後通過使用投影紋理相對於與封閉器的距離淡出陰影。流行語:魯棒性和效率在過去10年中,玩遊戲的複雜性激增,遊戲中現實和準確的陰影已經不夠了。我們需要提供強大且高效的模板陰影卷實現。在魯棒性的情況下,使用深度失敗技術足以滿足幾乎任何可想象的情況。然而,硬件限制和較差的幀速率有時會將深度失敗技術推廣到我們的計算預算之外。有很多方法可以優化我們的影子卷執行,以創建漂亮的陰影,並將幀速率保持在所有重要的20fps基準之上。模板陰影體積實現中的真正瓶頸是輪廓確定和陰影體積渲染。

     前者需要大量的CPU週期,如果遮罩體具有高多邊形數量,則會惡化。

    後者是無形填充率的巨大消費者。在剪影確定期間減輕CPU緊張的一個明顯方法是使用閉塞器的下多邊形模型。另一個有效的方法是每2-4幀確定一個新的輪廓。這是基於假設光的位置或封堵器的位置在2-4幀內不會非常顯着地改變。這個假設在大多數情況下都是相當不錯的。請記住,在深度故障技術中用於形成封閉陰影卷的額外封頂幾何形狀有助於深度失敗是更昂貴的方法?我們可以大大減少封堵器的封蓋幾何形狀,這些遮蓋物在經常面向光源的表面上具有相對較少的細節。這裏的細節意味着更少的幾何細節,這意味着表面相當平坦,並且通常產生接近或完全凸起的輪廓外殼。如果是這種情況,我們經常可以創建一個三角形條,用作前蓋來關閉陰影卷。我們應該注意到,這是一個近似值,因此會導致在某些角度不正確的陰影。然而,這種近似值對於小物體應該是非常好的。對於Direct3D實現,建議使用“焊接”網格。焊接網格只是意味着沒有重複的頂點代表完全相同的點。要查看“未焊接”網格的示例,請打開網格查看器工具並創建多維數據集。查看多維數據集的頂點信息,您將看到有24個而不是8個頂點。這是不可避免的,因爲Direct3D' 頂點的s版本包含不同的臉部共享的顏色和正常信息,指的是同一點; 因此爲不同的面產生額外的頂點。額外的頂點是多餘的,但在輪廓計算期間不能被移除,而沒有相當多的比較工作。因此,使用焊接網格來確定輪廓是比較明智​​的。

      Direct3D網格瀏覽器實用程序提供了一個漂亮的選項來做到這一點。點擊MeshOps然後焊接頂點,在焊接之前檢查去除背靠背三角形,重新生成鄰接和焊接所有頂點。或者,我們也可以使用網格函數D3DXWeldVertices來焊接網格。關於無形填充率,他們真的是不可避免的。但是,在渲染陰影卷之前,可以通過在Direct3D 中設置D3DRS_COLORWRITEENABLE渲染狀態來減輕影響。我們可以使用它來關閉紅色,綠色,藍色和Alpha通道繪圖,因爲我們只想填充模板緩衝區。我們應該注意的另一個領域是在3D場景中管理陰影投射燈。光源的良好管理將不斷有益於陰影體積生成過程。經驗法則是在任何一個時間將影子投射光源的數量保持在最大值4以下。未來的硬件或改進的算法將使先前的語句無效,但是現在它作爲一個很好的指導方針,至少可能在未來的兩年內保持下去。光源管理的重要方面是用於選擇哪些光源應該包含在陰影卷生成過程中的方法。應考慮的主要參數可能是強度,與觀衆的距離,與當前遊戲的相關性,以及最後的視覺重要性。看看查爾斯布魯姆關於選擇影子投射光源的優秀文章[4]。讓我們來討論一些我們可以採用的高級優化,以進一步加快我們的影子量的遊戲。當我們確定相機不在任何陰影卷中時,我們實際上可以利用深度傳遞技術。這可以通過形成近剪輯體積而相當容易地完成。光源的位置和近平面的四邊用於定義金字塔。近平面關閉金字塔,從而形成近剪輯體積。如果閉塞器完全位於該體積之外,我們可以安全地使用深度通過技術,因爲封堵器的陰影體積沒有與近平面相交的機會。Eric Lengyel還描述了使用OpenGL剪刀矩形支持來減少渲染陰影卷和照明碎片的填充率損失。然而,DirectX 8.1中尚未提供全面的高級剪刀矩形支持。有關這兩個優化的詳細信息,請參閱[11]。最後,我們應該積極利用任何可用的硬件支持。未來的GPU將被期望支持雙面模板測試,這將使我們能夠將陰影卷的正面和背面呈現在一起。當通過將幾何設置成本,頂點轉換成本和幾何傳輸成本減半來渲染陰影卷時,這將大大節省,因爲我們只需要將影子體積幾何圖形推送一次。硬件將在同一套幾何形狀上進行兩次模擬過程時自動清理前臉和後臉。還應使用硬件深度夾持支持,將陰影體積幾何尺寸剪切到遠處,無需額外費用。最後,讓我們來看一下最重要的現代圖形硬件功能,我們應該充分利用這些功能: 頂點着色器

       陰影卷由頂點着色器提供在商業圖形硬件的整體改進之中,可編程頂點處理流水線(頂點着色器)的引入可能是任何實現陰影卷的最好的事情。在頂點程序中執行陰影卷的最大優點是,無論何時生成陰影卷幾何,都不需要上傳它們。整個陰影卷可以作爲靜態頂點緩衝區駐留在硬件內存上。保存的數據帶寬可能相當大。此外,在可編程頂點硬件中完成的浮點運算非常快。但是,我們需要注意的是,使用頂點程序實現影子卷可能會在某些情況下降低性能。我們將在本節結尾處進一步說明。爲了利用頂點着色器的力量,我們需要首先對封堵器的幾何體進行預處理。當前的頂點着色器硬件不具備生成新頂點的能力。它是嚴格的1頂點和1頂點輸出管道。這造成了一個問題,因爲我們需要從輪廓邊緣創建新的頂點,以形成陰影卷。

     解決方案是創建預處理期間所需的所有附加頂點。一旦在頂點着色器中,我們使用這些附加頂點生成陰影卷。讓我們看看如何做到這一點。我們需要爲正好2個面共享的每個邊(2個頂點)創建一個四邊形。四邊形可以看作是由兩個不同的面共享的原始邊緣形成的“退化”四邊形。這兩個面都與退化四邊形有着相同的邊緣。由於兩個面的邊緣是相似的,所以位置上,簡併四邊形是“零長度”。唯一的區別是邊緣保持其各自面部的正常信息。

        一旦在頂點程序中,我們點亮光矢量和頂點法線。如果結果爲正,頂點將通過頂點程序。如果結果是負的,我們將它沿着光矢量的方向拉伸。這種技術將優雅地產生一個閉合的陰影體積,因爲面向幾何的幾何形狀保持不變以形成前蓋,而面向遠離光的幾何形狀被擠出以形成陰影體積和背蓋的側面。如果您不確定它是如何工作的,請嘗試此示例。想象一下,在其左側有一個點光源的球形網格。整個左半球面對光線,因此限定左半球的所有幾何形狀保持不變,以形成前蓋。整個右半球卻遠離光線。因此,限定右半球的所有幾何形狀都被擠壓形成後蓋。陰影體積的側面由沿着輪廓邊緣的退化四邊形自動神奇地形成。在這種情況下,剪影邊緣在球體的中間正好形成一條垂直線。這樣做是因爲剪切邊緣的每個退化四邊形正好是1個邊。

       之前的退化四邊形現在變成了定義陰影體積側的正常四邊形。Chris Brennan在[15]中提出了一個關於在頂點程序中實現陰影卷的擠壓的簡短文章。我們應該注意到,預處理需要創建大量額外的幾何。事實上,只有沿剪影邊緣的退化四邊形是有用的。其餘的只是休眠,但仍在推動通過處理管道。然而,現在可以在圖形硬件上完全完成陰影卷生成,並且在大多數情況下,性能通常要好於非着色器實現。Mark Kilgard最近指出,如果封閉器具有高多邊形數量或投射光源的陰影很多,則計算頂點着色器中的剪影邊緣可能會對性能造成不利影響。由於我們需要將更多的頂點推入管道,所有這些都必須通過頂點着色器中的輪廓邊緣測試,這個評估是嚴格的。

     因此,具有高多邊形數量的封堵器將產生大量的浪費頂點(退化四邊形),並且測試所有這些額外頂點的成本可能無法覆蓋使用頂點着色器獲得的幾何上傳節省!更多的光源將進一步惡化這種頂點着色器的實現。因此,可以對可編程頂點硬件上的陰影體積進行徹底的測試,以確保我們在使用CPU時實現了超過實現的淨性能提升。如果需要CPU用於重AI或遊戲邏輯計算,則影子卷的頂點着色器實現可能會更有效。然而,在許多情況下,也可以使用頂點着色器作爲輔助,而不是嘗試在頂點着色器中執行所有操作。故事的道德是: 永遠記得在遊戲中打開一切(AI,物理,聲音,輸入,網絡,渲染器等)並再次進行基準測試和基準測試。最後,關於模具陰影卷技術的更廣泛和深入的文章將在即將出版的書籍ShaderX2(www.shaderx2.com)中提供。

      本書中的文章深入瞭解模具陰影卷中涉及的算法,詳細討論了商業3D引擎中優化,工作流程和場景管理以及“祕籍”,以加速強大的陰影卷實施。還將有6個廣泛的樣品覆蓋正常的CPU,使用新的高級着色器語言(DirectX9.0)進行彙編和GPU實現中的GPU實現。這本書是在現場工作的專業人士和工程師的許多先進的着色器技術的彙編。它將在2003年8月份可用,編輯是沃爾夫岡恩格爾先生。陰影卷在工作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章