多年前就想为KlayGE做个Normal2Height的工具,一直没时间,现在终于抽空把它完成了。
缘由
Normal map的来源有多种。游戏开发中常规的做法是根据高模和低模的位置对应关系生成height map,然后用height map生成normal map。这种情况下不必担心是否能得到高精度的height map。但很多低端的做法是让美术直接画normal map,根本没有高模。随着游戏渲染水平的提高,normal mapping(NM)这种1970年代的技术已经不能满足需要了,越来越多的游戏开始过渡到更精确的parallax mapping(PM)、parallax occlusion mapping(POM)甚至displacement mapping(DM)。他们除了normal map,还需要有height map才能工作。所以如果normal map是手绘而成,就会因为缺乏height map而无法升级。如果能反过来,从normal map生成height map,就能在一定程度上解决这个问题。
比较一下normal mapping和parallax occlusion mapping,就可以明显地看出来在视差、遮挡效果和真实感上,POM远胜于NM。
算法
我实现的算法是基于NVIDIA在SIGGRAPH 2011上提到的Generating Displacement from Normal Map for use in 3D Games。我就不详细讨论了,有兴趣的朋友可以看原始pdf。这里指讨论一下基本的想法。
从height map计算normal map靠的是差分,所以直觉上从normal map计算height map就需要积分。但因为normal map保存的时候经过量化,误差比较大,造成不同的积分路径无法收敛到同一个值。
所以NV的方法是,先根据normal map计算depth difference map(DDM)。然后对DDM上的每个pixel,根据极坐标从小到大的顺序累计几圈,得到最终的height。
就是这样简单的累积算法,就能得到不错的效果。对于这样的normal map:
可以恢复出height map:
虽然比原始的高精度height map模糊,但在用于POM和DM的时候在视觉上看不出区别。
总结
在有了Normal2Height这样的工具之后,老土的normal mapping都可以顺利地进化到更精致的渲染效果。同时,对原有美术流水线的影响几乎为0。
理论上,还可以尝试通过求解Poisson Equation来得到精度更高的height。
Comments