日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GPU Gems1 - 9 有效的阴影体渲染

發布時間:2023/12/13 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPU Gems1 - 9 有效的阴影体渲染 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這章全面講述了用于實時陰影渲染中常見兩種流派之一的陰影體(Shadow Volumes)技術,又稱模板陰影(Stencil Shadows)技術,重點是得到正確的角度的情形,減少幾何圖形和填充率的消耗。

簡單談談陰影生成技術,目前普遍采用的一般有三種:Planar Shadow、Shadow Mapping和Shadow Volume,前者類似投影,計算最簡單,缺點只能繪制拋射在平面上的陰影;Shadow mapping利用站在光源處所沿光源法線看去所生成的深度圖來檢測場景中的體象素是否處于陰影中,缺點是光源與物體位置相對固定、且在極端情況下計算精度差,不太適合精確到象素的動態光陰場合;Shadow Volume是目前最適合精確表現動態光陰場景的技術,適用性最廣,其典型的適用范例便是Doom 3,不足在于陰影體積引入了額外的頂點和面,加大了存儲和處理強度,同時渲染出的陰影比較硬,如果要實現軟陰影,仍需其他技術配合。

說實話,GEM中這篇文章寫的挺難懂的,我還是以自己的角度,從網上等資料來理解下陰影體渲染。參考的一些文章鏈接如下:

https://blog.csdn.net/jxw167/article/details/65435329

https://blog.csdn.net/wang371372/article/details/41086435

陰影體渲染創建一個陰影體積,并僅在其外部的物體上處理照明,我們將使用模板緩沖區作為算法的關鍵組件, 因此名稱 - ?Stencil Shadow Volume。陰影體積算法背后的想法是將光線減弱時創建的對象輪廓擴展到一個Volume中,然后使用一些簡單的模版操作將該Volume映射到模板緩沖區中。 關鍵的想法是,當一個對象在Volume內(因此在陰影中)時,Volume前面的多邊形會對對象的多邊形進行深度測試,并且該Volume后部的多邊形將失效相同的測試,或者說不參與測試。
我們將根據稱為Depth Fail的方法設置模板操作,人們經常使用更直接的方法稱為Depth Pass來實現陰影體積技術,但是其致命缺點是當視點在陰影中時,會導致模板計數錯誤,而Depth Fail的方法修復了該錯誤。

我們在左下角有一個燈泡,一個綠色的物體(稱為遮擋物體),由于光而投下陰影, 在這個場景中也渲染了三個圓形的對象。 對象B被遮蔽,而A&C不是。 紅色箭頭限定陰影體積的區域(線的虛線部分不是它的一部分)。

我們首先將實際對象(A,B,C和綠色框)渲染到深度緩沖區中(從相機位置觀察的)。 當我們完成后,我們可以獲得最接近的像素的深度。 然后我們一個接一個地遍歷場景中的對象,并為每個對象創建一個陰影體積。 這里的示例僅顯示綠色框的陰影體積,但在完整的應用程序中,我們還將為圓形對象創建Volume,因為它們投射自己的陰影。 陰影體積是通過檢測它的輪廓來創建的并將其擴展到無限遠。 我們使用以下簡單規則將該Volume渲染到模板緩沖區中:

1、如果在渲染陰影體積的背面多邊形時深度測試失敗,我們會增加模板緩沖區中的值。
2、如果在渲染陰影體積的前面多邊形時深度測試失敗,我們會減小模板緩沖區中的值。
3、在深度測試通過,模板測試失敗情況下,我們什么都不做。

讓我們看看使用上述方案的模板緩沖區會發生什么。

物體A:渲染陰影體的背面時深度測試失敗(由于A的阻擋),所以模板緩沖值加1.渲染陰影體的前面時深度測試失敗(由于A的阻擋),所以模板緩沖值減1,所以最后結果是對于物體A,起模板緩沖中的值為0.

物體B:渲染陰影體的背面時深度測試失敗(由于B的阻擋),所以模板緩沖值加1.渲染陰影體的前面時深度測試成功所以最后結果是對于物體B,起模板緩沖中的值為1.

