各向异性高光

主要参考来自ATI Research Inc的《Hair Rendering and Shading》

原理

各向异性表现:光打到物体表面会在不同的表面发散

可以分为两部分处理:

  • 发光方向的处理
  • 拉丝感的处理

发光方向

使用kajiya-kay模型,不再使用法线和半程向量dot(N,H)去计算高光,而是使用每根头发对应的tangent值和半程向量的sin值去计算:sin(T,H) = sqrt(1-dot(T,H) * dot(T,H))

H越接近横截面,越亮,sin的特性也是如此(越接近横截面的时候值越大),因此用sin表示

1
2
3
4
5
6
7
8
9
// 半程向量
half3 half_dir = normalize(light_dir + view_dir);
// 计算TH点积,这里binormal的原因是unity中切线方向是u方向因此需要副法线
half TdotH = dot(binormal_dir, half_dir);
// 计算Sin
half SinTH = sqrt(1-TdotH * TdotH);
// 高光
half3 spec = pow(max(0.0, SinTH),_Shineness)
* _LightColor0.xyz * _SpecIntensity;

拉丝感

通过shift texture实现分为两个部分

  • shift texture
  • noise texture

1
2
3
4
5
6
7
8
9
// 采样噪声图来获取拉丝感
half uv_shift = i.uv * _ShiftMap_ST.xy + _ShiftMap_ST.zw;
half shiftNoise = tex2D(_ShiftMap, uv_shift).r;
// 为噪声添加强度
shiftNoise = shiftNoise * _NoiseIntensity;
// 为副切线添加偏移(控制高光的位置)
half3 b_offset = normal_dir * (_ShiftOffset + shiftNoise);
// 获取更新后的副法线
binormal_dir = normalize(binormal_dir + b_offset);

金属

金属的拉丝感需要通过贴图进行整理,思路类似凹凸贴图的使用,从贴图获取切线以及副切线的信息,对原本的副切线进行修改

颜色设置如下

PS中制作的贴图如下:

  1. r通道存储横向渐变
  2. g通道存储纵向渐变
  3. b通道存储拉丝的噪声

通过采样制作的贴图对binormal进行修改

1
2
3
4
5
6
7
8
// 获取贴图数据
half3 noise_data = tex2D(_FlowMap, i.uv).rgb;
// 获取噪声数据
half shiftNoise = noise_data.b * 2.0 - 1.0;
// 获取切线以及副切线方向修改信息
half2 noise_dir= noise_data.rg * 2.0 - 1.0;
// 修改副切线
binormal_dir = normalize(tangent_dir * noise_dir.x + binormal_dir * noise_dir.y);

修改后效果如下: