2010/10/13

Normal Map 法線貼圖 (一)

這裡翻譯/整理了幾篇關於Normal Map的文章. 因為字數太多所以分成三篇刊登. 希望對大家有幫助.


----以下為翻譯文----
原文請點以下連結

標題: 法線貼圖
翻譯: Hammer Chen

什麼是法線貼圖(Normal Map)
法線貼圖常常用在低解析度模型,偽裝出高解析度的模型細節表現。法線貼圖的每個像素儲存了法線,法線就是一種向量,紀錄了高解析度模型的表面斜度。紅色、綠色、藍色通道分別控制了每個像素的方向。

當你把法線貼圖到用到低解析度模型,法線貼圖上面的像素會控制了低階析度模型的向量,造成了模型表面更多細節的假象。然而,從側面來看,模型本身並沒有改變。

貼了normal map的低模
沒有貼normal map的低模
高模


切線空間(Tangent-Space)vs 物件空間(Object-Space)
有兩種法線貼圖,一種是切線空間,另外一種是物件空間。物件空間也被稱做是區域空間,或是模型空間。世界空間基本上跟物件空間是一樣的,只是世界空間需要模型維持他原始的轉向,不改變旋轉或是變形,因此世界空間這類型的法線貼圖很少使用。

切線空間的法線貼圖(Tangent-space normal map)
如上圖, 主要會是藍色的,物件可以移動,或是變形。很適合用在變形物件。例如角色、動物、旗子…等等。
  • 貼圖可以很容易被重複使用,例如不同形狀的模型。
  • 貼圖也可以很容易做重複貼圖tiled,鏡像也很容易。雖然有些遊戲引擎對鏡像normal不是很支援。
  • 很容易用疊合的方式繪製細節。
  • 很容易進行影像壓縮。
  • 但是比較難避免來自低模 vertex normals 的smoothing的問題 。
物件空間的法線貼圖(Object-space normal map)
如上圖, 顏色是彩色的,物件能被旋轉,但是不能有變形,除非修改shader讓它支援可變形的法線貼圖。
  • 很容易產生高品質的曲率,因為它完全忽略了低解析度模型粗糙的smoothing。
  • 效能上比切線空間的貼圖要好,但是沒有差非常多。
  • 很難重複利用,不同的模型需要不同的貼圖。
  • 很難做tile,鏡像也需要特殊的shader支援。
  • 很難以圖層疊加的方式來添加細節,繪製的細節必須要先轉換成物件空間,才能正確地與物件空間的法線貼圖疊合。
  • 圖片壓縮效果不好,因為藍色通道很難像切線空間的貼圖一樣,在shader裡面重現,而且三個色彩通到包含了非常不同的資料,很難做壓縮。如果壓縮的話會產生很多的雜點,建議使用一半解析度的物件空間貼圖解決這個問題。
不同類型的法線貼圖之間的轉換
法線貼圖可以由切線空間轉換成物件空間,反之亦然 。

Diogo "fozi" Teixeira先生寫了一個工具叫做--- NSpace。它可以把物件空間的法線貼圖轉換成切線空間,在3ds max可以完美地運作。它利用3ds Max的硬體shader,相同的切線基礎來做轉換。為了要看到結果,透過Normal Bump map 載入翻轉的貼圖,勾選"Show Hardware Map in Viewport"。Osman "osman" Tsjardiwal先生它寫了NSpace的使用者介面,你可以到這裡下載,只需要把這個跟NSpace exe放在同一個資料夾即可。Diogo先生還想替這個工具添加更多功能。

Joe "EarthQuake" Wilson先生說,8Monkey Labs 有個工具讓你載入參考模型與物件空間貼圖,然後載入切線空間的法線貼圖,調整tile的數值,我們必須要載入模型才能知道切線法線的方向是否有誤。大部分的狀況是可運作的,但是常常會扭曲法線,因此你必須要把模型切成某種smoothing groups,然後才執行這個程式。然後我們才會合成這個混合的材質,套用在我Photoshop的原始圖上面。

RGB通道
Shaders可以利用不同的技術來渲染切線空間法線貼圖,但是法線貼圖的方向通常是在遊戲裡面組成的,通常紅色通道儲存了X軸 (通常是向左或是向右),綠色通儲存 Y軸(向上或是向下),藍色通道儲存Z軸 (方向是自表面往外)。

切線空間法線貼圖的紅、綠、藍通道

如果你發現光源角度錯誤,可能是因為法線貼圖所指的方向,紅色或是藍色,指到了相反的方向。為了要修正錯誤,你可以改shader或是很簡單地把相對應的顏色通道翻轉,因此黑色的pixel變成白的,或是白的變成黑的。

有些shader 預期顏色通道會換,或是重整。為了要支援特殊的壓縮格式,例如DXT5_nm通常會認為X軸在akpha通道 Y在綠色通道,紅色與藍色是空的。

切線基礎(Tangent Basis)
切線空間的法線貼圖是一種特別的頂點資料,稱為切線基礎tangent basis。這跟UV座標很類似,差別在於切線基礎提供了模型表面的方向性。它組成了相對於表面的座標系統,這個座標系統是以每個pixel的法線為基礎儲存在法線貼圖裡面。

光線 Light rays是位於世界空間,但是法線儲存在法線貼圖裡,用的是切線空間 。當有貼normal-map的模型被渲染出來,光線必須要從世界空間切換成切線空間,這個轉換要透過切線基礎tangent basis。而射入的光線會跟法線貼圖裡面的法現做比較,這會決定每個pixel的模型要怎樣被光線照明。有時候,有些shader不轉換光線,但是轉換法線貼圖裡面的法線。由切線座標轉換成世界座標,然後世界座標的法線會跟光線做比較,來決定模型是否被照明。要用怎樣的方法取決於你怎樣寫shader,但可得到相同的結果

