Skip to content

Conversation

@bhouston
Copy link
Contributor

@bhouston bhouston commented Jul 17, 2025

Description

Adds support for the following MaterialX core nodes:

  • ln
  • transform matrix
  • transpose
  • determinant
  • invert matrix
  • creatematrix
  • length
  • crossproduct
  • ceil
  • floor
  • place2d
  • reflect
  • refract
  • ifgreater
  • ifgreatereq
  • ifequal
  • rotate2d
  • rotate3d
  • heighttonormal
  • separate
  • uniformnoise2d
  • uniformnoise3d
  • ramp4
  • extract

Add support for standard_surface material inputs:

  • opacity
  • specularIntensity
  • specularColor
  • ior, anisotropy
  • anisotropyRotation
  • sheen intensity
  • sheen color
  • sheen roughness
  • thin film thickness
  • thin film ior
  • transmission
  • transmissionColor.

Improved handling of material rendering modes:

  • Automatically becomes "transparent" if opacityNode or transmissionNode is defined.
  • Automatically becomes DoubleSided is transmissionNode is defined.
  • Automatically has iridescence set to 1.0 if thinFilmThicknessNode is defined.

These were motivated by the fact that Blender exports these MaterialX nodes, but ThreeJS doesn't support them.

I've included a bunch of new mtlx example files that demonstrate the new features!

This contribution is funded by DriveCore, Inc.

The new materialx loader example results:

Screenshot 2025-07-18 at 10 58 28 AM

What it looks like before this PR (notice that even the original materials now look better):

Screenshot 2025-07-18 at 10 15 41 AM

bhouston added 2 commits July 17, 2025 13:05
…rminant, invert matrix, creatematrix, length, crossproduct, floor, place2d, reflect, refract, ifgreater, ifgreatereq, ifequal, rotate2d, rotate3d, heighttonormal
@github-actions
Copy link

github-actions bot commented Jul 17, 2025

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 338.39
78.91
338.39
78.91
+0 B
+0 B
WebGPU 561.91
155.44
565.6
156.35
+3.69 kB
+906 B
WebGPU Nodes 560.51
155.2
564.21
156.1
+3.69 kB
+905 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 469.77
113.61
469.77
113.61
+0 B
+0 B
WebGPU 636.77
172.32
636.95
172.36
+178 B
+45 B
WebGPU Nodes 591.42
161.55
591.6
161.59
+178 B
+34 B

@sunag sunag added this to the r179 milestone Jul 17, 2025
@bhouston
Copy link
Contributor Author

bhouston commented Jul 18, 2025

@sunag, do you know why the mx_ nodes are defined in two places and what makes one choose one location over the other:

export const mx_aastep = ( threshold, value ) => {

const mx_add = ( in1, in2 = float( 0 ) ) => add( in1, in2 );

I put all my new nodes in the MaterialXLoader, but I just tried to minimize changes to the code of ThreeJS.

But I think it may be best to have a separate MaterialXNodes that is not in the core ThreeJS package and can be referenced by the MaterialXLoader as well as other files, like the upcoming GlTF support for MaterialX node graphs.

@sunag
Copy link
Collaborator

sunag commented Jul 18, 2025

@sunag, do you know why the mx_ nodes are defined in two places and what makes one choose one location over the other:

These Nodes were created specifically for MaterialXLoader because TSL has its own equivalents, like add instead of mx_add. But we can move them all to MaterialXNodes as well.

Awesome work 🚀

@bhouston
Copy link
Contributor Author

@sunag it turns out a bunch of examples use the mx_ functions, particularly the noise functions, from the TSL nodes:

  • webgpu_lights_projector
  • webgpu_tsl_procedural_terrain
  • webgpu_tsl_raging_sea

Hmm... not sure how to handle this.

@bhouston bhouston force-pushed the improved_materialx_support branch from c2b4c03 to 6f718eb Compare July 21, 2025 15:26
@sunag
Copy link
Collaborator

sunag commented Jul 21, 2025

But I think it may be best to have a separate MaterialXNodes that is not in the core ThreeJS package and can be referenced by the MaterialXLoader as well as other files, like the upcoming GlTF support for MaterialX node graphs.

Sorry @bhouston , I didn't pay attention to that. Wouldn't it be better to just move the new nodes to MaterialXNodes and keep them in the core? It supports tree-shaking and many users already use it this way.

@bhouston bhouston force-pushed the improved_materialx_support branch from 758627b to 74b25c7 Compare July 21, 2025 19:03
@bhouston
Copy link
Contributor Author

@sunag I've made the requested change and centralized all mx_* nodes into MaterialXNodes within the src/nodes/MaterialX directory.

@bhouston bhouston force-pushed the improved_materialx_support branch from b329b01 to 3ee58ab Compare July 22, 2025 15:34
@bhouston bhouston force-pushed the improved_materialx_support branch from 3ee58ab to de36b38 Compare July 22, 2025 16:07
@bhouston
Copy link
Contributor Author

@sunag - I got a nasty merge conflict and then I messed up git and somehow lost your branch and got a nasty conflict - so I undid all that. Can you re-push your changes with a new name as I've lost them? I've kept working on this branch without your changes.

I just added proper "time" support and a time example. :)

@sunag sunag merged commit fe5f4b2 into mrdoob:dev Jul 27, 2025
9 checks passed
@DennisSmolek
Copy link

@bhouston How are you getting your nodes out of Blender? I

@jo-chemla
Copy link
Contributor

jo-chemla commented Aug 2, 2025

@bhouston mentioned this addon he's been working on bhouston/materialx_addon

in the glTF-Blender-IO discussion here KhronosGroup/glTF-Blender-IO#2582 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants