http://developer.download.nvidia.com/whitepapers/2006/Mipmapping_Normal_Maps.pdf
来自nvidia的小短文,处理远处normal map不正确的计算导致的specular lighting,反射等闪烁的问题。
核心思想是把远处平均后的normal的长度作为衡量normal变化率的标志,基于此来修正用normal map计算的东东(specular lighting,env reflection...)。
中间各种的数学推导是精华(如果说low level programming is good for programmer‘s soul,那么也可以说math is good for render programmer‘s soul)
normal variation
一般normal map处理的时候,生成mipmap的话,就是linear的一级级downsample,这样在normal变化很大的地方,平均出来的normal的长度就很小。
那么可以根据normal的平均长度来建立normal的方差数学模型:
这里一旦出现normal偏差较大,那么就是用概率中的高斯分布(我们上学时候一般说是正态分布,和大家考评时候出现的中间占大头,两边占小头一样的)来描述。
specular lighting
远处一个点可以看作是一片点的specular lighting的平均值(离散积分):
这里可以看出,结果并不是和normal线性相关的,所以拿平均的normal来算离结果会相差很远,所以会产生较大的偏差(specular lighting又很亮,出来的就是闪烁)。
那么结合前面normal对于方差,正态分布的描述,这里可以对specular lighting计算进行建模,然后在一定范围内使用更简单的数学函数逼近(图形学推导常用方法)
最后specular lighting计算出来这样的:
其中ft,在文中被作者michael toksvig成为toksvig factor:
其中n就是normal,s是specular power。
最后直观描述出来就是,如果normal的长度低,也就是normal的方差大(变化大),那么会呈现远处specular power(gloss)降低的观感。
crytek在14年siggraph论文中谈到,把normal这个分布看作roughness一部分,也很有道理,远处normal很分散,不就是roughness很大么(相对gloss就低么),crytek正是使用这个原理,来根据normal的length来矫正roughness的。
没有做roughness矫正的:
做了矫正的:
其实直接看可能不是特别明显,这种情况如果动起来就闪的很厉害。
这个数学结论也更接近物理实际的情况和直觉观感。
实现:
paper最后是建议使用look up table把结果存起来,毕竟计算还是有点费的。