基于各向异性高光的头发卡通渲染尝试
之前我在资源商店上发了一个免费资源,内容是一个中国角色模型,其中还包含了头发,皮肤,眼球渲染的shader。现在,我想尝试做做卡通风格,而对于本例中头发卡通渲染,我打算原来各向异性高光的基础上弄弄。
资源地址:https://assetstore.unity.com/packages/3d/characters/humanoids/sci-fi/chinese-cyborg-warrior-free-287098
如下计算各向异性高光
float3 HairSpecular(float3 shiftedTangent, float3 H, float specStrength, float specPow)
{
half shiftedNoH = dot(H, shiftedTangent);
float sintTH = max(0.01, sqrt(1.0 - shiftedNoH * shiftedNoH));
float dirAtten = smoothstep(-0.1, 0.0, shiftedNoH);
return dirAtten * pow(saturate(sintTH), specPow) * specStrength;
}
偏移tangent如下得到
half3 Shift_Tangent(float3 normal, float3 tangent, float shift)
{
return normalize(tangent + normal * shift);
}
要想渲染出卡通的效果,主要是改变diffuse项的计算方法。我们在阴影边界出smoothstep。
float3 HairRender(lightDatas lightDat, surfaceDatas surfDat, half3 L, half3 lightCol, float shadow, float3 shiftedTangent, float3 shiftedTangent1)
{
float a2 = Common.Pow4(surfDat.roughness);
half3 H = normalize(lightDat.V + L);
half NdotH = saturate(dot(lightDat.N, H));
half NdotV = saturate(abs(dot(lightDat.N, lightDat.V)) + 1e-5);
half NdotL = saturate(dot(lightDat.N, L));
half VdotH = saturate(dot(lightDat.V, H));//LoH
half LdotH = saturate(dot(H, L));
float3 radiance = NdotL * lightCol * shadow;
half wrapNL = NdotL * 0.5 + NdotL;
float shadowNL = smoothstep(_ShadowStep - _ShadowStepSmooth, _ShadowStep + _ShadowStepSmooth, wrapNL);
float3 diffuseTerm = surfDat.albedo * OneMinusReflectivityMetallicCustom(surfDat.metallic);
#if defined(_DIFFUSE_OFF)
diffuseTerm = half3(0, 0, 0);
#endif
float3 specularTerm = HairSpecular(shiftedTangent, H, _HairSpecular, _HairSpecPow);
specularTerm *= surfDat.mask;
float3 specularTerm1 = HairSpecular(shiftedTangent1, H, _HairSpecular1, _HairSpecPow1);
specularTerm1 *= surfDat.mask;
specularTerm = specularTerm + specularTerm1;
#if defined(_SPECULAR_OFF)
specularTerm = half3(0, 0, 0);
#endif
float wrap = 0.2;
return diffuseTerm * shadowNL * lightCol * shadow + specularTerm * radiance;
//return specularTerm * radiance;
}
简单结果展示