Normal map[結語]
這次仔細研究normal map的製作,算是把整個normal map完全了解了。把整理的心得放在這邊除了是做紀錄外,也是想說透過這個方式把心得分享出來,可以對其他人有幫助。希望這不是野人獻曝 :)
3D Engine 研發手札
這次仔細研究normal map的製作,算是把整個normal map完全了解了。把整理的心得放在這邊除了是做紀錄外,也是想說透過這個方式把心得分享出來,可以對其他人有幫助。希望這不是野人獻曝 :)
技術文件
相關工具
normal map製作
現在的3D遊戲幾乎都使用DDS的壓縮材質,主要原因是壓縮效率品質都不錯。可是normal map直接壓縮為DXT1~5這些格式, 效果都很不好。於是研究了一下目前一般常用的技術。
大致上目前使用的技術都是只儲存X/Y值,而Z值都在pixel shader裡面計算..
Z = sqrt( 1 – x*x – y*y)
這樣的方式有些限制:
這個方式下有幾個常用的normal map格式:
下圖是測試比較圖,可以看出Swizzled DXT5效果還不錯說
簡單說明一下如何使用NVIDIA Photoshop plugin製作這些壓縮格式的方式:
normal map的座標系確定後,接下來整理一下normal map的製作方式。
一般製作normal map的方式大概有以下幾種:
NVIDIA Photoshop Normal map filter plug-in
紅色框的Invert-Y一要勾選, Wrap建議勾選
以下是試做bump map轉normal map的試做結果
製作高面數物件以及低面數物件來產生 normal map:
這個做法就是製作高面數的物件, 把高面數的normal 儲存成normal map。目前美術人員常使用的 3ds max, Maya, XSI等軟體都有內建高面轉低面數的工具,所以都可以使用這些工具製作高面數模型來轉換輸出。不過現在 Zbrush/Mudbox 這類 3D建模軟體的出現,使得 normal map 的製作更有效率。以下說明的是使用Zbrush/Mudbox軟體轉normal map的製作方式.。製作的流程如下:
注意圖中紅色框框:
- Tangent space N.Map 必須勾選,才能產生tangent space的normal map。
- Flip Image Vertically 必須勾選。
- Interpolate/RayTrace : 計算normal map的方式, Interpolate 比較快,Ray Trace會比較慢。理論上ray trace品質應該會比較好才是。
- 其他參數使用預設值。
以下是使用ZBrush製作normal map試做的結果:
製作方式與Zbrush差不多,也是製作低面模型輸出OBJ檔案到mudbox製作細節。不過目前測試的結果發現mudbox產生normal map的 Texture Baking工具 效果不是很理想,所以看到網路上一些美術好手的做法是將高面數的物件匯出OBJ檔案,再使用3DS MAX/Maya/XSI透過高低面產生normal map的工具來產生normal map。3DS MAX/Maya/XSI 產生Y-up 的normal map設定可參考http://sd-art.wikispaces.com/normalMapping
normal map是使用RGB來儲存normal 的XYZ向量值,所以必須定義normal儲存的座標系。座標系就包括了world/object/tangent space,其中還分成左/右手系統。不同的座標系統在處理lighting計算時候會需要不同的處理方式, 因此程式人員需要制定normal map所在的座標系,才能夠正確的處理normal map效果。 World space/object space的優缺點和tangent space正好相反,所以某些狀況下或許使用world/object space的normal map 會比較好。 不過我目前只打算使用 tangent space的normal map. 對object space下的normal map有興趣的可看http://www.3dkingdoms.com/tutorial.htm 下圖是兩個系統下normal map的比較. 可以發現左手系統XYZ(0, 1, 0) 或是RGB(128, 255, 128)是指向下方,右手系統是指向上方。在網路上搜尋了一下,似乎沒有人以左手右手系統來區分這樣的差別,只有提到Y向上或是Y向下。所以以下內容就是以Y向上系統(Y-up)或是Y向下系統稱呼(Y-down)。
缺點:
normal map是目前3D遊戲最常使用的技術之一。之前參與過的專案有嘗試使用normal map,但是由於程式人員對normal map技術沒有完全了解,以及美術人員無法負擔因為製作normal map所帶來的的製作量,最後也就放棄了這個技術。
為了提供點光源的陰影處理, 嘗試實作了CubeShadowMap. 做法主要是參考Nvidia SDK 9.51裡的Virtual Shadow Depth Cube Textures範例. 這個範例其實主要是實作了把CubeMap 展開成一個2D Depth Map的技巧, 透過這個方法, 就可以使用到nvidia硬體處理shadow map的功能了..該範例也實作了對照組, 就是最原始的Cube Shadow Map的做法. 目前實作的就是這個方法. 等之後有空在實作Nvidia的方法.
秀一張目前實作結果. 場景內只有一個點光源, Cube Shadow Map的格式是1024x1024 RG16F , 沒有作柔化shadow的處理.