[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。

 

 

©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页