摘要:本文介绍了各向异性(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

定义:

  • ata_t: 沿各向异性方向上的粗糙度, 即directionalAlphaRoughness
  • aba_b: 垂直方向上的粗糙度, 即materialAlphaRoughness

Anisotropic GGX Distribution

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;
}

参考

glTF Specification

PBR White Paper