USD Primvar Reader and String types

   5678   17   4
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
I can add custom float/color primvars to my geometry and correctly load those into my material network and get the expected result in the render. But let's say I want to store an image path as a string primvar on geometry prims and read that into the material… I can use USD Primvar Read, set to string type, and feed that to USD UV Texture's file input, but that doesn't seem to work. I've tried this string-type primvar and stringArray type and no luck so far.

Any insight on how I can pull texture paths into the material network which are stored as primvars on geometry?
Edited by Tim Crowson - Oct. 10, 2020 12:04:46
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
75 posts
Joined: July 2019
Offline
This would be super helpful - as a means of automating material networks that pull the asset name data from the prim.

Currently I can't get any string primvars to read in correctly in my material_library. I've used bind, usdprimvarreader, and getattrib.

Perhaps there's another way to author attrs (instead of primvars) inside LOPs that can be read into the material library?

-Dave
User Avatar
Staff
4438 posts
Joined: July 2005
Offline
Here's a hip file showing that it works, though it's going to require that the render delegate support plugging a UsdPrimvarReader into the file input of the UsdUVTexture node. Karma has no problem with this. This at least proves that this is a valid way to author the USD information, and that Hydra is able to convey the required information to the render delegate. I suspect it would work with other final-frame renderers like RenderMan if you used a texture file format they support. But the GL renderers like Storm and Houdini GL don't support this.

If you really want to see something like this working in OpenGL, you can use the Assign Material LOP to create unique copies of the material for each texture and assign the materials to different UsdGeomSubsets on the mesh. Houdini GL is fine rendering multiple materials on one mesh using subsets. The second attached file shows this workflow.

Attachments:
testprimvars.hip (107.3 KB)
subsetmaterials.hip (119.5 KB)

User Avatar
Member
7766 posts
Joined: Sept. 2011
Online
mtucker
Here's a hip file showing that it works, though it's going to require that the render delegate support plugging a UsdPrimvarReader into the file input of the UsdUVTexture node. Karma has no problem with this.

Is there any way to connect the primvar to a principled shader or other mantra material with karma? I tried using a parameter vop, but this only worked if I encapsulated the principled shader in a material builder vop first.
User Avatar
Member
240 posts
Joined: Oct. 2014
Offline
mtucker
Here's a hip file…

Thanks, I'll give this a shot. The renderer I am using is definitely able to render color primvars (at least) using a USDPrimvarRead into a UsdUvTexture node, so I'm optimistic. GL support is less important as we're mainly focused on final frame rendering.
Edited by Tim Crowson - Oct. 11, 2020 00:37:35
- Tim Crowson
Technical/CG Supervisor
User Avatar
Member
169 posts
Joined: Nov. 2013
Offline
Thanks Mark! Looking at the testprimvars.hip;

Several issues
1: You can't use usdprimvarreader nodes inside Material Builder Vops, meaning your material Library could become quite a mess, especially if you have multiple different delegates that you'd like to collect.

2: Using the usdpreviewsurface node is obviously not designed for final-frame rendering - what is the intended workflow for using the current Material vops (eg legacy material vops)? The current non-USD vops seem to have no impact to a network tree that is plugged into a usdpreviewsurface.
As Jmack pointed out, using a principled shader to receive these attributes requires putting the network inside a Material Builder. I'm not actually sure how JMack got his to work, but I couldn't get Karma to render using principled shader, whether inside a Material Builder vop or not.

3: What is the best way to define primvars in LOPs and get them to carry through correctly to the material network? Obviously models wouldn't be authored with texture path attrs, as models are published before textures are even started, so doing this in a Wrangle in LOPs is ideal. However (if you look at the attached hipnc file), for whatever reason, the primvars I've defined do not get recognised as a primvar, and their primvartypename also returns nothing. Check the Scene Graph Details.

Image Not Found

Attachments:
testprimvars_lop_wrangle.hipnc (328.6 KB)

User Avatar
Member
7766 posts
Joined: Sept. 2011
Online
Hamilton Meathouse
Thanks Mark! Looking at the testprimvars.hip;

Several issues
1: You can't use usdprimvarreader nodes inside Material Builder Vops, meaning your material Library could become quite a mess, especially if you have multiple different delegates that you'd like to collect.

2: Using the usdpreviewsurface node is obviously not designed for final-frame rendering - what is the intended workflow for using the current Material vops (eg legacy material vops)? The current non-USD vops seem to have no impact to a network tree that is plugged into a usdpreviewsurface.
As Jmack pointed out, using a principled shader to receive these attributes requires putting the network inside a Material Builder. I'm not actually sure how JMack got his to work, but I couldn't get Karma to render using principled shader, whether inside a Material Builder vop or not.

3: What is the best way to define primvars in LOPs and get them to carry through correctly to the material network? Obviously models wouldn't be authored with texture path attrs, as models are published before textures are even started, so doing this in a Wrangle in LOPs is ideal. However (if you look at the attached hipnc file), for whatever reason, the primvars I've defined do not get recognised as a primvar, and their primvartypename also returns nothing. Check the Scene Graph Details.

Image Not Found

Here's a scene where I read a primvar with a principled shader. It's not different than how it would be done with Mantra, except that the auto material can't be used here.

I also show how a wrangle could be used to create an indexed uniform primvar on a mesh, but it's a lot more convenient to do it in sops.

Attachments:
testprimvars_edit.hip (369.1 KB)

User Avatar
Member
169 posts
Joined: Nov. 2013
Offline
Thanks JMack - gonna have to play with this a bit. For now, If I edit any of that code in your Lop Wrangle I get an instant segfault (using 18.0.499 at home in Linux Mint).

I've even built a new scene from scratch and copy-pasted the code into the wrangle and it still crashes (no nodes below the wrangle, so not a viewport delegate issue).

Also, it seems kind of odd that all strings have to de defined as lists of strings, and then an index chosen…
User Avatar
Member
169 posts
Joined: Nov. 2013
Offline
It appears that setting a primvar index to a value that doesn't exist causes a segfault. Attached is a scene file example (see the line to comment out in the lop wrangle.

Houdini 18.0.499 (old version, so may be fixed in more current builds).

Image Not Found

Attachments:
testprimvars_edit_crash.hipnc (77.2 KB)

User Avatar
Member
7766 posts
Joined: Sept. 2011
Online
Hamilton Meathouse
Also, it seems kind of odd that all strings have to de defined as lists of strings, and then an index chosen…

Only have to for indexed primvars. Alternatively, the array can contain a value per face (or just one value). I haven't seen that crash, but I also didn't try indexing out of the array. I'm using 579
User Avatar
Staff
4438 posts
Joined: July 2005
Offline
That crash still happens, even in the very latest builds. I've submitted a bug for it. Thank you for the nice simple hip file.
User Avatar
Staff
1448 posts
Joined: July 2005
Offline
Is there any way to connect the primvar to a principled shader or other mantra material with karma?
Bind VOP should work (at least in 18.5).

You can't use usdprimvarreader nodes inside Material Builder
The Material Builder generates VEX shader from code fragments, and usdprimvar reader, being a USD preview shader, does not generate VEX code fragment, so can't be used.

Bind VOP may be more versatile, because it generates VEX parameter shader inside Material Builders, but USD shader translator scripts handle it too, and translate it to a USD Preview Shader primitive when used outside Material Builders.

The current non-USD vops seem to have no impact to a network tree that is plugged into a usdpreviewsurface.
USD standard has only a handful of supported shader primitives (eg, usd texture, usd primvar reader, etc), and does not support arbitrary operations such as addition or multiplication (eg, Mulitply VOP in your .hip file). So these groups of VOPs can't be mixed together.

You can however mix (only) Vex VOPs to build Karma shader.