不幸的是,對美術來說,有很多方法能計算切線基礎(tangent basis)。3ds Max、Maya、DirectX 9、NVMeshMender、 Eric Lengyel等等方法。這表示用不同方法做出來的法線貼圖,可能沒辦法在其它的應用程式裡面正確地被渲染。美術必須要做點測試,才能知道怎樣的參數最好,當算圖引擎或是遊戲引擎,渲染你的模型時,shader必須要跟你的法線貼圖產生器採用相同的切線基礎。否則,你會得到不正確的照明,尤其是在跨過UV的縫隙的地方。

xNormal SDK支援自訂義的切線基礎,當程式設計師使用xNormal SDK,把它導入到算圖引擎自己的切線基礎,美術使用Xnormal去做bake 法線貼圖,就能夠與算圖引擎完全地配合了。

在低解析度模型上面的UVs與vertex normals會直接影響到切線空間的法線貼圖的顏色,每個切線基礎的vertex都是由三個屬性結合的:mesh vertex的法線,受到smoothing影響、vertex的切線,通常是根據V軸貼圖座標而來、還有vertex的雙向切線,根據程式碼而來,通常稱為雙向法線binormal。這三個向量會對每個vertex產生一個軸,產生一個特定的切線空間的轉向,這些軸會被用在當被光線照射到的時候,由世界空間到切線空間產生適當轉換。因此,你貼法線貼圖的模型才能表現出正確的光照。

當三角的vertex法線是垂直往外的,那張法線貼圖的pixel顏色會呈現中性藍(128,128,255),這表示pixel的法線會直接由低階析度的模型表面垂直地指向外面。當pixel 法線是往左或是右偏移,它的顏色可能會比較紅,或是比較不紅,但是這要取決於法線貼圖是怎樣儲存x軸的資料的,是定義成正的,還是負的。同理,當法線是往上或是往下偏,顏色會呈現的比較綠或是比較不綠,如果vertex normal不是完全跟三角面垂直的話,法線貼圖的pixel一定會被染上顏色,而不是單純的中性藍。vertex normals與法線貼圖裡面的pixel normals最後會結合起來,構成最終的per-pixel surface normals。

Shaders的功能是利用法線貼圖裡面X Y軸資訊來控制方向 大部分的應用程式定義紅色向右是 +X,綠色向上+Y。但是3DSMAX是定義+X、-Y。這就是為什麼常常會需要翻轉綠色通道,才能得到正確的最後結果, 因為shader會定義特定的方向。

當模型上的共用邊,是在UV空間上有不同的角度,在邊縫的地方就會以不同顏色呈現,切線基礎會利用這個顏色來對模型做照明。

當你查看角色的切線空間的法線貼圖,通常會在UV邊縫的地方看到不一致的顏色。這是因為UV shell通常會在mesh上面有不同的朝向,這是由3D模型轉成2D貼圖的必要之惡。角色身體的部分可能是垂直的shell,而手臂可能是水平的。因此在法線貼圖上面的法線必須要扭轉這兩個不同朝向的UV shell,切線基礎能夠重新轉向 (扭轉)光源。當光線射入到模型表面的區域空間時,當光照照應這個邊縫時,看起來會很平順。

當美術對模型的切線空間法線貼圖進行tile時,例如地形,結果通常是正確的,因為模型具有統一的切線空間方向。如果模型具有連續的UV座標,或者法線貼圖有很大的方向漸層,那切線空間就不會是統一的,因此地形表面可能會出線邊縫。

低模(Low-Poly)的建模
遊戲模型必須要很小心的最佳化,產生美麗的剪影,刻劃出比較好的edge-loops。 這樣對變形的時候比較好,最小化極端的vertex normal改變。這樣才能具有更好的shading。

為了要產生最佳化的遊戲模型,例如好的剪影、好的loops產生好的變行動化。你可以添加第二級的subD細分,然後進行數位雕塑;或是直接用low-poly模型開始改,接著把edge loops塌陷掉,或是切出新的邊、添加細節、或者你可以重新進行拓普。

UV座標
法線貼圖烘培工具只會捕捉到在0-1 UV範圍的法線,因此超出範圍的會被忽略。

面向前的UV只有一份會在baking時後計算,如果你的mesh使用重疊的UV,會產生錯誤,因此在烘培之前,最好移除重疊的UV。

對稱的UV (紅色部分), 在烘培前偏移一個單位

如果你移除重疊的UV,然後鏡像,最後產生的結果會一樣。當然也可以不要鏡像,對大部分的遊戲引擎都沒差,但是小心ZBrush使用UV偏移來管理模型的可視度,但是其實這也沒太大差別。因為ZBrush cage mesh通常是跟遊戲裡面要做烘培的材質是不同的。

必須要避免在烘培法線貼圖後改變UVs,因為旋轉或是鏡像UV,會造成法線貼圖無法跟切線基礎對應上去,這會產生光照的問題。

在3ds max裡面,W是第三個材質座標。會被用在3D程序性材質,並且會儲存UV通道裡面的vertex color (你需要RGB的3軸,因此UVW可以儲存vertex color) 。 烘培問題可以把移動重疊的UV,沿著W軸移動到-1。這跟把重疊的部分在U或是V移動一個單位意思是一樣的。Render To Texture這套工具總是會對W軸上面最高的UV進行烘培,然後利用W烘培可能會產生問題,因為這個東西通常是隱藏的,除非你可以地查看它,這對團隊工作並不好。而且這個數值不會在輸出的時候儲存,高的W數值也可能會讓UVs不好選取或是焊接。

