Seeking Clarification on UsdPrimvarReader Node Functionality

Hello fellow developers,

I am currently exploring the functionality of the UsdPrimvarReader node in Shader Graph Editor and would appreciate some clarification on its operational principles. Despite my efforts to understand its functionality, I find myself in need of some guidance.

Specifically, I would appreciate insights into the proper functioning of the UsdPrimvarReader node, including how it should ideally operate, the essential data that should be specified in the Varname field, and the Primvars that can be extracted from a USD file. Additionally, I am curious about the correct code representation of a Primvar in USD file to ensure it can be invoked successfully.

If anyone could share their expertise or point me in the right direction to relevant documentation, I would be immensely grateful. Thank you in advance for your time and consideration. I look forward to any insights or recommendations you may have.

Replies

Hello Tim,

I'm looking for similar information as I'm new to USD and Shader Graph. In particular with my own use case I'm exploring the feasibility of rendering spherical harmonics in realitykit geometry. Custom Metal surface shaders are not an option for Vision Pro so I have to look at Shader Graph. Spherical harmonics embed many floats per vertex, and I'm looking into having that represented in a USD file, where that data would be encoded as per-vertex (maybe per-face) primvars.

I'm not sure exactly what your familiarity with USD is; but consider the following:

  • I don't know if you have your own USD or USDZ files to work with, if you need one, grab one of the "3D Models" on the Apple website.
  • To "easily" inspect the data of a USD/Z file, you can't beat reading its USDA ascii format. For that, clone the OpenUSD git repo and build it so you have its useful tool binaries. Then do e.g. usdcat -o sneaker.usda Downloads/sneaker_airforce.usdz. You'll be able to examine the data in a text editor.
  • For instance, sneaker_airforce has the following standard fields: positions (float3), normals (float3), st (float2). st (= uv coordinates) is the only one that's a primvar properly speaking. Primvars are geometry variables that can be interpolated. Looks like I can't link OpenUSD.org for some reason, but google "working with primvars".

In my own experimentation with UsdPrimvarReader in a custom Shader Graph material, I tried visualizing UVs and normals by mapping them to RGB. In particular trying to see how the nodes behave if I try reading vector2f (st) as vector3f, or vector3f (normals) as vector2f etc.

What I found is that those nodes seem pretty buggy:

  • Piping a constant string node to a UsdPrimvarReader's varname fails 100% of the time, with the fallback value being used 100% of the time; while entering the varname in the node directly would work as expected
  • UsdPrimvarReader (float): I didn't have data I could read and it failed to read any of the vector values, defaulting to fallback for all varnames I tried.
  • UsdPrimvarReader (vector2f) reads the st primvar perfectly, and it even seems to be able to read normals and positions (not primvars) but less consistently, with bugginess e.g. when I clear the varname field on the node.
  • UsdPrimvarReader (vector3f) seems entirely broken, outputing some cyan/teal noise, with different patterns depending on the selected varname. This one would even refuse to default to its fallback value.
  • UsdPrimvarReader (vector4f) like the float one defaulted to fallback for all varnames I tried.

All this might be just RealityComposer Pro as I have not tested rendering those on device. I'd love to hear from devs or Apple team if they had more luck than me!