Using a primvar string to give a texture path

   3224   13   4
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
I've seen a few references mentioning this, but I have still not been able to figure out how to make this work.

I have geometry coming in with a SOP import. I have an attribute 'texture' which is the path to a texture I'd like to use for a given object (this started as material_override, but I wrangled this on the SOP side before bringing it into USD). I've tried a Principled Shader, using a USD primvar reader to read the string into the basecolor_texture input to the principled shader, but it doesn't seem to affect the texture. I haven't been able to find anything in MaterialX that would even suggest this should work.

Any suggestions for this. Ideally, I'd like to get something that can render with XPU, but even CPU would be a good start.

To summarize:
  1. SOP import imports the attributes.
  2. I do have a primvars:texture attribute which is the string.
  3. In my material network, I have a usdprimvarreader feeding into the principled shader basecolor_texture. This doesn't seem to work, even if using the fallback value.

Thanks,
David
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
Some additional insight.

If I use an Assign Material node, and an override Vexpression of:
s@inputs:basecolor_texture = "path_to_texture.jpg";
it does seem to replace my textures. The problem is that it replaces all of them with the same texture.

I tried
s@inputs:basecolor_texture = s@primvars:texture;
but this just results on no texture being applied.

I feel like I'm close here.
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
Ok, I've got this working, at least with the Principled Shader and the CPU Karma renderer.

The 'texture' var was coming over as a string array. Even though I was having the SOP import divide them up into separate primities, the texture var was still an array. This was fixed by using the following vexpression in the Assign Material node:
string base = usd_primvarelement(0, @primpath, "texture", 0);
s@basecolor_texture = base;

Any idea if something similar can be done with a MaterialX shader. It'd be nice to be able to see the individual textures in an XPU render.
User Avatar
Staff
2498 posts
Joined: July 2005
Offline
There's been a bit of discussion in the MaterialX group about texture variation. The issue with MaterialX is that they need to be able to enumerate all textures prior to rendering for some renderers (like GL), so driving a texture with a primvar is not really feasible.
When using Karma and MaterialX, you can intermix Usd Preview nodes and MaterialX nodes (this may not be documented, but it's true). So, you should be able to feed a Usd Primvar reader into a Usd UV Texture then feed that into a Mtlx Standard Surface. This should work with both CPU and XPU.

P.S. It will not work with other renderers though.
Edited by mark - Feb. 12, 2022 16:34:36
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
When using Karma and MaterialX, you can intermix Usd Preview nodes and MaterialX nodes (this may not be documented, but it's true). So, you should be able to feed a Usd Primvar reader into a Usd UV Texture then feed that into a Mtlx Standard Surface. This should work with both CPU and XPU.

I tried this, and it works great with the CPU renderer, but I just get a dark grey surface when using the XPU renderer. If I just use the USD UV Texture with a fixed name, that does work, but it doesn't seem to work with the primvar reader on XPU.

Thanks,
David
User Avatar
Staff
2498 posts
Joined: July 2005
Offline
I stand corrected. String primvar support in XPU is still in its infancy.
User Avatar
Member
40 posts
Joined: Aug. 2018
Offline
Any idea on where string primvar support is in the XPU roadmap? I'm trying to decide if I should see if any of this will work in Redshift, or just deal with the CPU renderer for now.
User Avatar
Member
23 posts
Joined: Sept. 2021
Offline
We have used Redshift until December last year with Solaris and USD and until then string variables were not supported there either with no plans to change that (that we were aware of).

PS: Our workaround was to use a switch with all textures loaded in the material and use an integer primvar to select which texture to use. I'm guessing that would work in Karma as well - albeit it limits the scope of how many textures one can reasonably use and it needs to be pre-defined.
Edited by marcosimonrbl - Feb. 15, 2022 05:53:16
brians
Staff
265 posts
Joined: May 2019
Offline
d3zd3z
Any idea on where string primvar support is in the XPU roadmap?

The answer to this is more complicated than it might appear.

What you're asking for in essence is not just "when will string primvar support be working in XPU", but actually "when can we have something within a shader trigger the loading of a texture".

That kind of feature is called "on-demand texture loading".

We're looking into this, but it's actually a very large job (given the disconnect of the GPU from the CPU) so will not happen overnight. So perhaps somewhere between 6months -> 1year. But I cannot be certain sorry.

Thanks for the inquiry though.
Its useful to hear that people are attempting this kind of thing
Cheers
User Avatar
Member
185 posts
Joined: March 2011
Offline
brians
d3zd3z
Any idea on where string primvar support is in the XPU roadmap?

The answer to this is more complicated than it might appear.

What you're asking for in essence is not just "when will string primvar support be working in XPU", but actually "when can we have something within a shader trigger the loading of a texture".

That kind of feature is called "on-demand texture loading".

We're looking into this, but it's actually a very large job (given the disconnect of the GPU from the CPU) so will not happen overnight. So perhaps somewhere between 6months -> 1year. But I cannot be certain sorry.

Thanks for the inquiry though.
Its useful to hear that people are attempting this kind of thing
Cheers

For crowd that's a important feature.
Do you know if has been some development in rendering crowds on the gpu (not just talking about Karma here)?
Because It uses a lot of memory...
Last time I used that in Karma (CPU) I couldn't use the agents as instances (or some kind of It) due to some errors when binding the material variations, so I don't know how much that feature can help on the amount of memory needed, but, with that said, I didn't feel much difference from Mantra on the same scenario (although I didn't compare).
brians
Staff
265 posts
Joined: May 2019
Offline
I've thought a little more about accessing different textures procedurally on XPU in MaterialX.
Two workarounds exist

1) Use a switch node

