Anisotropy
glTF extension: KHR_materials_anisotropy
glTF properties: anisotropyStrength · anisotropyRotation · anisotropyTexture
Anisotropy stretches specular highlights along a tangent direction, simulating surfaces such as brushed metal, hair, or satin fabric. Requires KHR_materials_anisotropy to be enabled in the export options.
| Shader | Strength attr | Rotation attr |
|---|---|---|
standardSurface, aiStandardSurface |
specularAnisotropy (or anisotropy) |
specularRotation (or anisotropyRotation) |
openPBRSurface |
specularRoughnessAnisotropy |
plugin-managed custom specularRotation |
StingrayPBS |
not supported | not supported |
The exporter checks the Standard Surface and Arnold-family strength and rotation attribute names in priority order: specularAnisotropy before anisotropy, and specularRotation before anisotropyRotation.
openPBRSurface is still a partial case: the importer maps anisotropy strength to the native OpenPBR anisotropy control, and preserves glTF anisotropyRotation in a plugin-managed custom specularRotation attribute. That preserves round-trip export fidelity, but it is not the same as native OpenPBR shading support for the rotation value.
The glTF anisotropy texture is a packed RGB image:
| Channel | Data |
|---|---|
| R | Anisotropy direction X |
| G | Anisotropy direction Y |
| B | Anisotropy strength |
Anisotropy strength
Factor only
Set the shader's anisotropy-strength attribute directly:
standardSurface, aiStandardSurface: shader.specularAnisotropy or shader.anisotropy
openPBRSurface: shader.specularRoughnessAnisotropy
Exports as anisotropyStrength. Only written when the value is greater than 0.0.
Texture only
Color space: Raw
Use the anisotropy texture path for both of these workflows:
- a packed glTF anisotropy map where
R/Gstore direction andBstores strength - separate grayscale source images that are lane-mapped through the first
multiplyDivideand packed during export
For packed glTF anisotropy maps, use one RGB texture with this channel layout:
R= direction XG= direction YB= strength
For separate grayscale source images, use this lane mapping:
direction X source -> multiplyDivide1.input1X
direction Y source -> multiplyDivide1.input1Y
strength source -> multiplyDivide1.input1Z
For true grayscale source images, you can use outColor, outColorR, outColorG, or outColorB, because all RGB channels contain the same value. The lane still determines the result: input1X exports as packed R, input1Y exports as packed G, and input1Z exports as packed B.
Anisotropy rotation
Scalar value only
Set specularRotation (or anisotropyRotation) directly on the shader.
The exporter converts the value to radians using these heuristics:
- Value in [−1, 1]: treated as normalized turns → multiplied by 2π
- Value in [−360, 360]: treated as degrees → converted to radians
- Otherwise: assumed to already be in radians
For standardSurface and aiStandardSurface, rotation is only exported when anisotropy strength is also active (factor > 0 or texture present). Exports as anisotropyRotation.
openPBRSurface importer-authored materials preserve anisotropy rotation in the custom specularRotation attribute and emit a warning that the value is being kept for round-trip export rather than native shader evaluation.
Via the packed anisotropy texture (importer-generated graph)
When a glTF file with anisotropy is imported, the importer builds a specific node graph to decode the packed texture. The exporter recognizes this graph on re-export and reconstructs the packed RGB anisotropy texture precisely.
Strength chain:
anisotropyTexture
→ multiplyDivide1.input1{X,Y,Z}
→ multiplyDivide1.output
→ plusMinusAverage1.input3D[0]
→ plusMinusAverage1.output3Dz
→ multiplyDivide2.input1X
(strength scalar) → multiplyDivide2.input2X
→ multiplyDivide2.outputX
→ shader anisotropy-strength attr
Rotation chain:
plusMinusAverage1.output3Dx/y
→ aiAtan
→ plusMinusAverage2.input3D[0]
(rotation offset in degrees) → plusMinusAverage2.input3D[1]
→ plusMinusAverage2.output3D
→ multiplyDivide3.input1
(2π) → multiplyDivide3.input2
→ multiplyDivide3.outputX
→ shader rotation attr
The exporter reads multiplyDivide2.input2X as anisotropyStrength, and the rotation degrees offset from plusMinusAverage2 as anisotropyRotation (converted to radians). If the three input channels of multiplyDivide1 come from separate grayscale textures, the exporter packs them into a new RGB image (R = X channel, G = Y channel, B = Z channel).
If the anisotropy graph uses nondefault banding, the exporter also rebakes packed anisotropy textures on export so the packed direction map stays aligned with the exported anisotropyRotation value.
Separate grayscale source images (exporter-authored packing)
The exporter also supports authoring anisotropy from separate grayscale source images and packing them into one glTF anisotropy texture during export.
Use the first multiplyDivide node as the semantic lane mapper:
X lane: source -> multiplyDivide1.input1X -> packed anisotropyTexture.R -> direction X
Y lane: source -> multiplyDivide1.input1Y -> packed anisotropyTexture.G -> direction Y
Z lane: source -> multiplyDivide1.input1Z -> packed anisotropyTexture.B -> strength
For true grayscale source images, the exporter can trace outColor, outColorR, outColorG, or outColorB, because all RGB channels contain the same value. The semantic meaning still comes from the destination lane on the first multiplyDivide:
multiplyDivide1.input1Xmeans tangent-space direction X and exports to packed RmultiplyDivide1.input1Ymeans tangent-space direction Y and exports to packed GmultiplyDivide1.input1Zmeans anisotropy strength and exports to packed B
Recommended lane wiring:
direction X map -> multiplyDivide1.input1X
direction Y map -> multiplyDivide1.input1Y
strength map -> multiplyDivide1.input1Z
This lane mapping applies equally to standardSurface, aiStandardSurface, and openPBRSurface. Only the final shader attrs differ:
standardSurface,aiStandardSurface:multiplyDivide2.outputX -> shader.specularAnisotropy,multiplyDivide3.outputX -> shader.specularRotationopenPBRSurface:multiplyDivide2.outputX -> shader.specularRoughnessAnisotropy,multiplyDivide3.outputX -> shader.specularRotation
UV transform
file nodes: set repeat, wrap, mirror, offset, and rotation on the connected place2dTexture.
aiImage nodes: wrap, scale, and offset export natively; rotation requires a place2dTexture.
UV set: assign via Maya's UV Set Editor or UV Linking - see UV Set Selection for node-type differences.
Notes
- Always use
Rawcolor space for anisotropy textures. - The packed glTF anisotropy texture uses R/G = direction XY and B = strength.
- For true grayscale sources, the exporter can accept
outColor,outColorR,outColorG, oroutColorB, but the firstmultiplyDividelane still determines the packed glTF meaning: X -> R/direction X, Y -> G/direction Y, Z -> B/strength. - For separate grayscale anisotropy maps, wire direction X to
multiplyDivide1.input1X, direction Y tomultiplyDivide1.input1Y, and strength tomultiplyDivide1.input1Z. - Rotation is only exported when anisotropy strength is active.
- The exporter probes Standard Surface and Arnold-family attribute names in priority order:
specularAnisotropybeforeanisotropy, andspecularRotationbeforeanisotropyRotation. - Imported
openPBRSurfacematerials keep anisotropy strength and preserve anisotropy rotation in the customspecularRotationattribute for round-trip export. - Round-tripped materials (imported from glTF then re-exported) are handled by an importer-graph detection path that reconstructs the packed texture. When anisotropy banding differs from the default, the exporter rebakes the packed map so the exported texture and rotation stay in sync.
StingrayPBSdoes not exportKHR_materials_anisotropy.