鏡像(Mirroring)
法線貼圖能夠用鏡像的方式處理,產生對稱的細節,這樣可以節省UV空間。這樣可以讓你在法線貼圖裡面放置更多的細節,因為模型上的texture pixels變得更細緻了!

如果是採用物件空間的貼圖,鏡像的法線貼圖需要特殊的shader支援。如果切線貼圖。鏡像通常會產生shading縫隙,但是這個縫隙可以被減小或者隱藏,取決於你用的方法。

標準的鏡像工作流程
  1. 把模型一半刪除
  2. 整理剩下的模型的UVs,讓它充滿整個UV空間。
  3. 從鏡像模型產生完整的模型,在邊縫的區域把vertex焊接起來。
  4. 移動鏡像的UV整整一個單位。
  5. 烘培法線貼圖
烘培法線貼圖
有時候,美術會想要在烘培之前刪除模型對稱的那一半 。

這樣做是錯的,因為常常沿著切面開口的vertex normals會朝向開口處 而另外一面也沒有模型可以平均化這個法線 這樣會在法線貼圖上產生明顯的光線縫隙

最好的做法是用完全對稱的模型來進行法線貼圖的烘培,不要只用一半的模型。

避免對稱的UV產生重疊或是烘培錯誤,把對稱的UV移動到0-1 UV空間之外。 因此只有一個非對稱的UV在0-1範圍內。

為了要避免texel在UV shell之間洩漏出來,請確認每個shell有足夠的留邊,包含延著法線貼圖的邊,每個UV shell都不應該在0-1UV範圍內碰到彼此,除非你想要在貼圖上呈現tile的效果。

這裡再舉另外一個例子, 模型的一半先拆好UV 然後用Symmetry做對稱. (原文取自這裡)

這時候選取模型的左半部, 把左半部的UV 移到0-1的UV空間之外, 因為我們不希望因為對稱的UV相疊而重複計算法線貼圖

當我們用高模來產生法線貼圖時, 左側的法線貼圖的結果是正確的

法線貼圖是利用RGB值來讓低模產生變形的效果. 在模型的右側, 計算出來的法線貼圖一定是正確的因為法線貼圖就是根據高模的右側來產生的. 但是對於模型的左側 計算出來的反線是相反方線, 因為左側的模型是以symmetry產生的; 因此, 當法線會讓模型往外凸時 左側的模型照裡來說應該會往內凹(相反方向), 可是因為左側的UV其實跟左側模型正好是相反的, 因此負負的正, 最後的結果讓兩側的模型貼上法線貼圖 效果是正確的 .

遊戲裡面的效果是正確的.

中央對稱(鏡像)
如果鏡像的縫是在連續的模型表面上,例如人臉的中央,這可能就會產生光照縫

Epic Games的Unreal Engine 3 (UE3) 它們的對稱模型通常就是採用中央對稱 。 Epic的做法是利用另外一個法線貼圖做為細節貼圖DetailMap。這可以把鏡像的縫隙,diffuse/specular的光照分散開來。而光照模型的話,Epic有一種技術可以幾乎把鏡像縫完全消除。

左圖的detail normal map細節法線貼圖能夠把右圖的縫隙, 巧妙地隱藏起來

偏移對稱(Offset Mirroring)
偏移對稱是一種方法,這樣讓你的縫隙不會出現在正中央,例如角色的頭。UV縫可以放在耳朵。從那個地方產生UV縫。

這可以避免羅夏效應(Rorschach)。因此可以產生非對稱的細節,但還是可以節省空間,因為頭的兩側還是可以對稱,但是對稱面不會同時被看到。

鏡像偏移不會把邊縫移除,但是可以把縫隙移到比較不明顯的位置。

平色鏡像(Flat Color Mirroring)
這裡教你怎樣用手繪的方式把鏡像的切線空間法線。用手繪的方式塗上平色的法線,用的是中性藍,但是這只能用在垂直或是水平的UV縫,不能用在任意角度的UV縫,這樣可以移除沿著鏡像的縫隙。

元件對稱(Element Mirroring)
對稱的縫可以完全地避掉,如果你在對稱中心不放置模型的話。例如,如果你把一個detached的模型放在中心的位置,這個模型就可以獨立地設定貼圖,而兩側的模型還是可以進行對稱,不論對稱的模型是否共用vertex normals。有了非對稱的元件,就不會出現任何的縫了。

望遠鏡中間的元件,以紅色顯示。是一個獨立的非對稱UV,讓整個模型對稱但是完全不會有縫隙。

Smoothing Groups 與硬邊
每個模型上面的每個vertex都至少有一個vertex normal。vertex normal會用在控制三角面的方向,控制光照個結果。如果法線是朝向光線,那三角面就會被完全地照明;如果背對光線,那三角面就不會被照明。

但是每個Vertex,能夠有超過一個vertex normal。當共用邊的兩個三角面有不同的vertex normals時,會產生shading縫隙,稱之為模型的硬邊(hard edge)。3ds Max的Smoothing Groups能夠產生硬邊與軟邊,Maya則是利用 Harden Edge與 Soften Edge來控制。這些工具都能產生硬邊與軟邊,經由分裂或是合併vertex normals。

硬邊會在vertices產生多個法線

當模型完全地使用軟法線 (單一個smoothing group),光線會對差異極大的vertex normals進行內插。如果你的算圖引擎跟烘培器(baker)不使用相同的切線基礎的話,會產生shading錯誤,所以要儘量避免極端的vertex normals差異,才能避免這個問題。

