基于视差贴图的毛发效果

用视差贴图绘制多层,制作毛发效果

常见的毛发做法有:多个Pass往外挤压;《怪猎世界》中的后处理阶段UV沿着法线方向偏移采样多次;还有就是用视差贴图采样多次。

用视差贴图画多层的话,一般只能往下偏移,越来越深。UV偏移值最大的是最底层。所以要通过计算补上毛发底部的偏移,让毛发顶部偏移最大。

具体做法如下:

  • 在顶点阶段让mesh膨胀一点,模拟毛发蓬松效果(也可不加);再加上毛发抖动的偏移值,配合之后做毛发抖动;
  • 再PS阶段采样多层视差贴图,模拟毛发效果;其中每层的视差UV要反向补上每层的偏移值,这样配合之前的顶点偏移,刚好能产生视觉上底部不动,越往上晃动越大的效果;

毛发的效果主要来自下面这张噪点图:

B通道的噪点用来做毛发Clip,每个噪点的边缘有一点渐变,可以用来做毛发顶端细根部粗的效果。

RG通道用来做毛发方向的偏移,类似flowmap。

毛发的抖动效果:先用世界坐标算出一个整体晃动的波形。然后通过噪点图的色块mask(A通道)来控制每根毛发有单独的晃动偏移值,加上这个值就能模拟每根毛发随机晃动的效果,看上去会更自然。

毛发的光照以传统PBR为基础,修改了Radiance。为了让毛发更加柔和,NdotL做了平方,并且引入了毛发的AO(即毛发的高度值)

加上简化的背光Rim效果,FurRim = Pow(VdotNL, FurSoftness – FurAO)。因为这个做法很难计算出正确的Shadow和AO遮挡关系,所以我都是在用一些trick的方式模拟光照,都是经验函数和参数。

基于视线角度,正面的AO强度高,边缘的削弱,所以用NdotV模拟视线角度的AO影响,加入最终的radiance。

常规的radiance = atten * NdotL * MainLight.Color; 毛发的radiance = atten * pow(NdotL, 2+ FurAO + FurRim) * ViewAO;

用简单的采样ramp图的方式模拟SSS效果,最后混合diffuse和GI,就是最终的毛发光照效果。

总结:

  • 以上效果采样了10次视差贴图,优化上可以用8次采样+shader LOD远处采样数更低或者不做毛发效果。
  • 这个做法的缺点就是模型边缘不会像多pass往外挤压做法的那种自然毛绒边缘,也不能像多pass那样可以画出真实的毛绒阴影,大部分光照算法都是近似模拟的。但优点是可以一个pass画完,性能应该更省,适合手机端。

Share

This site is protected by wp-copyrightpro.com