Unity URP Shader之各向异性头发高光之KK高光模型
关于各向异性头发高光,效果可参考:
首先弄清以下知识点:
1. KK高光模型,即 Kajiya-Kay Model
传统的Phong高光模型使用 NdotH做为因子,这里采用 TsinH,即 sqrt(1 - TdotH * TdotH),注意这里是假设切线方向与发丝方向一致。
即高光公式改为如下:
half dirH = normalize(viewDir + lightDir);
half TdotH = dot(worldTangent, dirH);
half TsinH = sqrt(1 - TdotH * TdotH);
half3 specCol = pow(TsinH, _Gloss) * lightCol;
我们来用一个Sphere来做测试,由于sphere的切线方向是水平的,副法线方向是垂直分布的,所以这里我们用副法线方向来代替切线。
看下sphere的切线(绿色),副法线(红色),法线(蓝色)分布
修改高光公式之后效果如下(左边为传统Phong高光):
2. 这里还需要实现发丝的效果,方法是使用如下图来对切线沿法线方向做扰动
具体公式如下,我们修改上面代码中的worldTangent值,即完整代码如下:
half shiftnoise = SAMPLE_TEXTURE2D(_ShiftMap, sampler_ShiftMap, uv);
half3 newWorldTanget = worldTangent + shiftnoise * worldNormal;
half dirH = normalize(viewDir + lightDir);
half TdotH = dot(newWorldTanget, dirH);
half TsinH = sqrt(1 - TdotH * TdotH);
half3 specCol = pow(TsinH, _Gloss) * lightCol;
最终效果如下:
3. 双层高光
4. 一个比较省的头发高光算法
// 头发高光
half3 SpecularLighting_Hair(half3 specCol, half shiftnoise, half3 B, half3 N, half3 V, half gloss)
{
shiftnoise = clamp(shiftnoise, -1, 1.33);
float BoV = dot(B + N * shiftnoise, V);
half3 specular = specCol * pow(1 - BoV * BoV, gloss);
specular = clamp(specular, float3(0,0,0), half3(1.51,1.51,1.51));
return specular;
}