硬邊對於模型本來就有的縫是最好的。例如,你可以沿著車胎的框添加硬邊,避免輪胎模型扭曲車體。機械性的模型通常會使用硬邊 。
對大部分的模型,最好是在UV縫的地方添加硬邊,這個沒有絕對的解決方法,你必須要嘗試出最適合你遊戲的方法。

當你使用物件空間的法線貼圖時,vertex normal的問題就會消失,你不再依靠模型上面的原始vertex normals。物件空間的法線貼圖會完全忽略vertex normals,物件空間的貼圖讓你使用所有的軟邊,在低解析度模型也不會有bevel,也不會出線光照錯誤。

低模有設定smooth group與全部設為硬邊, 產生不同的法線貼圖. (圖文取自這裡, 作者Ariel Chai)

使用Bevels
Bevels/chamfers能夠改善模型的剪影而且能產生更好的反射高光。

但是bevel常常會產生很長的三角面,會降低遊戲裡面的算圖效能。即時的算圖器往往對於狹長的三角面會有問題,因為這會產生很多算圖的sub-pixel的區域。

Bevels也會讓vertex count數值大增 這能會讓位移的時候耗費很多效能與記憶體 硬邊也會增加vertex count 但是對於共用UV空間的邊縫不會增加vertex count 請看以下文章

跟bevel相比,使用硬邊,而且讓UV shells能夠穩合,通常能夠產生較高的效能與美麗的結果

如果沒有做bevel, 但是有設定smooth group, 用不同的顯示模式: 3ds max的硬體顯示, xNormal與raytrace算圖的比較. 很顯然3dsmax的normal map即時顯示效果不好!

若是對低模做了bevel, 就算是用3ds max的硬體顯示, 也能夠有好的效果

低模沒有設定smooth group, 在即時顯示的時候, 右邊的那個box出現怪異黑色線條. 請看下圖說明原因

主要是因為你的UV都拆在同一塊, 相接的地方因為法線方向不一致, 所以才會出現怪異的黑邊.

解決之道是把UV拆開成獨立區塊, 如此就不會出現怪異黑邊.

舉另外一個例子, 由kodde先生所提供 (原文請點這裡):
這裡比較對低模有加bevel, 或是設定smooth group產生normal map貼回低模後, 效果比較. 由左至右為: 高模, bevel的低模, 全部硬邊的低模, 全部軟邊的低模.

很顯然有做bevel的低模

1. 全部硬邊 2. 全部軟邊 3. 有做bevel, 3的效果較佳, 缺點是耗費比較多的poly數量.

如果還是不清楚為什麼會這樣, 以下CryEngine Mod有很好的圖示:


如圖所示, 橘色為低模, 藍色為高模. 當計算法線貼圖時, 由低模發射出的射線跟高模有交錯點 (紅點)

但是這樣產生的normal map效果不好看

這裡跟上圖類似 但是把高模往外推. 沒有設定smooth group與bevel以前, 低模的射線會有死角(deadzone)

因此計算出來的法線貼圖 原角的邊緣非常不明顯

如果把低模設定全部為一組smooth group, 射線在圓滑處與高模有比較好的交錯點 (紅色小點)

這樣產生的normal map效果很不錯, 但是有一個缺點是從很極端的角度來看邊界會有奇怪的亮光.

最後, 加了bevel同時也設定smooth group. 射線與高模有很好的交錯點


得到了很棒的normal map, 在極端的角度觀看有不會有怪異的亮光.

編輯Vertex Normals
如果你使用bevels的話,藉由編輯vertex normals, 讓大面積的平面具有垂直的法線,shading結果會改善。vertex normals通常會強迫跨過小的bevel面,而不是跨過大面積,請看以下教學:

有bevel的模型會讓法線偏向

建立高模(High-Poly)
SubD建模與數位雕刻,是大部分用來產生法線貼圖的相關技術。

有些美術比較喜歡先建出遊戲模型(低模),有些喜歡先建高模,有些則是介於兩者之間。順序其實是由個人自己取決。三種都可以產生很棒的結果。

  • 先建立出遊戲模型,然後提高解析度,然後再雕刻。
  • 建立高解析度的模型,然後據此建立出遊戲模型。
  • 建立基本模,然後提高解析度來雕刻它, 同時降低解析度再修改到變成遊戲模型。

如果遊戲模型是從細分表面雕刻而來,建議可以把某些edge loops,切割添加或是移除,來達到模型最佳化。

斜面的Extrusions
在高模進行Extrusions,它的斜面最好做的明顯一點,這樣才能產生較好的法線貼圖。

mental ray Round Corners Bump
mental ray算圖引擎會自動地產生bevel的算圖效果,稱之為Round Corners Bump。 這也可以bake到法線貼圖裡面,在3ds Max、Maya與 XSI都能利用此功能。

Jeff Patton貼了一篇有關於如何把Round Corners Bump功能擷取出來,讓你可以套用在其他材質上。
Michael "cryrid" Taylor 寫了一篇在XSI裡面利用Round Corners的功能。

XSI可以把這個效果成功地烘培到法線貼圖上面,但是3ds Max似乎會不正確地烘培。 Maya則是完全不能烘培,可能是要把.mi shader改成正確的座標系統max就會變正常了。


上圖左右都是同樣一個模型, 左邊那個有套用Mental ray round corner的shader, 會在算圖時產生bevel的效果. (原文取自這裡)
烘培(Baking)
根據高模進行的法線轉換到低模,稱之為烘培。這個烘培的工具通常根據某段距離自低模投射出來,發射出射線到高模,當這條射線跟高模交錯,它會紀錄模型的表面法線,儲存在法線貼圖裡面。

