Switching UsdRenderProduct's productName type from token to asset

Our studio would like to use USD expression variables to influence the names of products (i.e., image filenames) produced by a rendering process.

It is common for rendering systems to support things along these lines, such as in Houdini, where expressions in filenames in Houdini may use $F, $N, etc.

The original UsdRender schema proposal chose “token” for this attribute – but it also predated the introduction of USD expression variables.

By switching this attribute to the type “asset” (implemented as SdfAssetPath), USD attribute value resolution would resolve any embedded expression variables.

An example use:

def RenderProduct "primary"
    rel camera = </World/main_cam>
    rel orderedVars = [
    token destination = "diskfarm"
    asset productName = @`"Render/${SHOTPREFIX}${SHOT}.${PREFIX}${ELEM}${AOV}${SUFFIX}.${FRAME}.exr"`@

We were curious if anyone else would find this useful (or problematic).


By the time we get to the usd file for offline rendering, we have fully resolved the output paths, but it is also true that we are not using expressions in usd (yet?), so can’t really say much about that.

We do have timeSampled output though, so not sure how that’s going to work with expressions…

Variable expressions can be used within time sample values, for example:

asset productName.timeSamples = {
    101: @`"Render/${SHOTPREFIX}${SHOT}.${PREFIX}${ELEM}${AOV}${SUFFIX}.101.exr"`@,
    102: @`"Render/${SHOTPREFIX}${SHOT}.${PREFIX}${ELEM}${AOV}${SUFFIX}.102.exr"`@,
    103: @`"Render/${SHOTPREFIX}${SHOT}.${PREFIX}${ELEM}${AOV}${SUFFIX}.103.exr"`@

Calling attr.Get(…UsdTimeCode) on the attribute will return a SdfAssetPath-value. This will use the appropriate time sample and then substitute in the expression variables as needed. The result will be in SdfAssetPath::GetAssetPath().

One important related note we discussed with Spiff was that USD does not define an expression variable for time – therefore there is no built-in equivalent of ${F} as in Houdini.

Part of the background there is that, given its current design focus on representing cached-out animation, USD’s runtime does not want to take on additional evaluation overhead related to time. For example, we would ideally not want playback in usdview to require modifying the USD scene description (e.g. setting an ${F} variable). However, it does seem like it would be handy if USD could somehow provide acces to the timeCode as a variable in the future, given the common need to insert a frame number into filenames.

In addition, there are related concerns around how to format floating point variables that will be familiar to folks doing production rendering – such as how many leading zeroes to use, numeric precision on fractional frames, and how to handle negative frames. For our pipeline we are expecting to provide that policy at a layer above (i.e. in the rendering toolset) and use a ${FRAME_STR} string representation of the frame in the USD side. This is not a context where playback rate would matter, so the concern of setting expression variables for each frame is not a problem.

1 Like