MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Advice on creating a MaterialX importer/exporter for Blender

Open bhouston opened this issue 5 months ago • 5 comments

Hi all!

I'm trying to create a MaterialX exporter/importer for Blender.

I wrote something quick in Python here for exporting:

https://github.com/bhouston/materialx_addon

It mostly works for export for a lot of nodes, but I am wondering what I am losing/missing by writing it all in Python and not making use of the MaterialX Python Bindings?

I definitely am not going to try to build MaterialX for multi-platforms and distribute it with my add-on, it is too complex. But I am wondering if there are significant missing features as a result that I could use to try to convince Blender to start to ship MaterialX's python bindings.

Or maybe MaterialX already has a pure python library that I could make use of? For say parsing/generating XML from a Python-native graph representation with validation or even transformations? Honestly, that would be so useful.

BTW I could contribute this Addon to this project if it is of interest and my implementation matures a bit past prototype.

Thanks for any help!

bhouston avatar Aug 05 '25 19:08 bhouston

Hi @bhouston

Blender / bpy should already ship with MaterialX Python libraries so it seems that that would be the simplest and consistent way to go. You could (also) install your own version of MaterialX from PyPi. I think things could easily break via a pure XML route as you lose things like validation, upgrade mechanism, syntax / semantic changes etc.

I did an small sample export a few years ago here if you want to jave a look. It only did a couple of upstream nodes and the main shader.

I would be quite interested in how this progresses as I was looking to improve my own Blender export plug-in.

As for "add-ons", @jstone-lucasfilm, this topic has come up in the past. I wonder if it's worth to bring up for discussion where these types of utilities could land as I think we thought it was a good idea but that they did not belong in this repo since it's not "core" functionality ?

(BTW, I thought that there was an official project to export MaterialX, or perhaps that was USD ? ( i.e. a Blender -> UsdShade -> MaterialX export is possible though probably too much overhead ).

kwokcb avatar Aug 05 '25 20:08 kwokcb

Thanks @kwokcb . I'm incorporating your ideas now!

bhouston avatar Aug 06 '25 16:08 bhouston

Okay, I've made a refactor that utilizes the MaterialX Python interface as well as your mtlxutil functions @kwokcb!

https://github.com/bhouston/blender_materialx_addon/pull/3

bhouston avatar Aug 06 '25 19:08 bhouston

I have another question for you @kwokcb and @jstone-lucasfilm, how should I handle Blender nodes without direct equivalents in MaterialX? Should I export them with custom names and then post export, I would like to run a process that replaces the custom nodes with emulation node networks. Basically it is like exporting MACROS and then running the MACRO replacements to expand them. This seems clean and I could define the emulation networks in a materialx file that ships with the plugin rather than writing these emulation networks in the Python plugin itself.

For example, Brick texture, the different parameterizations of the Noise texture node.

Is that possible?

bhouston avatar Aug 06 '25 21:08 bhouston

Hi @bhouston , Let me know if this fits what your looking for. I'll be more verbose since I'm not sure how familiar you are with MaterialX.

  • You can define custom node definitions for Blender-only nodes if you like. These are nodedef elements. You can define whatever inputs and outputs you need. You can define a set of these within a MaterialX file and instantiate instances of them.
  • I think what you call "emulation node networks" can be accomplished by define the implementation of the definition as a graph (nodegraph elements). They can do whatever you want including just making them do a pass-through.
  • You would load in this MaterialX file as an additional "library" of definitions.

You can off course build definitions on top of existing definitions if so desired or just use the existing definitions in the "core" library.

This has the following upside:

  • There is no "special" injection of meta-data or other constructs which isn't natively supported by MaterialX.
  • You can expand them using built in functionality in MaterialX (there is a "flatten" utility which can be applied to convert definitions into their implementation graph nodes.
  • I assume this will help with ThreeJS conversion, but would also help glTF and USD consumption.

For reference the "core" definitions are defined here: https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/stdlib_defs.mtlx and the graph implementation here: https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/stdlib_ng.mtlx

If you think this is a good direction to follow, more details about how to create the graph implementation and definitions can be provided... This is already a long response :).

kwokcb avatar Aug 07 '25 03:08 kwokcb