Export material to MaterialX for Hydra render #111765
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
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
EEVEE & Viewport
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
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
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
EEVEE & Viewport
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
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
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
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#111765
Loading…
Reference in New Issue
No description provided.
Delete Branch "DagerD/blender:matx-export-material"
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?
Purpose
Significant part of Hydra render engine integration from #104712 is export Blender's material nodegraph to MaterialX nodegraph which automatically can be translated to USD shaders and use by Hydra render delegates.
Done
Created node parsing system in
bf_nodes_shader
project. Placed intosource/blender/nodes/shader/materialx
folder. It consists:class NodeParser
which provides required functionality for walking through node tree and translating blender node into MaterialX.compute()
method.NodeParser
operates with objects ofclass NodeItem
which simplifies work with MaterialX nodes and values: implements arithmetic functions and other math functions, simplifies work with node inputs and outputs.Added
bl_use_materialx
to Render engine property. When it is set, MaterialX is utilized for exporting materials to Hydra. Code moved from #111219.Already implemented export of following blender nodes: BSDFPrincipled, Invert, Math, TexChecker, TexEnvironment, TexImage, TexNoise.
Added
CLOG
logger to node parsing system.TODOs
NodeItem
to use enums instead string constants.See my comments about not converting parts of the node tree to materialx. There are many places this happens, please change.
@ -0,0 +17,4 @@
NodeItem subsurface = get_input_value("Subsurface");
NodeItem subsurface_radius = empty();
NodeItem subsurface_color = empty();
if (subsurface != zero) {
I would argue here.... for completeness that we should export the full node tree, even if some parts of it are "inactive".
E.G. Here we only convert the part of the tree with Subsurface Color input if subsurface is turned on. One could imagine that someone wants to take that exported materialx and then turn on the subsurface, then the part for the subsurface color is missing.
It's up to the MaterialX code generation and compiler to prune parts of the node tree that aren't needed. Not here.
This is done
Overall seems quite straightforward to understand.
Note sure how hard it would be to move the MaterialX export code into the existing shader node files, but I think it's important. I think it should be possible without too many changes to the overall design. Worst case you could have some begin/end macros that do the class and callback function definition, with the compute implementation between the two.
@ -210,2 +210,4 @@
endif()
if(WITH_MATERIALX)
list(APPEND LIB MaterialXCore)
Add
add_definitions(-DWITH_MATERIALX)
@ -12,6 +12,9 @@
#include <pxr/imaging/hd/tokens.h>
#include <pxr/usdImaging/usdImaging/materialParamUtils.h>
#include <pxr/usd/usdMtlx/reader.h>
Add
#ifdef WITH_MATERIALX
here and other places in this file, to make it possible to build without materialx.@ -24,0 +24,4 @@
if(WITH_HYDRA)
list(APPEND INC
../../io/usd
../../../../intern/clog
Add clog the general includes, not need to have this conditional.
@ -139,0 +175,4 @@
materialx/nodes/tex_environment.cc
materialx/nodes/tex_image.cc
materialx/nodes/tex_noise.cc
materialx/nodes/vector_math.cc
Can the code for all these node types move into the corresponding
source/blender/nodes/shader/nodes/node_shader_*.cc
file? We are trying to make node implementations self contained instead of spread across multiple files.Otherwise it's likely developers will forget to update the materialx code when making changes.
A new callback would be added to
bNodeType
, similar togpu_fn
, that would convert the node to materialx.@ -0,0 +23,4 @@
MaterialX::DocumentPtr doc = MaterialX::createDocument();
if (material->use_nodes) {
material->nodetree->ensure_topology_cache();
This should create a temporary copy of the node tree with
ntreeLocalize
, similar as is done for generating the GLSL shader. That will resolve any muting and reroute nodes, as handling them as part of the export process is not easy.Node groups might ideally be preserved in export, but it would be easiest to start with exporting them expanded. For this it would be easiest to use the functions also called from
ntreeGPUMaterialNodes
:Exporting of group nodes is implemented in
materialx/group_nodes.cc/.h
@ -0,0 +29,4 @@
case NodeItem::Type::SurfaceShader: {
res = get_input_shader(0, shader_type_);
if (!res) {
res = get_input_shader(1, shader_type_);
Can you add a comment explaining this logic, why it picks one or the other instead of adding? Is this something that can be improved?
@ -0,0 +31,4 @@
break;
}
case NodeItem::Type::SurfaceShader: {
res = get_input_shader(1, NodeItem::Type::SurfaceShader);
Similar questions as add shader, not sure what this is doing.
@ -0,0 +8,4 @@
namespace blender::nodes::materialx {
class NodeItem {
Can you add a comment explaining what this class is?
@ -0,0 +51,4 @@
static std::string type(Type type);
/* Operators */
operator bool() const;
Can you change this to
bool is_empty() const
? I would only use operator overloading when the meaning is more clear.Such bool operator is used during the code in several places, for example:
And seems for me it suits there very nice. Are you sure using
is_empty()
would be better?Ok, we can keep it as is since it's a bit like a null pointer check.
@ -0,0 +136,4 @@
break;
switch (from_node->typeinfo->type) {
CASE_NODE_TYPE(SH_NODE_BRIGHTCONTRAST, BrightContrastNodeParser)
If there is a node type callback, this switch statement will not be needed anymore.
@ -0,0 +20,4 @@
/* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains
* pretty general code, so could be moved from bf_usd project. */
#ifdef WITH_HYDRA
image_path = io::hydra::cache_or_get_image_file(bmain, scene, image, &tex->iuser);
Can thiscallback function somehow that can be provided by the code that calls the MaterialX conversion?
That would also avoid the dependency of the shader nodes module on the USD module.
A more concrete proposal for how to move the code into the node files. There could be macros like these:
Used like this in the node files:
Thanks, that reorganization looks good. Marking as request changes since there remain other comments to address.
@ -225,6 +225,9 @@ typedef int (*NodeGPUExecFunction)(struct GPUMaterial *mat,
struct bNodeExecData *execdata,
struct GPUNodeStack *in,
struct GPUNodeStack *out);
typedef void (*NodeMaterialXExecFunction)(void *data,
I would name this just
NodeMaterialXFunction
, theExec
is from a time when these functions actually executed the nodes.If you haven't already, please run the Hydra regression tests to identify problems. It will output a webpage where you can compare the results to cycles to see how closely it matches.
@blender-bot build
@brecht can you remind please how to do this? Which commands to run?
https://wiki.blender.org/wiki/Tools/Tests/Setup
Assuming you have the test files downloaded.
WITH_OPENGL_RENDER_TESTS=ON
and rebuild.make test
will work, butctest -C Release -R storm
from the build folder will be faster to run just the Storm teststests/report.html
in the build folder with the resultsPlease see the Linux build log for some warnings/errors to fix:
https://builder.blender.org/admin/#/builders/132/builds/2398
Group nodes don't seem to work reliably for me, two cases that didn't work:
shader/node_group_color.blend
renders white when it should be green, ignoring the color set on the group.There's some tricky logic with default values and socket type conversions that is not easy to get right and difficult to verify. That's why I suggested to simply expand the node groups to begin with. But it's up to you if really want to get this working well for 4.0.
@ -74,0 +82,4 @@
scene_delegate_->depsgraph, (Material *)id);
pxr::UsdMtlxRead(doc, stage);
/* Logging stage: creating lambda stage_str() for not to call stage->ExportToString()
for not to -> to not
@ -0,0 +68,4 @@
Vector<NodeItem> outputs;
for (int i = 0; i < values.size(); ++i) {
if (values[i]) {
outputs.append(create_output("output" + std::to_string(i + 1), values[i]));
Can you explain why this is using
output + index
rather than output socket names?I guess it's not to avoid naming conflicts, because
output1
isn't unique enough that a user would never name their socket like this.Changed name to
out_<out socket name>
A reminder that this should be merged before next Wednesday to get included in the 4.0 release.
At the moment it's unclear to me what exactly the status is, how many more changes are still planned. As long as this is marked "WIP" I assume this is not ready to merge yet.
Thank you for reminder. We are almost on finish line.
Our status: implemented almost all nodes available in Cycles. Currently polishing, reviewing and testing their implementation. Trying to implement TODOs in code as much as possible.
TODOs:
io::hydra::cache_or_get_image_file
I think on Monday those TODOs will be ready except polishing and we'll be ready for merge.
Most of issues were fixed. Polishing of implemented nodes are required + implement some remaining nodes. But this could be done after 4.0 release. Next several days we'll be spending on testing and bug fixing.
I think we are ready for merge at this stage. Please review.
@blender-bot build
Please document and not all nodes that are not supported yet.
I've been testing this and it's pretty awesome! There are a few things that aren't at all blockers for getting this merged, but that I want to note for future work.
--log 'materialx.shader'
flag.subsurface_radius
:Node interface error: Input 'subsurface_radius' doesn't match declaration: <standard_surface name="Principled_BSDF" type="surfaceshader">
. This is probably due to a version mismatch and should be an easy fix.Hello, we created document with statuses for all nodes available in Cycles
https://docs.google.com/spreadsheets/d/1U-jJ6QVpR4Dam6QDPoyUBYlScWQHYxfLGdDeX1eeNN8/edit#gid=0
WIP: Export material to MaterialX for Hydra renderto Export material to MaterialX for Hydra render@blender-bot build
This is fixed in DagerD/blender#34
There will be some PRs with node polishing today
We've finished polishing code. Ready for merge
@blender-bot build
I copied the spreadsheet to #112864, since we like to track development on our own platform, and avoid referencing third party websites from release notes or the user manual.