MaterialX + String path attributes?
7833 22 4- guilhermecasagrandi
- Member
- 274 posts
- Joined: March 2011
- Online
- rafal
- Staff
- 1454 posts
- Joined: July 2005
- Offline
Indeed. The MaterialX standard indicates that string inputs must be uniform.
Attributes for NodeDef Input elements:
- uniform (boolean, optional): if set to "true", then this input can only take uniform values and may not be connected to the outputs of other nodes. uniform must be set to true for string and filename-type inputs.
So for now the MaterialX shader VOPs don't provide an input for string parameters.
That's something we will need to revisit in the future.
Attributes for NodeDef Input elements:
- uniform (boolean, optional): if set to "true", then this input can only take uniform values and may not be connected to the outputs of other nodes. uniform must be set to true for string and filename-type inputs.
So for now the MaterialX shader VOPs don't provide an input for string parameters.
That's something we will need to revisit in the future.
- jsmack
- Member
- 8026 posts
- Joined: Sept. 2011
- Online
rafal
Indeed. The MaterialX standard indicates that string inputs must be uniform.
Attributes for NodeDef Input elements:
- uniform (boolean, optional): if set to "true", then this input can only take uniform values and may not be connected to the outputs of other nodes. uniform must be set to true for string and filename-type inputs.
So for now the MaterialX shader VOPs don't provide an input for string parameters.
That's something we will need to revisit in the future.
Does that mean the only way to vary the texture across different prims is to instance the material? That seems unnecessarily limiting. MaterialX is taking the approach of least common denominator, rather than osl's broad spec where coverage varies by the implementation.
Edited by jsmack - Dec. 17, 2021 11:07:43
- guilhermecasagrandi
- Member
- 274 posts
- Joined: March 2011
- Online
rafal
Indeed. The MaterialX standard indicates that string inputs must be uniform.
Attributes for NodeDef Input elements:
- uniform (boolean, optional): if set to "true", then this input can only take uniform values and may not be connected to the outputs of other nodes. uniform must be set to true for string and filename-type inputs.
So for now the MaterialX shader VOPs don't provide an input for string parameters.
That's something we will need to revisit in the future.
Thanks Rafal. At least in a crowd workflow, that's a problem because we don't have a "good" way to apply several different textures using a single shader. For now, I'll stick with vex for that.
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
Hi there;
I'm trying to solve a problem that I describe in this other thread [www.sidefx.com], which sounds very similar to what y'all are discussing here. But, in trying to learn whether Material Stylesheets might be a way to approach this problem, I also found this thread [www.sidefx.com], where Rafal offers a very helpful file with lots of examples of doing similar work at the primitive level in LOPS.
An example showing this exact issue - driving the value of a filename parameter on a MaterialX Texture node - isn't covered in Rafal's file, but a post later down the thread describes a 'hack' for feeding prim string attributes into the renderer, which leaves me a little confused as to whether a path exists for what I'm after (or, if not, whether it might be forthcoming in H19.5)?
I'm trying to solve a problem that I describe in this other thread [www.sidefx.com], which sounds very similar to what y'all are discussing here. But, in trying to learn whether Material Stylesheets might be a way to approach this problem, I also found this thread [www.sidefx.com], where Rafal offers a very helpful file with lots of examples of doing similar work at the primitive level in LOPS.
An example showing this exact issue - driving the value of a filename parameter on a MaterialX Texture node - isn't covered in Rafal's file, but a post later down the thread describes a 'hack' for feeding prim string attributes into the renderer, which leaves me a little confused as to whether a path exists for what I'm after (or, if not, whether it might be forthcoming in H19.5)?
Edited by dhemberg - May 17, 2022 20:58:39
- jsmack
- Member
- 8026 posts
- Joined: Sept. 2011
- Online
dhemberg
I'm trying to solve a problem that I describe in this other thread , which sounds very similar to what y'all are discussing here. But, in trying to learn whether Material Stylesheets might be a way to approach this problem, I also found this thread , where Rafal offers a very helpful file with lots of examples of doing similar work at the primitive level in LOPS.
That problem is not entirely relevant to the one here. Feeding varying numerical attributes to MaterialX shaders is fairly trivial. This thread was about strings in particular.
dhemberg
An example showing this exact issue - driving the value of a filename parameter on a MaterialX Texture node - isn't covered in Rafal's file, but a post later down the thread describes a 'hack' for feeding prim string attributes into the renderer, which leaves me a little confused as to whether a path exists for what I'm after (or, if not, whether it might be forthcoming in H19.5)?
The 'hack' refers to using stylesheets to connect attributes to cryptomattes via user properties overrides. This hack is not required for Karma, as driving cryptomattes with primvar attributes is also trivial.
Varying texture paths on MaterialX shaders in LOPs is basically a non-starter. There's no plug on the texture node, so not much you can do besides authoring opinions directly to the mtlx image node.
Edit:
attached example of how you might edit the texture prims directly just using usd overrides.
Edited by jsmack - May 17, 2022 22:22:48
- brians
- Staff
- 526 posts
- Joined: May 2019
- Offline
guilhermecasagrandi
At least in a crowd workflow, that's a problem because we don't have a "good" way to apply several different textures using a single shader. For now, I'll stick with vex for that.
You could use UDIMs?
So...
- arrange your textures in the UDIM tiled format
- have an integer primvar
- "add" the integer primvar to the input UV's in the shader graph (to match the UDIM textures on disk)
Another option is to again have an integer primvar, and use a switch node to select the correct texture result in the shader (although this would be more clunky, and also slower...)
Another option again might be to use the usdPrimVarReader and the usdUVTexture nodes. They allow for a procedurally-driven file string. I know they won't work in XPU (yet), but it might be an option for KarmaCPU.
Edited by brians - May 18, 2022 01:51:36
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
brians
Another option again might be to use the usdPrimVarReader and the usdUVTexture nodes. They allow for a procedurally-driven file string. I know they won't work in XPU (yet), but it might be an option for KarmaCPU.
Could I trouble you to elaborate on this bit? It's not quite clear to me how to connect the two nodes you mention.
Similar questions abound in the Redshift forums, with some interesting trickery using OSL to bridge the gap between these two things, though ultimately the devs there point to using Material Stylesheets as a way to solve this. Of course, Redshift isn't as intimately tied to USD, and so I realize there's lots of new caveats and constraints once we enter Solaris + MaterialX.
I appreciate the other suggestions; they're – as you say – a bit more clunky/intrusive, but I appreciate hearing new ideas. For my own part I would love to not have to re-generate textures to address the UDIM approach, nor architect a difficult-to-extend (and likely error-prone) switch node approach within a material builder. In my particular case, I have around 100 branch models, so either of those are a little unwieldy for me. It's not that I feel lazy about it, I just worry about maintaining it in a procedural pipeline.
The swanky way Karma + Material Stylesheets/Principled Shader parameter overrides works now is so dreamy and elegant. I was interested to hear what strategies others might be exploring; it's reassuring to hear I'm not the only one with this problem.
- goldleaf
- Staff
- 4195 posts
- Joined: Sept. 2007
- Offline
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
Ahhhh; the critical thing I missed here is that there is a MaterialX usdUVTexture node as well as a, um, non-mtx usdUVTexture node; the former does not provide a string input, and it wasn't clear to me that mixing and matching materialX and non-materialX nodes was ok!
Thank you! This is very helpful.
Thank you! This is very helpful.
- goldleaf
- Staff
- 4195 posts
- Joined: Sept. 2007
- Offline
No problem; and I forgot to caveat, but mixing MtlX with USD Preview nodes will only work with Karma.
If you create a "Karma MaterialX Subnet" inside of Material Library, your tab menu will be filtered to nodes that work with together and are compatible with Karma CPU (Karma XPU being is in alpha still, of course ).
If you create a "Karma MaterialX Subnet" inside of Material Library, your tab menu will be filtered to nodes that work with together and are compatible with Karma CPU (Karma XPU being is in alpha still, of course ).
I'm o.d.d.
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
Hi again;
I was so excited to jump over into H19.5, hoping that I might be able to finally get to use XPU on the scene to which I refer earlier in this thread. This scene has a uniform string primvar on some geometry specifying a texture file I would like to use as my basecolor.
The strategy of mtx_USD_primvar_reader -> USD_uv_texture -> MTX_standard_surface works splendidly for Karma CPU, but still seems not to work in XPU. I'm curious if I shouldn't expect this to work, and whether there might be some workaround that didn't previously exist that would allow XPU to work this way?
I was so excited to jump over into H19.5, hoping that I might be able to finally get to use XPU on the scene to which I refer earlier in this thread. This scene has a uniform string primvar on some geometry specifying a texture file I would like to use as my basecolor.
The strategy of mtx_USD_primvar_reader -> USD_uv_texture -> MTX_standard_surface works splendidly for Karma CPU, but still seems not to work in XPU. I'm curious if I shouldn't expect this to work, and whether there might be some workaround that didn't previously exist that would allow XPU to work this way?
- jsmack
- Member
- 8026 posts
- Joined: Sept. 2011
- Online
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
I guess I'm a little confused: how are other artists handling this problem? It seems like a bit of a foundational thing for sets creation, where someone might want to have lots of geometry that uses a single shading network (e.g rocks scattered on a field, trees, destruction, etc).
Is this a "never in XPU" thing? A "it's coming, just not quite yet" thing? A "there's a way around this, here's an idea" thing?
I *think* I understand that this is - to some degree - a materialX thing and might not be a Karma thing (?). I would be happy to read any blog post or other informational resource to educate myself about this; I'm not trying to be exasperating by asking. But "it doesn't work" doesn't offer me much in the way of plotting a roadmap for myself, so I'd like to understand better.
Is this a "never in XPU" thing? A "it's coming, just not quite yet" thing? A "there's a way around this, here's an idea" thing?
I *think* I understand that this is - to some degree - a materialX thing and might not be a Karma thing (?). I would be happy to read any blog post or other informational resource to educate myself about this; I'm not trying to be exasperating by asking. But "it doesn't work" doesn't offer me much in the way of plotting a roadmap for myself, so I'd like to understand better.
Edited by dhemberg - July 28, 2022 11:36:01
- BryanRay
- Staff
- 43 posts
- Joined: March 2022
- Offline
At present, MaterialX itself does not permit an external connection to the Filename. We can work around the limitation in Karma CPU because it can use Vex, letting us shoehorn the USD UV Texture VOP into the network, but XPU will never be able to use Vex.
I believe we've made the case to the MaterialX group that string inputs are a desired feature. There was some discussion there spring boarding off this submitted issue: https://github.com/AcademySoftwareFoundation/MaterialX/issues/878 [github.com]
I'm not sure how far off it is. There was some mention of their six month goal window, but that was four months ago, so it's possible it might be coming soon. Or perhaps not; I haven't been around long enough to know how quickly these things move.
I believe we've made the case to the MaterialX group that string inputs are a desired feature. There was some discussion there spring boarding off this submitted issue: https://github.com/AcademySoftwareFoundation/MaterialX/issues/878 [github.com]
I'm not sure how far off it is. There was some mention of their six month goal window, but that was four months ago, so it's possible it might be coming soon. Or perhaps not; I haven't been around long enough to know how quickly these things move.
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
Thank you so much for this insight! Super helpful!
This bit in particular:
is helpful, as it wasn't obvious to me that VEX was the thing allowing this to work for CPU.
I know this is a work in progress, but maybe a note can be added here:
https://www.sidefx.com/docs/houdini/solaris/materialx.html [www.sidefx.com]
to clarify that this workaround applies to CPU but not XPU.
Thank you again for the explanation.
This bit in particular:
At present, MaterialX itself does not permit an external connection to the Filename. We can work around the limitation in Karma CPU because it can use Vex, letting us shoehorn the USD UV Texture VOP into the network, but XPU will never be able to use Vex.
is helpful, as it wasn't obvious to me that VEX was the thing allowing this to work for CPU.
I know this is a work in progress, but maybe a note can be added here:
https://www.sidefx.com/docs/houdini/solaris/materialx.html [www.sidefx.com]
as MaterialX doesn’t currently support string inputs, we can’t wire up the primvar name to a material’s public interface. Karma lets you mix the USD Preview nodes with MaterialX nodes, so that is a current workaround until MaterialX supports string inputs.
to clarify that this workaround applies to CPU but not XPU.
Thank you again for the explanation.
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
I threw a question on the MaterialX github repo [github.com], but it's gone unresponded to and I can't quite tell what the velocity is for this issue. One thing Spiff mentioned is that the trick here lies in Hydra, and he mentions "renderer-specific affordances", which is jargon for what I *think* refers to a particular token one might be able to use in a primvar and have the renderer make sense of it (e.g. <UDIM>, I think?). Does Karma have 'render affordances' I could leverage? I presume no, otherwise it would have been suggested already.
One thought I wondered about: can one do string building in MaterialX? E.g. if ultimately the texture I want to get is:
whereis a number I'm choosing in, say, a foreach loop or as a point attribute for copying geo onto points, can I store just X on the geometry, and then build a string around that in my mtlX graph?
I'm so puzzled that this seems to be such an outlying problem that it makes me think I'm approaching this problem of wanting to use one shader on multiple objects the wrong way...
One thought I wondered about: can one do string building in MaterialX? E.g. if ultimately the texture I want to get is:
/path/to/my/stuff/asset_X/albedo.exr
where
X
I'm so puzzled that this seems to be such an outlying problem that it makes me think I'm approaching this problem of wanting to use one shader on multiple objects the wrong way...
Edited by dhemberg - Aug. 5, 2022 13:02:42
- jsmack
- Member
- 8026 posts
- Joined: Sept. 2011
- Online
dhemberg
I'm so puzzled that this seems to be such an outlying problem that it makes me think I'm approaching this problem of wanting to use one shader on multiple objects the wrong way...
Use USD to specialize the same source material, with an override of the texture path for each asset you want different. Using shaders to build texture paths isn't optimal and won't work with many renderers.
- dhemberg
- Member
- 207 posts
- Joined: Nov. 2015
- Offline
Ohhhhhhhh! Ok, this just clicked for me; you even explained it several months ago similarly, but I understood USD far less then so it didn't register. My insistence of wanting to do this via string primvars is a holdover from earlier Renderman days, when other options didn't exist. This makes sense to me now, thank you!
A followup question: in the example hip you provide above, you're accomplishing the thing I'm trying to do by directly editing the property of a material prim after it's been created and bound. I see that there are "parameter override" options in the Material Assign node, which I *think* (but am not sure) might be another way to approach this problem? But, I can't wrap my head around how it might work when you're assigning one node (mtlxStandardSurface) but want to target the parameter of another node (the mtlxImage node). Is this possible? I'm attaching a variation of your hip file above where I'm attempting this, though it does not currently work.
The reason I like this latter approach is that I need to do some sort of coding to read my string attribute off my primitive before being able to set the property accordingly. I'm sure I could do this in the Property node, but it seems like the Material Assign node might already be intended to do this?
My instinct would be to wrap all of those shading nodes into a subnet, create a parameter on the subnet itself, connect this to the parameter inside the subnet that I want to control (this connection mimics what a Parm node would do, but I can't actually hook a Parm that mtlxImage node), and try to drive the node on the subnet with the Parameter Override. But, this doesn't work for me either, which makes me suspect I might be misunderstanding how it works.
Thank you again for being patient and repeating your answer, there's a fair bit of runway for a USB newb like me to consume, and some un-learning and re-learning intuitions before it clicked for me.
A followup question: in the example hip you provide above, you're accomplishing the thing I'm trying to do by directly editing the property of a material prim after it's been created and bound. I see that there are "parameter override" options in the Material Assign node, which I *think* (but am not sure) might be another way to approach this problem? But, I can't wrap my head around how it might work when you're assigning one node (mtlxStandardSurface) but want to target the parameter of another node (the mtlxImage node). Is this possible? I'm attaching a variation of your hip file above where I'm attempting this, though it does not currently work.
The reason I like this latter approach is that I need to do some sort of coding to read my string attribute off my primitive before being able to set the property accordingly. I'm sure I could do this in the Property node, but it seems like the Material Assign node might already be intended to do this?
My instinct would be to wrap all of those shading nodes into a subnet, create a parameter on the subnet itself, connect this to the parameter inside the subnet that I want to control (this connection mimics what a Parm node would do, but I can't actually hook a Parm that mtlxImage node), and try to drive the node on the subnet with the Parameter Override. But, this doesn't work for me either, which makes me suspect I might be misunderstanding how it works.
Thank you again for being patient and repeating your answer, there's a fair bit of runway for a USB newb like me to consume, and some un-learning and re-learning intuitions before it clicked for me.
Edited by dhemberg - Aug. 6, 2022 14:32:43
- antc
- Member
- 329 posts
- Joined: Nov. 2013
- Offline
Apologies if this is more confusing than helpful, but from your description it sounds like you want something that builds out a bunch of materials based on some kind of texture attribute or primvar on each mesh in a model. Attached is my attempt at this, where (as a starting point) each mesh has a "diffuseTex" attribute pointing at a file and there's also a single "base" material. From there a python lop creates (and binds) a specialized material for each texture it finds on the meshes. Someone with better node powers than me could probably do this with nodes and avoid python.
So, due to the specializes arc the base material is still 'live' and any edits further down the line that need to target all the materials should continue to edit base. The 3rd and 4th meshes showing the same texture is deliberate in order to demonstrate that only one material is created.
Oh and I used usd preview surface stuff but materialx should work the same way.
So, due to the specializes arc the base material is still 'live' and any edits further down the line that need to target all the materials should continue to edit base. The 3rd and 4th meshes showing the same texture is deliberate in order to demonstrate that only one material is created.
Oh and I used usd preview surface stuff but materialx should work the same way.
Edited by antc - Aug. 7, 2022 13:11:35
-
- Quick Links