在上篇談論完卡通渲染的技術之後,本文我們來探討一下主材質的製作方法。首先還是跟前文一樣,我們來討論一下主材質(Master Material)是什麼,以及它的存在意義。
試想一下,現在你的遊戲裡面有大量屬性不同的物件有不同的材質需要管理,但同時這些材質可以受到某些相同的環境因素影響(如雪的覆蓋、墨水噴灑等等),此時每個材質都分開來寫顯然不是一個很好的解決方案,而採用繼承思想去製作材質顯然會更好一些——正如在寫程式碼時候可以有父類子類一樣,我們製作材質同樣可以用這個思路去做主材質和派生材質。此外,製作主材質同樣可以方便美術使用,保證場景內大部分材質只需要調一調引數就能出需要的效果。
本文預設閱讀者已經能清晰理解材質是什麼,材質與Shader的關係與區別。
上 - 主材質 | 下 - 根據主材質派生出的Material Instance
主材質的製作分析
在本專案中,美術對於材質有以下需求:
可以選用固定色作為diffuse圖
可以選用漸變色作為diffuse圖
可以選用指定圖與固定色的疊加作為diffuse圖
可以不指定normal map,自動生成預設normal圖
允許在diffuse上疊加一層貼花紋理
允許調整整體顏色的明暗
接下來我會依次分析如何實現這些功能。
UE4基礎材質節點
首先我們先看一下基礎的Opaque Material輸出節點含有哪些屬性:
Base Color:基礎色,這裡的輸出色即後續處理中的diffuse color
Metallic、Specular、Roughness:PBR渲染的三個屬性,分別表示金屬度、高光強度、粗糙度,其預設值分別為0、0。5、0。5。
Emissive Color:自發光色,預設為黑色
Normal:材質法向量
注意:Unreal中材質法向量預設為(0,0,1),而不能寫為(0。5, 0。5, 1),我被這裡坑了很久,並不清楚為什麼Unreal是這麼處理的。同樣,法向量貼圖需要選擇Sampler Type為Normal,否則不能得到正確的法向量。
World Position Offset:世界座標偏移,一般是用在頂點形變上面的,這邊我們專案不需要所以就不連東西了。
Ambient Occlusion:環境光遮蔽,一般是用在寫實渲染裡面製作全域性光的,AO我接觸不多,這邊就略過不寫了,有懂的大佬也可以補充一下。
Pixel Depth Offset:一般用來製作Parallax Occlusion用的(如帶深度的磚塊或者石頭,這個比Normal會產生更好的效果),這個也是我Shader寫過但藍圖沒玩過的東西,所以略過。
我們需要給美術定製化的節點主要有Base Color、Metallic、Specular、Roughness、Emissive Color和Normal。
於是最簡單的一版主材質就可以按以下方式製作出來了,其含有可供美術玩耍的Albedo、Normal貼圖替換,以及PBR引數的調整。
使用主材質生成的子材質製作的偏金屬感的“牆”
允許使用者在純色貼圖與紋理貼圖間切換
接下來我們實現一下美術的第一個需求,允許使用固定色作為貼圖色。
這裡介紹一下Unreal中的一個材質節點
StaticSwitchParameter
,使用這個節點可以在材質中讓使用者自由選擇走哪一個分支,從而可以在同一個材質中實現不同的效果。這裡需要注意的是每個StaticSwitchParameter都會造成材質在編譯時生成2種不同的Shader,如果使用StaticSwitchParameter過多,那麼很有可能造成編譯Shader數量爆炸,Draw Call爆炸等多種問題。舉個粒子,如果這個材質存在12個Switch,那麼極端情況下就會編譯出4096個變體出來,得不償失。
使用了Switch Parameter後可我們就能簡單地實現貼圖切換了
可以看到,選擇了AlbedoUsingPureColor後,我們的Vector Parameter多出了一項AlbedoColor,而同時我們也失去了選擇Albedo貼圖的功能,這正是我們想要的效果。
按照這種思路,我們同樣也能製作Normal貼圖的切換方法。
漸變色材質的製作
在本專案中,美術需求要能夠在z軸方向上實現材質的漸變,並且漸變可以挪動位置,以及調整漸變的幅度等等。
先來看一個簡單的漸變色效果實現
接下來開始分析漸變的製作方法:
獲取物件在世界座標上z的範圍,將其對映至0~1的範圍
將顏色對映進行插值
首先是如何獲取物件的z範圍,我們可以在Material中獲取以下值:Absolute World Position、Object Position以及Object Bounds。透過Absolute World Position - Object Position我們就能得到當前畫素點在物件中的相對位置,而透過Object Bounds引數我們能夠得到物件的z方向長度,由此就能將畫素點對映到z軸上的0~1區間。
接下來就是一些數學變換和顏色對映的效果了,在這裡我額外引入了Power函式用於給美術調整對映曲線,以及GradientOffset用於製造顏色偏移。最終的漸變顏色計算圖如下
貼花疊加
貼花疊加的紋理在我們遊戲裡是這樣處理的,由貼花Mask圖與疊加色兩部分組成,最後直接疊加到diffuse色上
下圖為使用貼花的一則例項
最終顏色的亮度調整
在RGB空間裡面直接做亮度的處理顯然不是一個很好的解決思路,這裡我們對顏色的處理轉換到HSV空間中處理。
HSL和HSV都是一種將RGB色彩模型中的點在圓柱座標系中的表示法。這兩種表示法試圖做到比基於笛卡爾座標系的幾何結構RGB更加直觀。
HSV即色相、飽和度、明度(英語:Hue, Saturation, Value),又稱HSB,其中B即英語:Brightness。
色相(H)是色彩的基本屬性,就是平常所說的顏色名稱,如紅色、黃色等。
飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取0-100%的數值。
明度(V),亮度(L),取0-100%。
可以看到,如果我們在HSV空間對顏色處理,那麼只要調整V的值就能實現顏色的亮度偏移。事實上我們同樣能夠實現色相與飽和度的偏移,這裡由於思路是類似的就不展開談了。
於是亮度調整的思路可以由以下流程表示:
RGB Color -> HSV Color -> Modify V value -> RGB Color
在本流程中需要解決的問題就是如何將顏色由RGB空間對映到HSV空間,以及將顏色由HSV空間映射回RGB空間。
在Unreal中存在
RGBtoHSV
節點,然而不存在HSVtoRGB,所以我們需要自己實現一下HSV -> RGB的函式。
這裡我參考了
https://
ferkizue。blogspot。com/2
018/06/hsv-to-rgb-material-function-in-unreal。html
以及
http://
lolengine。net/blog/2013
/07/27/rgb-to-hsv-in-glsl
,將HSVtoRGB的函式實現如下:
最終實現的主材質
上文總結了各個部分製作的細節,這裡展示一下我最終實現的主材質藍圖。
完整藍圖見https://blueprintue。com/blueprint/cj1ezqth/
總結
製作主材質的時候需要多和美術溝通,明晰美術的需求後再製作。起初主材質不一定複雜,但隨著功能的增加主材質會新增越來越多不同的細節,在新增的過程中也需要注意可能造成的冗餘材質編譯的問題。
製作完主材質後也並非一勞永逸了,仍需和美術進行大量的溝通。在本專案中我和美術溝通不夠,就造成了美術將roughness和specular調到不合理值(不僅不在0~1區間,甚至遠遠超出1的範圍)的可能。這一點即使寫了註釋也不一定能夠引起美術的注意,必要時候還是應該直接去和美術對線的。
以上就是我對主材質製作的一點小小經驗分享,歡迎交流提問。那麼下期見~