基於PCF ShadowMapping 的軟陰影實現

來源:互聯網
上載者:User

這篇文章主要介紹一種極為簡單的軟陰影實現方法。主要方法和PCF的shadowmapping大同小異,只是多了一步screenspace的高斯模糊,從而實現所謂的軟邊陰影。具體方法如下:

首先第一個PASS和傳統的shadow mapping演算法是一樣的,獲得光源空間下的物體最小深度,說白了就是把Camera移動到光源位置,渲染一遍,得到深度圖,這樣得到了情境到光源的最近的深度。如果你用的是DX,那麼你可能需要把深度寫到一個rendertarget裡面,方法如下:

Output.color = float4 ( pos.z / pos.w ,pos.z / pos.w , pos.z / pos.w , 1.0 ) ;

注意這裡的深度並不是Zbuffer裡面的最終的數值,因為它並沒有經過視口變換。它的範圍在-1到1之間。

如果你用的是Opengl,那麼可以方便的通過depth buffer獲得,但是這個值是經過視口變換的,它的範圍在0到1之間。

 

第二個PASS,把Camera拉回到它原來所在的位置。然後正常地渲染情境。常規的shadow mapping做法是把情境每個像素點轉化到光源空間下,與深度圖裡面的值進行比較,如果這個點轉化過去比同樣位置的點深度值大,那麼它肯定在這個點背後,光源是照不到的,因此這個點在陰影之中,反之則在光源照射下。我們可以簡單地這樣處理,如果這個點在陰影中間,那麼這個點最終的顏色要乘以一個0到1的係數,讓它變暗一點,比如0.5。這樣做有一個問題,就是最終產生出來的陰影可能會有鋸齒。:

這是由於陰影貼圖的精度造成的。這個時候PCF應運誕生了,哈哈。說白了就是不光當前像素點去比較,連同周圍的點一起比較,這樣邊緣不會這樣生硬,也不會有明顯的鋸齒,但是實際情況仍然不能令人滿意,因為在不是很大精度的深度貼圖中,PCF會產生令人討厭的馬賽克,:

為瞭解決這個問題,我們再次引入一個PASS,即screen-space的高斯模糊:

我們把第二個PASS產生情境的顏色(不帶陰影)放在一個紋理中,而把陰影的數值放在第二個紋理中。

第三個PASS:我們把第二個紋理,即存放陰影數值的紋理進行高斯模糊,這樣數值的邊緣就不會有很大的梯度,從而漸層到0.

最後一個PASS:把剛才的顏色紋理和高斯模糊後的紋理疊加起來,形成最終的效果:

恩,得到了較為理想的效果。不過screen-space的陰影有它的硬傷,就是它始終是screen-space技術,和情境的距離無關,也就是說情境不管遠景,模糊的尺度都是那麼大,這顯然是不對的,不過在遊戲當中如果稍加避免,就會得到不錯的效果。

希望這篇文章對你有用,如果有什麼疑問,請發郵件到我的郵箱:xingjinanmo@163.com,或者加我的QQ:182322035

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.