為了要理解這些選項會怎樣影響你的法線貼圖,先用簡單的box來做測試,然後很快速地實驗UV mirroring、smoothing groups等等。這會讓你了解設置參數。

反鋸齒(Anti-Aliasing)
開啟超級採樣或是反鋸齒 (或是multi-ray casting),能夠幫助你修掉當高解析度模型跟自身重疊,重疊在低模的UV邊界以內,產生的鋸齒邊。不幸的是,啟動反鋸齒會算的比較慢,也比較耗記憶體。

沒有開啟反鋸齒就去烘培材質會在高模模型重疊的區域產生鋸齒錯誤
一個小技巧,就是算圖的時後計算原圖的兩倍大,然後在Photoshop裡面縮小。這個縮小的動作會進行pixel重新採樣,在縮放以後,確認貼圖有re-normalize。因為如果沒有這樣做會產生很多小的雜點,Re-normalizing可以利用NVIDIA的法線貼圖濾鏡來做。

3ds Max的超級採樣處理edge padding效果不好,會在留白的pixel間產生黑色的長條,如果會出現這樣的問題話,先關掉padding選項,然後之後再做padding。重新baking,不要勾選超級採樣,或是利用Photoshop濾鏡來處理。

烘培透明度(Baking Transparency)
有時候你需要從物件烘培法線貼圖,這個法線貼圖要用在透明度控制,例如帶有透明度控制的樹葉。很不幸地,烘培的軟體會完全忽略你高模的透明度。

3ds Max的RTT baker會產生透明度錯誤

正確的光照設定產生完美的透明度

為了要解決這個問題,對模型的上視圖進行渲染,這只對當你對低模使用平面的UV投影,計算切線空間法線貼圖有用。

請確認上視圖長寬能與低模的planar UV投影尺寸相符,這對等角攝影機的精確放置會有幫助,高模則需要套運特別的照明或是特殊的材質。

(1)以下教學有提到照明設置
直接在3D應用程式裡面建立法線貼圖
用3D軟體產生高品質的法線貼圖
繪圖技術顧問 Xbox遊戲內容與設計團隊
(2)material shader也可以做到相同效果 但是不需要打燈
NormalTexMap 這是一個用3ds Max腳本產生的貼圖
InfoTexture貼圖外掛

由上往下的光照環境設定

邊界留白(Edge Padding)
如果法線貼圖的邊界沒有留邊,會在UV邊界的地方產生縫隙。

粉紅色是模型的材質區域 黑色是背景區域. 當遊戲在進行時, 為了要讓材質顯示更平順 會套用filter到材質上面 稱為down sample降採樣. 如果背景區域的顏色跟材質本身的顏色差異太大 將採樣產生的mip可能會吃到黑色背景區域. (原文連結請點這裡)

因此在畫材質或是產生法線貼圖時要設定padding (留邊) 避免上述狀況

高模材質
如果高模套用了mental ray Arch & Design material材質,那麼3ds max就無法正確地產生法線貼圖,如果法線貼圖的結果是全黑,那就改用Standard材質吧。例如這帖有討論到的:

Reset Transforms
在烘培之前,請確認你的低模的位移形變已經重置了。 這點很重要,通常建模的過程中,會進行旋轉與縮放,但是這些會產生大量的區域座標空間local "space" 。而這樣會很容易產生法線貼圖的算圖錯誤。

解決交錯的模型
投影的過程通常會產生遺失、重疊、交錯
而高模的自身交錯讓要產生乾淨的法線貼圖變得十分困難,通常會出現在手指附近,把ray distance設定的太高會導致拾取到其它的手指,太小的話在低模與高模距離較遠的地方會出現問題。

還好有幾種方法可以解決這類的問題
  1. 改變cage的形狀,手動邊即投影cage的點,能夠幫助你產生更好的cage,能夠更緊密地包覆住手指。
  2. 用材質來限定投影或是UVs
  3. 把模型炸開,請看這帖討論欄
  4. 用不同大小的cage來進行烘培,然後在Photoshop結合起來
當烘培時隨機產生的像素錯誤
如果你採用3ds Max的『Render To Texture』的功能,來進行烘培的話,你可能會發生隨機的雜點,這只會當你使用原本的模型來做投影,而這個模型用了不同的UV 通道的時候。

在烘培法線貼圖時產生的隨機像素錯誤

有兩種方法解決
  • 在複製的模型上添加push的修改器,把數值修改為0.01
  • 在算圖設定的地方關閉濾鏡,避免反鋸齒你也可以在Global Supersampler關閉反鋸齒。
波浪狀的法線貼圖
當你為圓筒狀模型進行法線向量計算時,低解析度與高解析度之間會產稱波紋狀的法線貼圖,有很多方法可以避掉這個問題。

  1. 很簡單只需要修改cage的形狀,這樣改變rays的朝向,在最下面的法線貼圖教學裡。Ben "poopinmymouth" Mathis展示如何在 3ds max裡面達到上述動作, 相同的方法如下圖:
  2. 細分低解析度模型,讓它盡量穩合高解析度模型。Jeff "airbrush" Ross在這個教學影片有解說如何在Maya裡面做這個效果。
  3. 把波浪線塗抹掉,由Ben "poopinmymouth"寫的法線貼圖教學,Mathis介紹了一個教學如何把波浪的法線貼圖用塗抹的方式塗掉。
  4. 使用獨立的平面投影方法用來捕捉筒狀區域的細節,因此ray-casting會更平均 例如要添加輪胎的胎紋,胎紋可以由一條平的模型產生,然後在2D繪圖軟體裡面以圖層方式疊合上去。
  5. 調整cage的形狀,讓扭曲的法線貼圖消失

調整cage的形狀就可以產生沒有波浪紋的法線貼圖了

