[Graphics] 法線圖生成器(Normal map generator)

最近因爲研一的課程、作業太多,平時很少有時間幹自己的事情,也好久沒有寫新的文章。而且!!!最倒黴的是,我的算法課由於前兩節沒選課!導致不知道作業還有截止時間,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:

gray=(r+g+b)/3

此時設點(i,k)處的灰度值記爲G(i,k)

2. 利用gradient來計算初步的Normal map 1

這裏我們利用更高的grayscale image來獲取一個初步的Normal Map。由於Normal是一個三維向量(x,y,z),所以我們利用如下方法來計算點(i,k)處的法向量:

利用Sobel算法來計算水平和數值方向的梯度,即:

dx= G(i-1,k-1) +2*G(i,k-1) + G(i+1,k-1) - G(i-1,k+1) -2*G(i,k+1) + G(i+1,k+1)

dy = G(i-1,k-1)+2*G(i-1,k)+G(i-1,k+1)-G(i+1,k-1)-2*G(i+1,k)-G(i+1,k+1)

此時,點(i,k)處的Normal值即:

x = +dy

y=-dx

z= strength

Normal(i,k)=(x,y,z)

其中,strength是一個修正量,默認可以是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。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章