Unity大中華區技術支持團隊近年來爲國內Unity用戶提供了高質量的技術支持服務,本文將由該團隊的技術支持工程師張陳淵,根據本身的豐富經驗,爲你們分享在Unity中實現實時陰影的方法。算法
光照在遊戲做品中的重要地位早已不容忽視,陰影與光的實現技術一直在高效與真實之間左右權衡着。下面主要經過一個具體的問題探討Unity實時陰影的內部實現。app
兩種陰影實現方式優化
Unity有兩種陰影實現方式:烘培陰影與實時陰影。3d
烘培是一種離線計算,它採用光線追蹤算法來模擬現實世界中光的物理特性,如反射,折射及衰減,光沒法到達的地方皆爲陰影;實時陰影是一種更加精簡的模擬,它忽略掉了光的衆多物理特性,利用數學方法人爲地去製造陰影。您能夠經過下圖更形象地瞭解到兩種陰影之間的計算區別。htm
烘焙過程當中,光線沒法到達的地方成爲陰影blog
實時陰影更像人爲地繪製,將燈光角度沒法看到的區域,繪製上陰影的顏色遊戲
烘培陰影是光線追蹤算法的天然產物,準確無誤,真實過渡。但因爲其計算量巨大,阻礙了它在遊戲中的實時運用。不能實時運用並不表明光線追蹤不能應用到遊戲中,實際上游戲中存在大量靜止的物體,如場景中的地形,房屋等,在燈光不變的狀況下,這些物體產生的陰影也是固定不變的。內存
因爲這種需求廣泛存在,Unity的烘焙系統隨之誕生:經過離線計算,生成記錄光照信息的Lightmap,渲染靜態物體時採樣Lightmap,進而產生較真實的陰影效果。對於動態物體而言,Unity使用Shadow Mapping技術,高效地產生實時陰影。因爲篇幅限制,本文咱們主要經過一個具體的問題探討一下Unity實時陰影的內部實現。數學
實時陰影的內部實現it
有企業級客戶提到這樣一個問題:半透明物體的陰影效果是如何實現的?
回答這個問題以前,有必要先了解Unity實現不透明物體陰影的基本原理。爲了簡化問題,假設場景中只有兩個物體,石頭A和地面B。
爲了最快速地分析圖像問題,咱們列舉一下渲染流程:首先,從攝像機角度生成A與B的深度值到Depth Buffer深度緩衝中。
接下來,從燈光視角生成A與B的深度到Shadowmap深度圖,這裏有四張深度圖,能夠認爲是不一樣的精度。
3,4:近視角高精度;1,2:遠視角低精度
而後進入整個流程的核心部分,利用上面兩個步驟的數據生成Screen Space Shadow Mask紋理,基本方法爲:經過深度緩衝可將屏幕空間的點還原到世界空間,而後將此世界空間座標轉換到燈光視角空間,投影以後的Z值再與對應深度圖的值進行比較,若是大於深度圖,說明此屏幕空間上的點是陰影。
最後一步,渲染A和B到Color Buffer顏色緩衝中,將世界空間的點轉換到屏幕空間,採樣Screen Space Shadow Mask紋理得出陰影,最後可根據自定義需求,與材質顏色進行相應的混合得出最終的陰影顯示效果。
那麼,如今開始進入正題了,之因此會有人問半透明物體的陰影如何產生,其根源在於:雖然半透明物體能夠不寫深度緩衝,但必須寫深度圖,那麼半透明物體的深度值如何寫入深度圖呢?
衆所周知,寫深度這一操做,只有兩種方式,寫與不寫:對於不透明的物體來講,深度一直寫;對於半透明的物體來講,假設透明度是alpha,alpha=0不寫,alpha=1寫,那麼alpha=0.5究竟寫仍是不寫呢?
帶着這個問題,讓咱們來看看Unity的標準Shader是如何處理的。
上邊代碼的紅框決定深度是否寫入一張3D紋理,如變量_DitherMaskLOD。設置變量vpos和alpha對3D紋理進行採樣,vpos爲正交或透視投影產生的結果,alpha爲半透明物體對應的alpha值。因爲vpos是變化的,即便alpha都爲0.5,採樣的結果也會不一樣,由此來決定此像素是否剔除。
製做這張3D抖動紋理時必定要保證alpha爲0或1時採樣的結果是固定,alpha大於0.5時,採樣到1的機率偏大,alpha小於0.5時,採樣到0的機率偏大。經過查看內存,此3D紋理可視化後是這樣的:
講到這裏,這個問題的答案已呼之欲出:實時半透明物體陰影與不透明物體陰影在實現上並無太多區別,只是在生成燈光視角的深度圖上,半透明物體在Pixel Shader階段會採樣一張3D抖動紋理,來隨機決定此像素是否輸出,進而產生近似的半透明陰影效果。
這個算法有一個缺點,因爲使用視角數據來採樣抖動紋理,因此當視角變化時,陰影必然會有明顯的抖動。
解決抖動的優化辦法,留給你們去思考。
結束語
關於Unity中實現實時陰影的問題,因爲篇幅有限,本文其實只講到了冰山一角,還有不少其餘的陰影有關的話題,如烘培陰影會使用Shader嗎?它會利用到GPU嗎?咱們會常常分享更多的Unity相關技術剖析在Unity官方中文社區(forum.china.unity3d.com),請保持關注!
轉載請註明來源:Unity官方中文社區(forum.china.unity3d.com)。請勿私自更改任何版權說明信息。
實時陰影
2.png
12.png
13.png