Translation for specular anisotropy, rotation from Standard surface to gltf_pbr
Changes
Adds translations for specular_anisotropy and specular_rotation from standardSurface to gltf_pbr
Renders
Material from AMD GPU Open MaterialX Library- Aluminum Brushed
Standard Surface - OSL Render |
Translated to gltf_pbr - OSL Render |
|---|
Standard Surface - GLSL MaterialXGraphEditor |
Translated to gltf_pbr - GLSL MaterialXGraphEditor |
|---|
Before / After PR
Before PR - Translated to gltf_pbr - OSL Render |
After PR - Translated to gltf_pbr - OSL Render |
|---|
Description
I have created a transfer function going from standard surface input for specular_roughness, specular_anisotropy, specular_rotation to glTFs roughness, anisotropy_strength, anisotropy_rotation
Visual implementation of the added parts in the translation graph. Highlighted inputs are interfaced inputs.
Anisotropy Strength & roughness
Roughness anisotropy defined in Standard Surface
def mx_roughness_anisotropy(roughness: float, anisotropy: float) -> tuple[float, float]:
roughness_sqr = clamp(roughness*roughness, sys.float_info.epsilon, 1.0 )
if anisotropy > 0.0:
aspect = math.sqrt(1.0 - clamp(anisotropy, 0.0, 0.98))
rx = min(roughness_sqr, aspect, 1.0)
ry = roughness_sqr * aspect
return (rx, ry)
return roughness_sqr,roughness_sqr
Roughness anisotropy defined in gltf_pbr
def gltf_roughness_anisotropy(roughness: float, anisotropy: float) -> tuple[float, float]:
alphaRoughness = clamp(roughness*roughness, sys.float_info.epsilon, 1.0 )
at = mix(alphaRoughness, 1.0, anisotropy * anisotropy)
ab = alphaRoughness
return at,ab
Transfer function used in this PR
def transform_mx_to_gltf_inputs(roughness_mx: float, anisotropy_mx: float) -> tuple[float, float]:
separate_roughness_x, separate_roughness_y = mx_roughness_anisotropy(roughness_mx, anisotropy_mx)
roughness_gltf = math.sqrt(separate_roughness_y)
numerator = separate_roughness_x - separate_roughness_y
denominator = 1.0 - separate_roughness_y
if denominator <= 0:
anisotropy_gltf = 0.0
else:
anisotropy_gltf_sq = numerator / denominator
anisotropy_gltf = math.sqrt(anisotropy_gltf_sq)
return roughness_gltf, anisotropy_gltf
Plots of the results
mx_roughness_anisotropy |
gltf_roughness_anisotropy |
transform_mx_to_gltf_inputs -> gltf_roughness_anisotropy |
|---|
Anisotropy Rotation
Standard surface have it's rotation maped between [0-1] where 1 is a complete rotation, in the MaterialX implementation it's currently in clockwise direction. Note that it may change: #2083
glTF uses radiance, i.e a complete rotation is 2*PI, glTF rotation is defined as counter-clockwise.
Transfer function is implemented as a multiplication with negative 2*PI