setting a primvar index to a value that doesn't exist causes a segfault.
Should be fixed in 18.5.365
User Avatar
Member
7766 posts
Joined: Sept. 2011
Online
rafal
Is there any way to connect the primvar to a principled shader or other mantra material with karma?
Bind VOP should work (at least in 18.5).

Ah, I was trying in 18.0. That's cool that binds as primvar readers can be connected to input's of karma shaders. Is there a reason an actual usd primvar reader can't be used for this purpose? It seems like it should create the same usd graph.

Can we expect other kinds of graphs to work with karma shaders in the future? Such as karma pattern shaders with cached code being connected to principled shader inputs?
Edited by jsmack - Oct. 13, 2020 15:42:49
User Avatar
Staff
1448 posts
Joined: July 2005
Offline
jsmack
That's cool that binds as primvar readers can be connected to input's of karma shaders
Yeah, that brings Karma's shaders in line with Mantra's. Ie, it's a familiar concept, and it also means that older shader networks (in /mat) have better chances to behave correctly in LOPs.

jsmack
Is there a reason an actual usd primvar reader can't be used for this purpose?
It has to do with legacy code we have for dealing with VEX shader builders, and how they expect VOPs to provide VEX code snippets, and how we have special treatment for Parameter and Bind VOPs. And USD Primvar Reader is none of that. Which means, we would have to complicate existing code just to accommodate it, for marginal benefits.

While you can't use USD Primvar Reader VOP for Karma, you can use Bind VOP for other renderers, because default shader translator translates it to privar shader primitive, just like karma shader translator does.

Just like Parameter VOP is designated as a general way to define Material input, Bind VOP can be thought of as a general way to define a primvar reader. Note, just for completeness, that Bind VOP also authors a Material input, which feeds into USD primvar reader's fallback value. This way you can drive the value either by overriding the material input or by authoring a primvar on geometry primitive.

jsmack
Can we expect other kinds of graphs to work with karma shaders in the future?
That's one area we are exploring and seriously considering. Though I'm not sure what form it will take in the end.
User Avatar
Member
169 posts
Joined: Nov. 2013
Offline
I was defining some primvars in a LOP wrangle in order to pass to a usdprimvarreader. I noticed that some string and string array primvars are different colors (I'm assuming based on whether they are valid primvars or not).
Can anyone tell me what the colors mean in the Scene Graph Details pane? Some string primvars are blue, some are light green/yellow.
User Avatar
Member
7766 posts
Joined: Sept. 2011
Online
Hamilton Meathouse
Can anyone tell me what the colors mean in the Scene Graph Details pane? Some string primvars are blue, some are light green/yellow.

light blue means default value. green means has time samples.
User Avatar
Member
169 posts
Joined: Nov. 2013
Offline
Is there a way to remove time samples from a primvar? I see usd_primvartimesamples can query them but not alter them.

Also, pulling any part of a primvar (eg; splitting a string) that has timesamples, storing it in a variable, then using that variable as part of another primvar, causes the new primvar to have timesamples. Is there a way to avoid this?
User Avatar
Staff
4438 posts
Joined: July 2005
Offline
LOP nodes automatically author time sampled values if the parameter driving the attribute is animated. Or for some LOP nodes, like Attribute Wrangle nodes, there is no way to determine if a given value will be time varying, so any attribute set by a time dependent wrangle node will be authored as time samples.

To author an attribute value as a default value rather than time sampled, you must avoid these situations. The simpler approach, if the attribute you want to make non-timesampled is a scalar value or a single-element array, is to use an Edit Properties node to set the attribute value using a parameter value that is not time-varying. This will author a default value even if the input node is time varying. If you can't use an Edit Properties node, the only way to prevent a node from being time dependent when its input is time dependent is using a Cache LOP set to “Cache All Frames” (which will eliminate the whole-node time dependency). And then of course there is the Python LOP which you can use to clear all time sampled values and author only a default value (regardless of the time dpendency of its input node).
  • Quick Links