物體C:渲染陰影體的背面時深度測試成功,渲染陰影體的前面時深度測試也成功所以最后結果是對于物體C,起模板緩沖中的值為0.

請注意,到目前為止,我們還沒有碰到色彩緩沖區。 當我們完成上述所有的操作后,我們再次使用標準的照明著色器渲染所有的對象,但是這次我們設置模板測試,使得只有模板值為零的像素才會被渲染。 這意味著只有對象A&C才能使其在屏幕上顯示出來。
讓我們看看如何把這個知識付諸實踐。 正如我們前面所說,我們需要渲染當我們擴展遮擋物的輪廓時創建的體積。 我們所需要做的就是將輪廓邊緣延伸到一個體積中, 這是通過為每個輪廓邊緣從GS發射四(或實際上四角形拓撲中的四個頂點)來完成的。 前兩個頂點來自剪影邊緣,當我們沿著從光照位置到頂點的向量將邊緣頂點延伸到無窮大時,生成其他兩個頂點。 通過延伸到無限遠,我們確保體積捕獲位于陰影路徑中的所有物體。 這個四邊形如下圖所示:
?

?

當我們重復這個從所有輪廓邊緣發射四邊形的過程時,會創建一個體積。 夠了嗎? 當然不。 問題是這個體積看起來像一個沒有蓋子的截錐體。 由于我們的算法依賴于檢查體積的前后三角形的深度測試,所以我們可能會遇到一個情況,即從眼睛到像素的矢量可能沒有通過正面或背面,如下圖這個狀況:

解決這個問題的方法是生成一個在兩邊封閉的體積。 這是通過創建一個正面和后面到體積(上圖中的虛線)完成的。 創建前蓋非常容易。 面向光的每個三角形都成為前蓋的一部分。后蓋需要將面向三角形的光的頂點延伸到無限遠(沿著從矢量到每個頂點)并反轉它們的順序(否則所得到的三角形將指向體積內)。“無限”一詞在這里已經提到過幾次,我們現在需要確切地說明這是什么意思。 看看下面的圖片:

我們看到的是從上面取出的截頭錐體的圖片, 燈泡發出一個穿過點p并繼續無限遠的光線。 換句話說,p擴展到無限遠。 顯然,在無窮遠處,點p的位置是簡單的(無窮大,無窮大,無窮大),但是我們不在乎。 我們需要找到一種光柵化陰影體積的三角形的方法,這意味著我們必須在投影平面上投影其頂點。 實際上這個投影平面是近平面。 雖然p沿著光矢量延伸到無窮遠,但我們仍然可以在近平面上投射它。 這是通過從原點開始的虛線完成的,并在某處穿過光矢量。 我們要找到Xp,它是該矢量穿過近平面的點的X值。

我們將光矢量上的任何點描述為p + vt,其中v是從光源到點p的向量,t是從0到無窮大的標量。 從上圖和三角相似之處可以看出:
?

其中n是近平面的Z值。 隨著t到無窮大,化簡公式如下所示:

所以這就是我們在近平面上如何找到“無限遠”的投影,根據上述我們只需要乘以矢量(Vx,Vy,Vz,0)(其中V是從光源到矢量的點p的向量)來計算通過視圖/投影矩陣并應用透視分割、

?

總結一下 Z-fail算法(John Carmack's Reverse)
1. 先關閉光源,將整個scence渲染一遍,獲得深度值
2. 關閉深度寫,渲染陰影體的背面,深度測試失敗則模板值加1
3. 渲染陰影體的正面,深度測試失敗則模板值減1
4. 最后模板值不為0的面便處于陰影體中,開啟深度寫
5. 用模板手法重新渲染一次加光的scence即可,陰影部分不渲染色度
6. 注意,該算法要求陰影體積是閉合的,即需要前后封口
7. 該方法不是沒有缺陷的,有可能因為Z-far clip plane過近而導致模板計數錯誤

?

陰影體渲染要點總結

  • 輪廓檢測創建陰影體,封閉的面(但是在GEM這篇文章當時,輪廓檢測一般只能運行在cpu中)
  • Z-fail算法模板計數
  • 渲染場景

?

?

總結

以上是生活随笔為你收集整理的GPU Gems1 - 9 有效的阴影体渲染的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。