写实头发材质部分,也就是讲下Shading Model实现.
Kajiya-Kay[1989]关于头发的Shading Model沿用至今,已经快30年。Kajiya模型的优点是:
- 算法简单,便于理解,计算量小
- Primary Specular的性价比高,效果明显,方便美术使用
但Kajiya模型又被称作Painter's Illusion, 难以获取真实的头发材质效果,其不足在于:
- Kajiya的模型过于简单,只简单模拟了Primary Speucular, 没有处理Light Transport的其他情况,比如光线在头发纤维内的传播过程。
- Kajiya假设头发纤维是光滑的圆柱体,而电子显微镜下显示头发纤维是由表面粗糙的鳞片层叠形成的不规则几何体,鳞片之下还有色素髓质。鳞片和髓质对光线的传播,染色和衰减吸收作用,都没有在Kajiya模型里体现。
因为以上的问题,导致Kajiya Model是non-physically based。 经验值参数导致光照能量不守恒。弊端是在Artist在特定的光照情况调出来的头发效果,光照发生变化之后,可能会出现明显的瑕疵,很多时候需要Artist把头发的颜色预先画在贴图上。
针对Kajiya模型的不足,Marschner[2003]提出了一个新的模型,其特点:
- Light Transport更完善,不仅有Primary Specular(R mode) , 还包括光线在头发纤维髓质内折射后再次出射Transmission(TT mode), 光线在头发纤维髓质内多次反射后再次出射Secondary Specular(TRT mode),TRRT, GLINT等
- Marschner模型考虑到头发纤维的微观结构,纤维外层的鳞片会对R, TT, TRT的路径产生影响,光线在纤维内部的传播也会受到菲尼尔,染色,吸收衰减的影响。另外,头发纤维的横截面是椭圆,这个结构的设定可以通过微分方程的奇点计算出头发Glint效果。
这个模型基本模拟了所有较明显的头发光照效果,因此在CG和游戏领域被广泛采用。
下面以Marschner. 2002. Light Scattering from Human Hair Fibers的论文以及UE4.20的实现来详细介绍Marschner Hair Model的近似解析解。
假设我们要求解的头发纤维散射函数为 S(φi,θi,φr,θr)。通过几何推导和实测数据验证,S有三个特性:
- 光线在头发纤维中不管经历多少次反射和折射,入射角和出射角的经度是一样的。
- R, TT, TRT mode分布在圆锥面上,圆锥面的母线和中轴线的夹角等于入射经线角(即入射光线和法线平面投影之间的夹角)。但受到头发纤维鳞片的作用,R会向发根倾斜一定的角度,TT, TRT会向发梢倾斜一定角度。
- S函数中经度角θ和方位角φ的依赖关系可以通过多项式分解提取出独立的M(θ)和N(φ)
因此得到解析解的形式:
S(φi,θi,φr,θr) = ∑pM(θh) * N(φ)* A(p), p∈{R, TT, TRT, TRRT, GLINT........}
M为θ分布函数,N为φ分布函数,A = Absorption * Fresnel
(UE4里只考虑前三项的影响,且只处理圆形横截面)
- M项。如果头发纤维是光滑的,那么M项应该是δ distribution。而实际上头发纤维的鳞片外层是粗糙的,所以这里用了gaussian distribution。其中gaussian distribution的标准差对应的是纤维粗糙度,期望值对应鳞片外层会对光线产生的偏移。Digital Weta在后来的实验中发现M项如果能部分依赖φ, 能更准确的计算backlit。由于对φ的依赖计算复杂,UE4只在最明显的R mode使用了这个办法, TT, TRT仍然使用gaussian distribution。
- N项。R的反射分布使用Kajiya推导的解析解N = 1/4 * cos(φ/2)。Pixar. 2013. A Data-Driven Light Scattering Model for Hair发现柯西分布和logistic分布比高斯分布更利于采样计算,所以UE4里尝试用logistic分布估算N项: Ntt = exp(-3.65 * cosφ - 3.98), Ntrt=exp(17 * cosφ - 16.78)
- A项。Fresnel是Schlick近似求解。R只有一次Fresnel计算, TT有两次, TRT是三次。Absorption的关键是计算入射光线到纤维中心的距离(Scattering Geometry b)根据光线在头发纤维横截面的传播过程可以推导出等式:φ(p, h)=2pγt - 2γi + pπ 。φ是入射光线和出射光线的方位角之差。求导以后可以到得TT, TRT的h解。TT的解有一个, TRT的解有一个或者三个。其中htt = sign(φ)cos(φ/2)/√(1 + a*a - 2 * a *sign(φ)sign(φ/2)),htrt没有解析解。UE4对htt, htrt做了简化。htt≈(1 + a * (0.6 - 0.8 * cosφ)) * cos(φ/2). 而TRT的lobe只用一个,用√3/2估算。通过h的值便可以得到光线在纤维内部的路径,从而得出absorption项,当然也是近似值。Ttt = pow(color, 0.5 *√(1 - h*h*a*a) /2 *cos(θd)), Ttrt=pow(color, 0.8/cos(θd))
最后还有scattering diffuse. 这一项的physically based计算非常复杂,UE4对这部分做了最简单的处理,参考了Kajiaya的diffuse term,同时用经验值和视线矫正过的NoL做了线性插值。UE4 Hair Shading Model作者也认为这部分的优化空间很大。Marschner.2008.Efficient Multiple Scattering in Hair Using Spherical Harmonics是一个很好的参考改进方案。
下文: 游戏角色写实头发制作(三): 造型
大星星:腾讯互娱技术美术组招聘 渲染方向TA(含实习生,长期有效)zhuanlan.zhihu.com