左圖為低模, 右圖為高模(本例得原文請點這裡)

這是在max裡面預設的低模投射到高模時 cage的模樣, 很醜

產生的法線貼圖有明顯的波浪紋

左圖貼上法線貼圖的低模 與右圖相比 有明顯的波紋

這是因為在計算法線貼圖時的射線扭曲的問題 (紅色)

有一個很簡單的方法可以解決 那就是Reset cage. 但是會出現上圖的錯誤, 法線貼圖被剪切掉了. 因為cage沒有把高模包起來

Reset cage後 把cage 原柱的上下兩個蓋子往內推 最後就可以得到正確的法線貼圖


三角化
在烘培以前,最好要把低模先三角化,由polygons轉換到純的三角面,這樣避免之後的vertex normals 改變,產生奇怪的高光。

當四邊面在Modo裡面轉成三角面時,內部的邊常常會翻轉,造成shading結果的不一致。

有時候烘培工具或是模型的輸出/輸入會把多邊形重新三角化, 一個四邊面的多邊形,其實是兩個三角面,內部的邊(對角線)是可以改變方向的,當四邊面的點被移除時,軟體對多邊形模型的演算法會試著維持四邊面表面合理的非重疊形狀,這是藉由翻轉內部的邊(對角線)達成的。

高光會受到三角面的影響,翻轉對角線可以修正錯誤,請看這篇說明文

處理Cages的問題
Cage對法線貼圖處理有兩項意義:一是對低模而言是用來細分模型表面所用 ,二是用來計算法線貼圖的ray-casting模型。以下是談到ray-casting cage.的主題。

大部分的烘培工具提供您distance-based raycast工具,ray (射線)會沿著每個vertex normal朝外,在設定的距離裡,設定射線投影回來的距離,當射線與高模交錯時 他會對那瞬間的法線採樣。

硬邊與有距離範圍的射線(distance-based raycast) (灰色的區域),會造成射線(黃色)遺失,還有射線重疊(藍色)。

灰色區域則是完全使用軟邊soft edges,能夠避免分岔的法線產生ray-casting的錯誤。

很不幸地,用了distance-based raycast的方法,分岔的vertex normals會造成烘培的高模部分移失或是邊縫的問題。

有些軟體讓你使用cage的模型,這基本上就是把低模膨大,這樣就會自每個vertex往回raycasts。這樣會自cage產生膨大的模型。

繪製(Painting)
不要害怕在Photoshop裡面編輯法線貼圖,畢竟法線貼圖本身也是一張貼圖,因此你可以複製、模糊化、混合等等操作。只要最終效果是好看的就好了,對於法線貼圖處理顏色的了解會幫助你有有效率地繪製法線貼圖。

利用高解析度模型來產生的法線貼圖通常會比用材質做出來的好,因為你是真的自精確,高模來截取適當的法線,這表示法線貼圖的像素基本上就是重現了高模的表面細節,因此可以獲得非常逼真的效果。

如果你是利用一張貼圖來產生的法線貼圖,結果可能看起來很平,或是得到完全不能用的法線貼圖。如果你沒有調整到適當的數值範圍的話,大部分的法線貼圖產生軟體會假定輸入的圖是heightmap,其中黑色是最低點,白色是最高點。如果你想要把手繪材質選換成法線貼圖,結果會非常不好看,最好的辦法是從高模產生一張具有大,中細節的法線貼圖,然後再利用相片產生的法線貼圖來處理模型最細微的表現,例如纖維、刮痕等等。

有時候,預算無法負擔由高解析度模型產生法線貼圖,例如角色或是主要環境資產還是要以高模產生法線貼圖,但是對於比較不重要的環境原件,從heightmap產生的法線貼圖就很夠用了,也不需要花太多時間來處理。

平色(Flat Color)

平色(128,128,255)會產生一個完全垂直於模型表面的法線,只要vertex normals也是垂直的話。請記住,法線貼圖的每個像素的法線會從vertex normals,產生每個像素的法線偏移,如果你希望法線貼圖的某個區域是平的,那就產生沒有偏移的vertex normals,採用128,128,255的顏色就可以。

這當你在鏡像法線貼圖時,並採用反射漸層時特別明顯,反射通常會把法線的角度強化出來,因此法線的錯誤就會更明顯。

鏡像的法線貼圖,當你使用(127,127,255)的顏色會產生縫隙,要用平色 128的效果比較好。
在邏輯上,127似乎才是真正介於0-255的中間數值,但是實際上在用的時候,128才比較實用,當你用(127,127,255)或是用(128,128,255)來繪製時,很明顯的127會產生法線的彎曲,而128才能產生完全平的顏色。

這是因為大部分的遊戲流程使用unsigned normal maps,更多細節請看這裡

把兩張法線貼圖疊在一起
把兩張法線貼圖疊在一起,可以很快速地添加模型細節,例如皺紋、裂痕等等。細節能夠用height map繪製,然後用轉換軟體產生法線貼圖,這樣的細節法線貼圖可以與用高模產生的法線貼圖疊合在一起。

以下是四種混合的方式,請注意預設值是採用CrazyBump (強度50 33 33),但是軟體本身使可以讓你調整任意強度的,在混合之後又重新標準化貼圖(re-normalized)一次。

