Anisotropy从理论到实践
摘要:本文介绍了各向异性(Anisotropy)渲染的核心实现,包括切线空间定义、纹理映射转换和各向异性GGX分布函数。重点讲解了anisotropyStrength参数对粗糙度的动态调整,并对比分析了UE4和glTF两种实现方案。
Anisotropy
前提:
- 必须定义切线空间
- normalTex 和 anisotropyTex必须使用同一组uv
参数:
- anisotropyStrength(float): [0,1] 表示沿指定方向增加粗糙度,默认方向是切线方向
- anisotropyRoataion(float):
- anisotropyTexture(Texture)
- r & g : anisotropy Dir in [-1,1] tangent, bitangent
- b : anisotropy strength

映射
rg: [0,1] -> [-1,1]
directonalAlphaRoughness = mix(materialAlphaRoughness, 1, anisotropyStrength^2)
其中:
materialAlphaRoughness = materialRoughness^2
- materialRoughness: 设计师填入的粗糙度
- anisotropyStrength: 设计师填入的各向异性强度
- directionalAlphaRoughness: 各向异性计算后需要的粗糙度
D_AnisotropyGGX
定义:
- : 沿各向异性方向上的粗糙度, 即directionalAlphaRoughness
- : 垂直方向上的粗糙度, 即materialAlphaRoughness

UE4 实现:
// Anisotropic GGX
// [Burley 2012, "Physically-Based Shading at Disney"]
float D_GGXaniso( float ax, float ay, float NoH, float3 H, float3 X, float3 Y )
{
float XoH = dot( X, H );
float YoH = dot( Y, H );
float d = XoH*XoH / (ax*ax) + YoH*YoH / (ay*ay) + NoH*NoH;
return 1 / ( PI * ax*ay * d*d );
}
glTF实现案例:
float D_GGX_anisotropic(float NdotH, float TdotH, float BdotH, float at, float ab)
{
float a2 = at * ab;
vec3 f = vec3(ab * TdotH, at * BdotH, a2 * NdotH);
float w2 = a2 / dot(f, f);
return a2 * w2 * w2 / M_PI;
}
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 VanishingBlog!


