1. 程式人生 > >Unity頂級物理材質的製作之曲面細分

Unity頂級物理材質的製作之曲面細分

曲面細分(Tessellation)已經不是一個陌生的名詞,從DX10時代的Geometry Shading演變而來的線性插值細分頂點,被微軟的圖形工程師認為是“掀起業界風暴的圖形優化技術”,通過線性插值在兩頂點相連的線中中插入數個頂點,將一個網格模型的面數瞬間提高到之前的幾倍。比起單純的使用高模,他的效率可以提高几十倍,在對頂點位置的並行處理方面,CPU執行的網格合批效率是無論如何也無法和顯示卡的流處理器相提並論的,因此,在使用DX11及以上API的大作中,這項技術被大量使用以大幅度提高渲染效能與遊戲畫面。

在一個複雜的場景中,許多模型要求擁有光滑或凹凸不平的表面,這時美工需要輸出大量的高模,高精度的動態模型(如人物)每一幀都會給

CPU帶來災難性的任務量,使用曲面細分可以徹底解決這個問題。Unity已經給我們提供了曲面細分的實現方案,不想深究其原理的開發者可以直接通過編寫Surface Shader來實現曲面細分:

https://docs.unity3d.com/Manual/SL-SurfaceShaderTessellation.html

我們這裡為了保證最高的顯示效能並提供強大的功能,使用了Vertex Hull Domain Fragment Shader, 注意這裡的Vertex函式是針對細分前的頂點,Hull函式負責進行頂點的插值細分,而Domain Shader則相當於每個細分後的頂點的Vertex函式,最後的Fragment函式和普通Shader中的Fragment函式無異。執行順序大致如下:每個模型頂點執行一次Vertex函式,Vertex函式將返回值傳入Hull函式,Hull函式與其分支函式負責將傳入的一個面片通過新增節點切分為數塊,細分後每個頂點(包括原頂點)都會執行一次Domain函式,相當於我們平時寫的Vertex函式。

這裡使用的Shader工作流程與Standard shader基本一致,都擁有對Albedo, Normal, Specular(Gloss), Occlusion, Detail Albedo, Detail Normal等貼圖的支援,同時,在細分曲面方面還有能使表面光滑化的Phong與管理細分頂點位置的Displacement Map:


這個Shader較為複雜,想要深入研究的朋友可以下載自行閱讀原始碼,Shader下載地址:https://pan.baidu.com/s/1eT0zzSu

首先建立一個普通的平面,Shader使用預設的Standard Shader:


Unity預設的平面由100個方形也就是200個三角形組成,從這裡看面數非常稀疏,我們希望獲得一個點數多且細膩的平面,但是頂點的增多無異會給本來並行能力就弱的CPU雪上加霜,所以這裡使用Tessellation Shader:


Shader中已經進行了Editor優化,沒有新增的貼圖不會被計算,phong值設定為0時同樣不會進行外凸計算,這裡我們的測試模型實平面,所以可以將Phong設定為0,然後新增各種貼圖,並且新增一對碎土貼圖用作細節貼圖。然後進行細分頂點位置的調整,首先需要調整的是Vertex Scale,通過改變該值可以改變細分貼圖對頂點位置的影響,其次調整Vertex Offset以防點位置過高,高於原平面的定點位置可能會導致視錐剔除運算錯誤,模型在螢幕邊緣時會直接消失,這裡我們的調整辦法是,將Vertex Offset設定為負數,這時頂點的位置應該要等於或略低於預設平面,這樣整個模型也不會因此特別臃腫(實際製作不一定如此,需要技術美術人員進行嘗試調整以確定最合適的做法),畢竟曲面細分的原則是模擬更多節點,比普通的高模還是要注意很多地方以防止穿幫的。

在本次的Demo中,每兩個頂點之間進行了100次細分,也就是說面數數增加了10000倍,簡簡單單的一張平面就有了200萬個面,如果用這種精度的模型,在一個較為複雜的室內場景中,已經會出現極其嚴重的卡頓甚至直接幻燈片了,而這裡的材質渲染耗時與無細分的PBR Shader相差無幾,由此可見曲面細分技術可以給顯示效能帶來革命性的提高與優化。