上圖用了四種混合模式
  1. 由Ryan Clark撰寫的CrazyBump軟體,是採用3D空間來計算法線貼圖的混合,而不是用2D,這是保留細節最好的方法,而且每個圖層強度可以個別修改。
  2. 在Photoshop裡面進行法線貼圖的混合,正值是Linear Dodge;而負值採用Difference mode,結合了Photoshop Action來加速合成動做,這是免費的,但是跟CrazyBump相比比較不精確。
  3. 由Paul "paultosca" Tosca製作的Making of Varga,把法線貼圖混合在一起,對紅色與綠色通道以Overlay模式混合,綠色與藍色通道用Multiply混合,這產生的混合效果會比單純用Overlay的效果要更強烈。Leo "chronic" Covarrubias在這裡有一步一步的詳細教學:
  4. 由Ben "poopinmymouth" Mathis做的Normalmap Deepening 說明利用Overlay模式產生的法線貼圖混合,CGTextures的教學裡面說明了Scott Warren如何利用多圖層來產生法線貼圖。

由Nvidia-filter normalizing產生的灰階圖可以產生很好的height map。Polycount 論壇上面有提到不同的混合選項,請看2D工具的章節:

預先做好的圖庫
你可以建立一堆做好的形狀,之後可以取用,這樣可以節省法線貼圖的製作時間 例如螺絲、管線等等裝飾物,這些形狀會以bipmap儲存,帶有透明度,因此可以用圖層的方式與法線貼圖做混合。

重新標準化法線(Re-normalizing)
重新標準化法線表示重設每條法線的長度到1的範圍內

法線貼圖shader利用三個顏色通道產生每個pixel的法線長度與方向,這些法線會影響模型在場景裡面的光照,但是如果你用手繪,或是混合多個法線貼圖的化 會改變法線的長度。大部分的shader只會認法線長度是1,但是有些shader會動態地去進行重新標準化法線,例如3ds Max的硬體shader。

如果你的法線貼圖沒有標準化 (normalized) 而且顯示的shader也沒有重新計算法線的功能,那你可能在模型顯示的時候看到許多錯誤,高光會產生很多雜點 表面會出現許多怪異的陰影,為了要解決問題。你可以使用NVIDIA的法線貼圖濾鏡,提供了很簡單的重新標準化法線re-normalize的功能,只要勾選Normalize Only就好了。Xnormal也有提供相同的Photoshop濾鏡。

NVIDIA的法線標準化的選項

有些shaders會壓縮法線貼圖,通常會把藍色通道完全地捨棄,因此是即時的重新計算,但是shader必須要重新標準化法線,才能建立資料,因此客製化的法線長度會完全地被忽略掉。

把AO(Ambient Occlusion)算到Normal Map裡面
雖然shader可能不會對法線貼圖進行標準化,但是AO 卻真的可以烘培到法線貼圖裡面,這會讓模型表面的縫隙的法線長度縮短,造成該區域接受到較少的光源,這可以用在diffuse與高光或是其他任何使用法線貼圖的通道,例如反射通道。

為了要把AO烘培到法線貼圖裡面,首先調整AO圖層,讓黑色區域低到恰好與128的灰色相同,然後把AO圖層設定為Darken mode,這會讓法線貼圖的法線變短。讓該區域的表面獲得更少的光線,產生更暗的光照。

這個技巧不能用在具有標準化法線功能的shader,例如3ds Max的硬體shader 。 必須要修改shader才能讓它真的吃到你客製化的法線。大部分的shader都假定法線長度是1,因為這樣的程式碼比較好寫, 而且這個技巧不能用在大部分的法線貼圖的壓縮格式,因為這類壓縮都會捨棄藍色通道,然後重新計算shader 這是一個標準化法線的必要動作。

想要有最好的結果,通常把AO跟color map做multiply,而不要把AO混到法線貼圖裡面。

逆光(Back Lighting)的狀況
你可以客製化法線貼圖,產生有趣的效果,如果你藍色通道翻轉,法線就會朝反方向去,因此會模擬出逆光效果。

模擬出樹葉的次表面散射效果

這是樹葉的貼圖,第二個diffuse很簡單地把顏色反轉,偏移了hue,180° 調整飽和度。
樹葉用了shader,然後用了兩種不同的diffuse shader貼圖:一個使用正常的切線空間法線貼圖,另外一個用相同的圖,但是反轉了藍色通道,這會造成背面的葉子只會被背面的光線所照明。 樹葉的模型是雙面的,但是兩面使用相同的shader 因此這效果可以用在任一角度的光線,還有另外一個優點,因為樹木開啟自身陰影計算,樹葉的影記不會接受的直接照明,因此背面不會顯是翻轉的法線貼圖,因此就可以造假出當光線直接打到樹葉時才會有的透光效果 (SSS),這對整個森林不能用,因為自身陰影與雙面法線貼圖太耗效能了,但是可以用在重點物件 或是用在有做LOD的樹木,在遠方會切換到效能比較好的shader。

Shaders與縫隙
必須要使用正確的shader才能避免在UV斷點的地方看到縫隙,shader必須要跟烘培前的狀況使用相同的切線基礎(tangent basis)。如果不是的話,光照結果不是對於跨UV邊界的地方不一致,就是平滑面出現錯誤。

當你在Xnormal裡面,就可以正確地顯示產生的精確法線,SDK也可以讓你自行撰寫自己的切線空間產生器。

3ds Max Shaders
3ds Max 2011裡面的Render To Texture功能,與老的切線空間切圖,能夠用scanline正確地渲染出來,但是如果用3ds Max shaders不能在螢幕上即時正確地顯示。Max算圖與即時顯示用的是不同的切線基礎,這個問題在你使用非有機的硬邊模型的法線貼圖尤其明顯,smoothing的錯誤會顯示在螢幕上,但是算圖的時候不會出現。

當你使用Render To Texture產生的錯誤可以藉由Christoph 'CrazyButcher' Kubisch 與Per 'perna' Abrahamsen所寫免費的"3Point Shader"來解決,這樣shader就會跟烘培的工具使用相同的切線基礎,所以可以產生幾乎沒有錯誤的法線貼圖,用在舊的法線貼圖上也可以。

