[MAX-MAT-001] Strip buggy specular_rotation=0.25 from MaterialX export - #36
Open
doug-smith-miris wants to merge 1 commit into
Open
Conversation
3ds Max's MtlxIOUtil bridge hardcodes specular_rotation=0.25 on every ND_standard_surface_surfaceshader, regardless of source PhysicalMaterial anisotropy. The MaterialX nodedef default is 0.0; the value has no visual effect when specular_anisotropy is zero (the BSDF multiplies them), but it silently introduces a 90deg highlight rotation if a downstream layer turns anisotropy on. Add a post-parse normalization pass in MtlxShaderWriter::Write that walks the parsed MaterialX document and drops specular_rotation from standard_surface nodes when: * the value is statically 0.25 (the bug pattern), AND * specular_anisotropy is absent or statically 0.0. Connected anisotropy, any non-0.25 rotation value, and connected rotation are conservatively left untouched. Validated against the diagnostic corpus (samples/complex_export.usda): 6/6 affected materials cleaned, Karma renders byte-identical pre/post (SHA-256 match — semantic-only fix). Synthetic negative test (BrushedSteel with specular_anisotropy=0.4) confirms the fix is surgical and preserves intentional rotation. Also adds doc/translation-mapping.md to track 3ds Max -> MaterialX property mappings going forward, and a MaxScript regression test in mtlxShaderWriter_test.ms. Build/run validation deferred: 3ds Max is Windows-only and this repo builds via Visual Studio (configure-vsdevcmd.bat). The Python validator in the arch-build dir mirrors the C++ logic exactly at the USD layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
3ds Max's
MtlxIOUtil.ExportMtlxStringMaxScript bridge writesspecular_rotation = 0.25on everyND_standard_surface_surfaceshader, regardless of source PhysicalMaterial anisotropy. The MaterialXstandard_surfacenodedef default is 0.0, andspecular_rotationis multiplied byspecular_anisotropyin the BSDF — so when anisotropy is 0 (the universal default case), the value has zero observable effect, but it silently corrupts downstream pipelines that read MaterialX values directly or layer-override anisotropy later.This PR adds a post-parse normalization step in
MtlxShaderWriter::Write()that dropsspecular_rotationfromstandard_surfacenodes when:specular_anisotropyis absent OR statically zero.Connected anisotropy, any non-
0.25rotation, or a connected rotation input are all left untouched, so the fix is surgical and does not touch genuinely-authored anisotropic materials.Diagnostic finding
MAX-MAT-001-specular-rotation-default-0.25samples/complex_export.usdaaffectedWhat's changed
src/translators/MtlxShaderWriter.cpp— adds_NormalizeStandardSurfaceSpecularRotation, called immediately afterreadFromXmlString.src/Tests/Integration/mtlxShaderWriter_test.ms— addstest_export_physical_material_strips_buggy_specular_rotation, a regression test that creates a defaultPhysicalMaterial, exports it via MaterialX, and assertsspecular_rotationis either absent or 0.0.doc/translation-mapping.md— new tracking doc for 3ds Max -> MaterialX property translation status. MAX-MAT-001 is the first row.doc/changelog.md— Unreleased entry.Validation
3ds Max is Windows-only and this repo builds via Visual Studio (
configure-vsdevcmd.bat). I cannot build or run the plugin on macOS, so I validated by mirroring the C++ logic in Python at the USD layer (normalize_specular_rotation.pyin the arch-build dir):samples/complex_export.usdastrips exactly the 6 known-bogusspecular_rotation = 0.25lines and changes nothing else (USDA diff = 6 deletions, 0 additions, 0 modifications).eaf3832840…b8351). This is the expected outcome:specular_rotation*specular_anisotropy= 0 when anisotropy is 0, so the lighting integrator never sees the value.specular_anisotropy = 0.4onto one shader. The normalizer correctly preservesspecular_rotation = 0.25on that shader while still stripping it from the other 5. Confirms the fix is surgical.Build / run status
Status
Opening for review. The C++ change is straightforward and has clear semantics, but a Windows build/test pass is needed before this is merge-ready. The visual evidence and Python-validated post-fix USD strongly suggest the change is correct.