So if you had (eg)5 textures, you could simply feed all 5 textures into a switch node, and then drive the selected parameter with an integer primvar.

This does not scale very well, and will slow down with large amounts of textures (especially on CPU device), but its an option

2) Use UDIMs

So udims allow you to specify a grid of textures and then access them procedurally within the shader.
Simply add the integer coordinates of the grid location to your 0->1 UV coordinate to access what texture you want


Attached is an example of both being used

Attachments:
screenshot.JPG (170.0 KB)
proc_texture_xpu.zip (109.8 KB)

tamte
Member
7206 posts
Joined: July 2007
Offline
brians
Two workarounds exist
unfortunately people spoiled by properly working solution in Mantra (and possibly Karma CPU) will not be easily satisfied by tedious workarounds, even though may be grateful if a workaround exists that may meet their needs

traditionally, you can literally have 1 shader and then feed it 1000 textures using prim attributes without even touching the geo keeping it packed alembic
it just makes things so easy and effortless to set up especially if named properly

I thought that since engines like Unreal support Virtual Texture Streaming from disk that this is not an issue anymore for GPU and theoretically OGL and GPU renderers could all just stream pixels on demand the same way, but granted I don't know the details so maybe it has some drawbacks that would make it not a viable solution
Edited by tamte - Feb. 17, 2022 19:56:50
Tomas Slancik
FX Supervisor
Method Studios, NY
tamte
Member
7206 posts
Joined: July 2007
Offline
mark
The issue with MaterialX is that they need to be able to enumerate all textures prior to rendering for some renderers (like GL), so driving a texture with a primvar is not really feasible.
how does it know which UDIMs it will needs if it can't pre-evaluate st primvar?
I assume it will just load all that match the pattern even if they may not be necessary?
Tomas Slancik
FX Supervisor
Method Studios, NY
brians
Staff
265 posts
Joined: May 2019
Offline
tamte
unfortunately people spoiled by properly working solution in Mantra (and possibly Karma CPU) will not be easily satisfied by tedious workarounds, even though may be grateful if a workaround exists that may meet their needs

It is something we're aware of and working towards.

tamte
I thought that since engines like Unreal support Virtual Texture Streaming from disk that this is not an issue anymore for GPU and theoretically OGL and GPU renderers could all just stream pixels on demand the same way,

I'm not sure how Unreal are doing it, but there are two conceptual ways to do this

1) unified memory
https://developer.nvidia.com/blog/unified-memory-cuda-beginners/ [developer.nvidia.com]

We really like the idea, but it comes with issues that currently make it unusable.

The main one is that we cannot access the memory on the CPU if the GPU is doing any work without the application being terminated by the driver. And this means any work at all...
So its impossible for us to use when we have an open system like Houdini with plugins that might also be making use of the GPU as well :/

It also means we'd need to double all our data in memory, so the CPU device could also run.
There are also quite a bit of performance issues when used with Optix.
We're talking to NVidia about potential improvements, but I don't think this issue will resolve itself anytime soon.

2) on-demand loading
https://on-demand.gputechconf.com/siggraph/2019/pdf/sig913-texture-paging-in-optix.pdf [on-demand.gputechconf.com]

This is where we load the textures on demand, which is what NVidia actually recommends (over unified memory).
They even maintain an example library.
This is the one we plan to implement over the next one/two release cycles.

tamte
how does it know which UDIMs it will needs if it can't pre-evaluate st primvar?
I assume it will just load all that match the pattern even if they may not be necessary?

Yes, XPU currently pre-loads all the texture data.
So in this case it will pre-load ALL UDIMs, whether they're needed or not


Brian
  • Quick Links