头发的各向异性高光
概念
各项同性材质渲染可以认为是在所有方向上均匀地散射光,可以认为一个点的法线N是固定的,而各项异性材质的渲染,在微观上是有各种颗粒和划痕的,一个表面上的点可能有多个法线,所以我们不能用普通的高光模型去计算各向异性的高光
Kajiya-Kay Model原理
依据Blin-Phong 光照模型 高光的强度是通过 pow(max(0, NdotH), _SpecularPow) 计算的,但是各项异性中N没法直接获取,我们需要通过切线T和方向和入射光方向来确定该平面上的法线
在数值上,我们会发现TH的夹角正弦会等于HN的夹角余弦值,得到如下代码
fixed dotTH = dot(tangent, halfDir);
fixed sinTH = sqrt(1.0 - dotTH * dotTH);
//衰减值,dotTH大于0不衰减,dotTH小于0衰减
fixed dirAtten = smoothstep(-1.0, 0.0, dotTH);
fixed kkSpecular = dirAtten * pow(sinTH, _SpecularPowH) * _SpecularAttenL;
fixed3 specular = _SpecularColor.rgb * kkSpecular;
优化
根据以上代码得到效果如下
法线高光是块状的和现实效果不符合
偏移贴图
我们通过Shift Tangent Map对切向方向进行偏移
float shiftTex = tex2D(_SpecularShift, i.uv) - 0.5;
fixed3 tangent = normalize(i.tangent + worldNormal * (_Shift + shiftTex));
得到如下效果
主副光和AO
为了让高光的明暗度更加符合现实,可以通过两层高光来控制高光,并把高光与AO以及阴影进行关联,让高光效果的可调性和敏感变化更好
fixed kkSpecular = dirAtten * (pow(sinTH, _SpecularPowH) * _SpecularAttenL + pow(sinTH, _SpecularPowL) * _SpecularAttenH);
fixed3 specular = _SpecularColor.rgb * kkSpecular * shadowAtten * ao;
模型UV
进行上述优化后,发现高光的纹路线条是扭曲的,并不是很自然
需要对贴图的切线进行修正来提升效果,或者在制作头发贴图时,所有的头发模型的UV都是在垂直方向展开的,这样高光的效果会更好
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.