混合Nnormal map 的方法-使用RNM 演算法 (Reoriented Normal Mapping in Unity )





Normal map 出現之後就很快地應用載客種CG領域的材質表現上,但同時需要使用多張不同的Normal map 的問題也隨之產生,而因為Normal map 的獨特性,使用傳統的方式混合常常出現越是混合細節越是被掩蓋的問題,無論在Photoshop 中靠視覺土法煉鋼還是寫成論文作為專門的方式發表,現在已經有許多成熟的混合方式。

本篇介紹的是RNM 方式的混合,相關文獻可以在這裡看到:
http://blog.selfshadow.com/publications/blending-in-detail/

本篇直接使用其中的算法透過Shader 希望可以在Unity 中實現。

以下是結果與一些比較。

這是單獨貼上 兩張不同Nromal 的結果:


左邊是類似鵝卵石的法向量資訊, 右邊則是粗糙類似沙地的表面紋理。

接著使用一些方式讓兩張Normal混合

這裡並沒有測試所有算法,使透過Photoshop 疊合,以及Unity 中內建之PBR 的材質來做比較。


疊合比較圖

左邊是Photoshop 直接  Overlap 的結果,基本上這樣的混合方式會讓Normal 越疊細節越少。


中間是使用Unity 5.0 PBR 的材質 通道,Normal 貼上Base Normal ,Detail 的Normal 則貼上希望作為表面細節的 Normal map。


原本以為Unity 的PBR 中Secondary map 的法線通道部分八成也是使用RNM 的算法,但不知道為何,我使用這兩張Normal 結合時並沒有呈現出我預期的結果。


而是接近於Photoshop 中直接使用兩張圖片Overlap 的結果。




以下是這兩種方法的特寫圖



簡單地檢視並看不出特別的差異,這結果也算是預料之外。

於是我順手作了 比較經典的Base Normal Map + Detail Normal 至Unity 的Shader 中。


左邊是Detail Normal 右邊為Base Normal Map

結果:


出現正常的結果了,我沒有查詢到Unity 使用的是哪種混合方式,但看來內建Shader 提供的方法不是很好地混合兩張有較多紋理的法線資訊。

接著 回到剛剛的兩張法線圖,這是我基於RNM 算法在做一些個人喜歡地小修改後的結果。

 
成功出現了我希望的兩張法線疊合的結果。

但這三種方法的材質 基本色我都設定為中間灰色128

但可以看出每個算法因為對法線資訊的修改會造成顏色通道的資訊減益,這部分可能需要再針對顏色通道做補正調整。

簡單地說明一下我的疊合方式:

RNM 
float3 t = tex2D(texBase, uv).xyz*float3( 2, 2, 2) + float3(-1, -1, 0);
float3 u = tex2D(texDetail, uv).xyz*float3(-2, -2, 2) + float3( 1, 1, -1); float3 r = t*dot(t, u)/t.z - u; return r*0.5 + 0.5;



這邊我針對 最後

float3 r = t*dot(t, u)/t.z - u; 的部分做了一些修改


在- vectror3 u 之前我先針對 前方結果做了1-X ,在-u


另外 最後我也做了變數 控制最後結果是要使用加法或是減法


可以看到不同算法 呈現的不同結果:






A-B 減法 細節的法線資訊較為強烈






A+B加法 基本法線資訊較強烈

我自己的Shader 也做了參數給不同情況調整:




留言