glTF Anisotropy: Highlight Direction and Strength

In glTF 2.0, controlling the shape and orientation of specular reflections relies on the KHR_materials_anisotropy extension. This extension defines how specular highlights stretch and rotate across a surface using a combination of scalar factors, texture channels, and the underlying mesh geometry. The strength of the highlight stretching is primarily governed by anisotropyStrength, while the direction is determined by the mesh's tangent space, modified by anisotropyRotation and directional data encoded within anisotropyTexture.

Parameters Defining Highlight Strength

The elongation or stretching intensity of the specular highlight determines how non-uniform the roughness is along different axes. It is controlled by the following parameters:

  • anisotropyStrength (Float): A scalar factor ranging from 0.0 to 1.0. A value of 0.0 produces standard isotropic reflection where the highlight is circular. A value of 1.0 delivers maximum highlight stretching.
  • anisotropyTexture (Blue Channel): When an anisotropy texture is supplied, the blue (B) channel acts as a linear multiplier for the anisotropyStrength. The final strength at any UV coordinate is calculated as: \[\text{Final Strength} = \text{anisotropyStrength} \times \text{Texture.b}\]

Parameters Defining Highlight Direction

The orientation of the stretched highlight is calculated relative to the surface's tangent space and altered by rotation angles and vector textures:

  • Mesh Tangents (TANGENT attribute): The baseline orientation of the anisotropy relies on the vertex tangents and bitangents defined in the 3D model. If explicit vertex tangents are omitted, implementations must derive them from surface UV coordinates.
  • anisotropyRotation (Float): A scalar angle in radians ranging from \(-\pi\) to \(\pi\) (or \([0, 2\pi]\)). This value rotates the primary tangent vector counter-clockwise around the surface normal.
  • anisotropyTexture (Red and Green Channels): Encodes a 2D direction vector within the tangent-bitangent plane. Values stored in the \([0, 1]\) range are remapped to \([-1, 1]\) vectors: \[\text{Direction} = 2 \times \text{Texture.rg} - 1.0\] This 2D vector establishes a local tangent direction, which is then further rotated by anisotropyRotation.

Mathematical Interaction

During shader evaluation, the engine computes an anisotropy vector \(T_{aniso}\) on the surface plane by combining the texture-based direction vector (from the red and green channels) and rotating it by anisotropyRotation. The roughness along this direction is maintained at the base roughness, while the roughness perpendicular to it is scaled upward according to the computed final strength:

\[\alpha_t = \text{roughness}^2\] \[\alpha_b = \text{roughness}^2 \times \left(1.0 + \text{Final Strength} \times \dots\right)\]

This discrepancy between the parallel roughness (\(\alpha_t\)) and perpendicular roughness (\(\alpha_b\)) is what causes the specular highlight to appear visibly stretched perpendicular to the resolved tangent direction.