USD: Add MaterialX shader export #122575
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#122575
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "wave/blender_wave_Apple:dhruv/usd-materialx"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This change adds the ability to export MaterialX networks into the resulting
USD layer.
Details:
A new export option has been added to the USD export to enable MaterialX
export. It is off by default currently due to reasons in the caveats
section.
When enabled, it exports the MaterialX shading network alongside the
UsdPreviewSurface network, on the same USD Material. This allows the same
material to be used by renderers that don't support MaterialX, using the
USDPreviewSurface as a fallback. This is similar to setups in other DCC
packages, and matches the format we've used in our Reality Composer Pro
asset library.
It uses the existing MaterialX framework used to generate MaterialX
documents for rendering, to act as the basis for the USD graph. In this
process it also re-uses the existing texture export code as well if provided
and necessary.
Once the MaterialX document is created, use usdMtlx to generate a USD
shading network. Unfortunately, usdMtlx generates a graph that is unlike
what other DCCs that support MaterialX-embedded-in-USD generates. It
generates several extra prim hierarchies, and externalizes all shader
inputs, making them difficult to edit in other MaterialX graph editors.
To workaround this, generate the MaterialX shading network onto a
temporary stage, where we then run various pre-processing steps to prevent
prim collisions and to reflow the paths once they're converted.
The PrimSpecs are then copied over to their new path. The resulting prim
hierarchy matches what many artists we've worked with prefer to work with.
Caveats:
The Export MaterialX check is off by default. When using the Principled
BSDF, the resulting graph is very usable. However, when using some of the
other BSDFs, the shading networks generated by the existing MaterialX
framework in Blender generate some shading graphs that are difficult for
usdview and other DCC's to understand. The graph is still correct, but
because we're trying to prioritize compatibility, the default is off.
In future PRs we can aim to make the graphs for those other BSDFs play
better with other DCCs.
Other Implementation Details:
As part of this commit we've also done the following:
avoid node conflicts.
conflict cases.
to resolve header ordering issues. This has no effect on any runtime code.
make sure we get an export out the other end that matches our expectations
Authored by Apple: Dhruv Govil
This PR is based on an earlier implementation by Brecht van Lommel , as well
as Brian Savery and his teams' work at AMD to implement the general
MaterialX framework within Blender.
58c5b542ac
to3ac2827fd6
@ -544,3 +548,3 @@
"generate_preview_surface",
true,
"To USD Preview Surface",
"Export USD Preview Surface",
Leave out "Export" from label name, for consistency with other properties.
@ -39,0 +45,4 @@
#endif
#include <iostream>
#include <unordered_map>
Generally
BLI_map.hh
should be used instead.@ -1088,0 +1247,4 @@
* and modify it to match the final target location */
for (auto &temp_material_output : temp_material.GetOutputs()) {
pxr::SdfPathVector output_paths;
;
Stray
;
, here and various later instances in this function.@ -59,3 +62,4 @@
if (material->use_nodes) {
material->nodetree->ensure_topology_cache();
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
// Add a nodegraph for the material
Code style: use
/* */
@ -766,2 +766,3 @@
NodeItem res = empty();
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, type_str);
// Surfaceshader nodes and materials are added directly to the document, otherwise to the
// nodegraph
Code style: use
/* */
@blender-bot build
@ -13,8 +13,11 @@ class ExportImageFunction;
namespace blender::nodes::materialx {
using ExportImageFunction = std::function<std::string(Main *, Scene *, Image *, ImageUser *)>;
Getting a build error here, needed to add:
(It's because I have unity build disabled, which catches some missing header includes)
Can you add this code to make it so that it also works for our Hydra integration?
https://projects.blender.org/brecht/paste/src/branch/main/usd_hydra_materialx.patch
That way we can run the Storm render tests, enabled through
WITH_GPU_RENDER_TESTS
. These test rendering both through Hydra directly, and through loading an exported USD file in Hydra. There are some known differences (e.g. #122651), but we can at least manually check then if the results are as expected.In testing this, it seems this is breaking Hydra MaterialX export, and USD also does not appear to be using the MaterialX network. Reverting the changes made in
source/blender/nodes/shader/materialx/material.cc
appears to fix both.The issue can be reproduced as follows:
To test with USD export:
If you want to run the full tests, you need to merge with main to get the latest test reference images.
I edited the description to make it ready as a commit message, and added the "Authored by Apple" from the commit which I guess was unintentionally left out.
Thanks for the notes, @brecht . I'll get those sorted.
Still reviewing a bit but the biggest issue I've run into is that I can't get textures to be exported (both generated textures or ones with paths). I'm testing with "Export USD Preview Surface" disabled and only keeping "Export MaterialX Network" enabled. The material network is basically Image Texture -> Diffuse BSDF -> Output.
@ -39,0 +44,4 @@
# include <pxr/usd/usdMtlx/utils.h>
#endif
#include <iostream>
iostream is also unnecessary and can be removed.
@ -1088,0 +1174,4 @@
* This does mean that we need to pre-process the resulting graph so that there are no
* name conflicts.
* So we first gather all the existing names in this namespace to avoid that.*/
std::set<std::string> used_names;
Use
blender::Set
(like theblender::Map
feedback for the unordered_map)@brecht I'm looking into if there's a workaround for the EDF failure , but in the meantime I did also file an issue with Pixar because it is a problem on their end https://github.com/PixarAnimationStudios/OpenUSD/issues/3105
This only happens when using the Diffuse BSDF because it has to surface the node graph up from inside an ND_Surface node.
I checked against the latest commit (
3a2ea7828e
) inmain
and am seeing the same errors there. I therefore believe this is an issue that pre-dates this PR, and falls into the caveats+future work I had mentioned in my original description.@deadpin would you have a file I can test with? Preferably one with an embedded texture?
It was working for me in my simple case, but having more test cases would be really valuable so I can iron out the kinks.
I've addressed the rest of yours and Brecht's notes and will get an update pushed as soon as I can validate the texture export against your file.
@DhruvGovil Attached here.
Thanks, I can reproduce that it doesn't export textures if USD Preview Surface is off. Should be a quick fix.
Okay, I believe I've hit up all the notes above. @wave will upload the changes as soon as he can.
@brecht , I've also uploaded a patch to USD that will fix the issue you were reporting above. https://github.com/PixarAnimationStudios/OpenUSD/pull/3106
I'm not sure when this will get merged into mainline USD, but perhaps it would be good to merge the change on Blender's vendor version of USD?
Is the idea that Blender would still write out USD files that can't be rendered by the current version of Hydra Storm, and they would only start working in a future USD version? If so, that doesn't seem ideal.
The main purpose of Hydra Storm in Blender right now is more to verify what the results will be when others import the data, including quirks and bugs. We could apply the PR ourselves if we have no alternative.
Could we work around it by adding an EDF with color zero when it's not there, which I guess is what makes Principled BSDF work? Maybe there are some downsides regarding performance (would affect Principled BSDF too though) or messy node graphs.
Also to be clear, the Hydra MaterialX code path with diffuse BSDF is working in main for me, on Linux with OpenGL. But maybe not with macOS and Metal, I remember some extra issues there.
I can only do a partial review (due to time constraints), but the changes to the existing files (e.g.,
usd_writer_material.cc
, etc.) look good to me. I tested exporting MaterialX to Houdini and that seemed to work as expected.@DhruvGovil I did notice that texture coordinates must be named
st
and that the texture coordinate name provided in Blender'sUV Map
node is ignored. If I recall, this is a limitation in MaterialX support in USD. Is that correct?@makowalski Yes that's a limitation of USD's MaterialX translation currently. Is there a place where you resolve that name? It doesn't seem to make it into the MaterialX graph itself, so it's lost by the time it gets to my code that writes it out. Perhaps we could find a way to persist it through though. If you have a test file as well, that would be useful.
@brecht Apologies, I got confused between two sets of stacked errors in your example file.
The errors you mentioned above should be fixed now as soon as Wave can upload it. The issue there was that the Material name was being derived from Blender's name, which aren't always valid identifiers in USD. I now pre-convert them to a valid identifier. Which is why you don't see them prior to this PR.
However that still leaves the EDF issue in the resulting USD file with an EDF type, when using an ND_Surface node. Unfortunately that would require a patch in USD itself (as linked) because it just doesn't understand what an EDF is. Even connecting it to something would fail because it's looking up the shader registry within itself, and fails before it even parses the graph connections.
These are the ones I was also hitting on
main
as well, so pre-date this PR. If you're not hitting them on Linux, then I suspect the Pixar codepath only has the issue in the Metal path (though it does happen in the shared shader gen section so I am suspect). Those errors would look like this when a diffuse BSDF is loaded in Storm:Unfortunately, the state of USD+MaterialX is a bit raw at the moment, and my team is working with both projects + several DCC developers to fix them.
I think if you're not seeing the EDF issue on Linux, it's probably fine to not apply the USD patch mentioned above, and I can then work with Pixar to land it ASAP (earliest would likely be USD 24.8 at SIGGRAPH). My opinion would be that the EDF issue shouldn't be a blocker for this PR, if everything else looks alright (though of course I defer to you on that) since it'll be fixed in the upstream USD soon.
For
UsdPreviewSurface
we find aUV Map
node connected to theImage Texture
node and look up the name. If there is noUV Map
node, we use the name of the active UV map on the mesh as a guess. However, in my opinion, solving this for your MaterialX export is not a high priority. I would be fine with the assumption that the maps need to be namedst
in the initial commit.Ah that's good to know. Thinking about it now, the changes could in theory be completely on the MaterialX graph side by explicitly authoring geompropvalue nodes that have a stringed lookup of the primvar, which (like you said) probably lends itself to being a future PR since I would like to keep graph changes here to a minimum.
@DhruvGovil Thanks for the explanation. I have added the patch to our USD build in #122725.
So then we should be all good with the updated version of this PR.
3ac2827fd6
to488efe82e0
@brecht Okay, latest changes are pushed! Apologies for the delay getting them up.
I've included your patch as requested as well in this change.
As I mentioned earlier, I can only do a limited review, but the changes on the whole look good to me. With that caveat, I am approving this PR, so as not to block the commit once @deadpin and @brecht approve the latest changes.
Thanks, @makowalski
@blender-bot build
Testing this with our Storm render test, the Hydra regression is fixed.
For the USD path, the two main difference with Hydra are:
Probably best to merge as is an deal with texture coordinate issues afterwards.
@blender-bot build +gpu linux
@blender-bot build macos-arm64
@blender-bot build macos-arm64
I created a follow up issue for the texture coordinates in #122800.
Looks alright from my side too. I tested with the materials I had on hand, not many worked due to existing MaterialX conversion known issues, but nothing crashed Blender or
usdview
. Seems ok enough to continue from this point forward.Awesome, thanks @brecht and @deadpin ! Much appreciated :-)