你可以在Max螢幕上看到在maya裡面烘培的切線法線貼圖,效果還算ok。在螢幕顯視硬體貼圖,在標準材質中載入,啟動Show Hardware Map in Viewport。 另外一個方法是使用Render To Texture來烘培物件空間的法線貼圖,使用Nspace把他轉換成切線空間貼圖,載入DirectX material與採用RTTNormalMap.fx shader。

絕對不要相信3ds max螢幕上顯示的normal map效果 (原文請點這裡)
由上往下分別是: 在maya裡面產生法線貼圖 然後在max裡面顯示; 在Maya裡面產生法線貼圖 然後在maya裡面顯示; 如果是在max裡面產生法線貼圖(利用scanline) 然後在max裡面顯示 看到那恐怖的三角面了嗎?

Max裡面用scanline計算出來的法線貼圖

Max裡面用Mental ray計算出來的法線貼圖 (請忽略反鋸齒的問題, 為節省時間沒有啟用反鋸齒)

Maya計算出來的法線貼圖




Autodesk知道這個問題,並且計劃在下一版修正這個問題。

比較Maya與Max與客製化的code產生的法線貼圖與即時材質顯示的問題

Christoph "CrazyButcher" Kubisch 與 Per "perna" Abrahamsen寫了一個特別的shader/修改器,來修正這個錯誤,請看這個討論串:

3 Point Studios這個法線貼圖顯示工具可以修正3ds max的問題



3ds max 2010不同的顯示方式的比較

3ds Max編輯法線的技巧
在烘培之後,如果你在你的貼了法線貼圖的低模上面加了edit normal的修改器 似乎會讓vertex normals比較鬆 產生比較精確的螢幕顯示效果

你也可以把修改器塌陷掉 如果你想要的話

Maya Shaders
Maya能在螢幕上面正確地產生法線貼圖 有正確的切線基礎 跟3ds Max相比也比較不會有smoothing的問題

由Brice Vandemoortele與Cedric Caillaud所寫的BRDF shader 這包含了物件空間的法線貼圖 浮雕貼圖 自身陰影 且確認Maya plugin manager使用有cgFX shaders 然後你就可以依此產生Lambert, Phong等等 關閉高品質算圖才能在螢幕上正確地顯示

如果你想要使用軟體算圖引擎 使用mental ray 但是不要使用Maya的軟體算圖 因為mental ray能正確地解讀切線空間的法線 而Maya算圖器會把法線貼圖視為灰階的bump map 產生難看的結果 Mental ray支援Maya的hong shader 雖然它不認得插在"cosine power裡面的gloss map 拉桿還是可以用地 如果你不介意gloss有統一的數值 Spec maps也還能運作 在螢幕上使用相同的設定 最好把貼圖儲存成TGA 格式

法線貼圖的壓縮
法線貼圖會吃掉很多記憶體,壓縮可以壓到原本的1/4大小,因此你可以增加解析度或是放更多的貼圖。

通常的壓縮法是把藍色通道丟掉,因為這個可以用最小的資源在shader編碼裡面重新計算,bitmap只會儲存兩個顏色通道,而非四個 (紅色 綠色 藍色與alpha)。

這篇關於即時法線貼圖壓縮格式DXT Compression,從id software 與 NVIDIA 是篇很棒的文章:

DXT5nm壓縮
DXT5nm的壓縮格是跟DXT5是一樣的,除了把紅色通道移到alpha通道。綠色通道不變,紅色與藍色通道填充相同的實體色。這樣的安排稱為swizzling。

綠色與alpha通道被採用的原因是DXT的壓縮格式在紅色與藍色通道會用到比較高的bit深度,紅色與藍色會用相同的實體色填充,因為DXT會採用壓縮系統比較不同顏色通道,如果你試著要儲存紅色或是藍色材質、高光、高度貼圖,這樣的壓縮會產生更多的壓縮錯誤,因為他會比較所有的三個通道。

NVIDIA DXT壓縮選項能夠幫助降地壓縮錯,如果你想要添加材質到紅色或是藍色通道 如果你不把紅色或藍色通道放空,產生的錯誤會更多。但是可能優點大於缺點,可以看看在NVIDIA研發論壇上面的討論。

DXT1的壓縮
DXT1有時候會用在切線空間的法線貼圖上面,因為他是DXT5大小的一半,缺點是他會產生很多壓縮的缺陷,所以後來很多人就沒有用這個壓縮格式。

3Dc壓縮
3Dc壓縮又稱為DirectX 10的BC5壓縮,它跟DXT5nm很類似,因為他只儲存X, Y通道。差別是他會儲存跟DXT5 Alpha channel相同的通道,跟DXT5nm的綠色通道相比會稍微高一點的bit深度,跟其他演算法相比3Dc能夠產生最好的結果。不需要處理時間或是特殊的硬體。

A8L8的壓縮
DDS 格式A8L8並沒有真正的壓縮,只需要兩個8bit灰階通道,每個256灰階 這會讓你避免使用三個顏色通道。但是shader必須要重新計算藍色通道才能正常的運作,但是A8L8並沒有節省到任何材質記憶體,它只是在送給顯卡的時候 轉成四個通道的32bit材質。這個格式的唯一優點是減少硬碟使用空間。

----翻譯完畢----

[更多教學]

2 comments:

HappyPingu said...

受益良多!

maggie chang瑪姬美宇_手塗日記 said...

在maya裡鏡射那一半的UV移到0-1的空間之外的地方,出來的結果好像還是一樣耶,是甚麼問題?謝謝