1. 程式人生 > 其它 >Unity Shader 曲面細分簡介

Unity Shader 曲面細分簡介

目錄

Unity Shader 曲面細分簡介

概念介紹

曲面細分一種對輸入的圖元(三角形、四邊形、線段)進行細化,產生出更多的頂點,使其變得更精細的技術。
這一功能在渲染管線中完成,通常會由顯示卡硬體支援。從階段上講它位於頂點著色器之後,畫素著色器之前。
它的內部流程分為三部分:可程式設計的Hull Shader(控制細分引數),不可程式設計的Generator(細分頂點),可程式設計的Domain Shader(頂點位置計算)。
因此,它基於頂點著色器階段後的頂點資料,並可以控制生成更多的頂點資料交由畫素著色器使用。

作用

曲面細分技術降低了模型精細度要求,在模型製作、儲存、載入上都可帶來節省。
通過曲面細分生成更精細的頂點後,可以應用“置換貼圖”技術來渲染出更加精細、逼真的模型。

置換貼圖不同於法線貼圖修改頂點的法線方向來造成光影錯覺,它會真正修改頂點的位置來產生凹凸感,因此當視線與網格切面方向接近時法線貼圖基本上失效而置換貼圖仍可產生逼真的效果。
例如以下分別是【標準】材質、【未細分僅置換】材質、【固定數目細分置換】材質的效果:

關於Unity支援

unity文件裡只提了Built-in Render Pipeline的Surface Shader支援曲面細分,並且只支援三角形。同時它需要Shader Model 4.6target,因此不支援更老的裝置。

官方案例

在使用Surface Shader的前提下使用曲面細分非常簡單,以下的每種細分方法都提供了內建的函式,直接呼叫就完事。
總的來說是在shader中增加兩個函式:

tessellate:FunctionName
vertex:FunctionName

tessellate宣告的函式返回細分控制引數,這是一個float4型別,前三個值分別表示輸入三角形的三個邊被分成幾段,第四個值是Inside因子,演算法使用,不太清楚。

vertex宣告的函式可以拿到細分後的所有頂點,可以在這裡修改其位置。

例圖:

不細分,僅頂點置換

和上圖不同之處在於,它只聲明瞭vertex函式,未宣告tessellate函式,因此它僅在vertex函式中取樣了置換圖然後修改頂點位置。

固定細分和頂點置換

例圖中就是這個示例,它在tessellate函式中返回了一個固定的細分因子,因此它產生的細分數量是固定的。

基於距離的細分和頂點置換

它的效果就是當物體離相機近時細分增多,當離相機遠時細分減少。

它的tessellate函式略有不同了,多了三個引數。這三個引數就是原三角形的三個頂點,裡面又呼叫了UnityDistanceBasedTess方法,這個方法會計算每個頂點與相機的距離,最終生成細分因子。

基於邊長的細分和頂點置換

上面的其於距離細分只能用於所有三角面都差不多大的情況,否則細分就不均勻。
因此,UnityEdgeLengthBasedTess基於邊長生成細分因子,更大的三角形將細分成更多三角形。

Unity還提供了替代方法UnityEdgeLengthBasedTessCull,它會額外計算相機的可視範圍裁剪,減少參與細分的三角形數量,當網格會有很多部分在視野外時,應使用這個方法。

馮氏曲面細分

這個的效果就是會讓細分後的面向網格法線方向外移一點點,這會使得網格變得更加光滑,因此用於low-poly模型時效果不錯。

這個更簡單了,不需要提供vertex函式而是指定了一個tessphong的float值控制強度,Unity自動完成頂點修改。

更多

雖然文件化的只有Surface Shader,實際上也支援更靈活的頂點\畫素shader,只是需要去看Surface Shader的生成程式碼總結規律。