最近因爲研一的課程、作業太多,平時很少有時間幹自己的事情,也好久沒有寫新的文章。而且!!!最倒黴的是,我的算法課由於前兩節沒選課!導致不知道作業還有截止時間,oh,fuck!!少交了好幾次哦我滴龜龜!!
嘛,吐槽完了,開始正題。前段時間基於C++做了一個Normal map的生成器。用處是把一副圖像轉換成Normal map,對於我們做Graphics的人來說,還是蠻有用的。
首先還是慣例貼一下實驗結果:
一、Experimental Results
(1) Mapping on sphere with a stone picture.
(2) Mapping on plane with an anime picture.
(3) Mapping on a soldier model with a wall picture.
(4) A result set of my program.(Pair of original image and normal image)
二、我提供的一些資源:
1. 程序的下載鏈接:
2. 參考文獻:
三、算法原理
下圖是本文采用的Normal map generator的pipeline。使用該方法獲得到的Normal map和常規方法的要平滑逼真的多。
1. 獲取原始圖像的grayscale image.
首先,加載一副彩色圖像,並將其轉換爲灰度圖像,即Grayscale Image。採用下式來將r,g,b值轉換爲灰度gray:
此時設點(i,k)處的灰度值記爲G(i,k)。
2. 利用gradient來計算初步的Normal map 1
這裏我們利用更高的grayscale image來獲取一個初步的Normal Map。由於Normal是一個三維向量(x,y,z),所以我們利用如下方法來計算點(i,k)處的法向量:
利用Sobel算法來計算水平和數值方向的梯度,即:
此時,點(i,k)處的Normal值即:
其中,是一個修正量,默認可以是1.0。通過這一步獲取到的圖像可以就是初步的Normal map 1。
3. 對downscale後的image重新計算一個縮小的中間normal map 2
雖然通過上面的步驟就能夠得到一個初步的Normal map 1,但是僅僅這樣獲取到的Normal map是不夠光滑的。因此,我們這裏採用一種PS中常用的手段來對修正法線。
我們對原始圖像進行一個降採樣,即縮小輸入的Grayscale Image。例如,縮小至原來的50%。然後對這個縮小後的Grayscale Image進行第2步中的處理,求得一個縮小的Normal map2
4. 將兩個Normal map合併得到最終的法線圖
將縮小後的Normal map2放大回原來的大小,然後與Normal map1求一個平均,這樣就得到了最終的Normal map。