A Render Layer Workflow

Hi folks,

I’ve been trying to figure out a way to make a layer that would work similarly to that of a Maya render layer workflow, at least in how one would construct them.

Here is what I have come up with, I’m hoping to get some feedback on the concept:

So assume we want to create a render layer for a shot, and say this shot is composed of many layers and references.

A “render layer” would be created by an additive process, meaning the user would pick the prim they would like to be part of this render layer.

Say they wanted a layer of only the characters, they would either manually pick or write an expression to collect the desired prims.

Once the list of prims is collected they would then create a new stage and define new prims using these selected prim paths and then reference the shot we had open and sub-root the same paths.

Here is an example of what that might look like:

# Example code
input_stage_path = 'sequences/000994/0010/shot.usda'
output_stage_path = '/RENDER_LAYER/TO/EXPORT.usda'
render_layer_prim_paths = ['/world/chr/chr_A_0001', '/world/chr/chr_B_0001', '/world/chr/chr_C_0001']

shot_stage = Usd.Stage.Open(input_stage_path)

# Create a new, empty stage to export the selected prims
render_layer_stage = Usd.Stage.CreateNew(output_stage_path)

# Copy the selected content to the new stage
for prim_path in render_layer_prim_paths:
    prim = shot_stage.GetPrimAtPath(prim_path)
    if prim:
        render_layer_stage.DefinePrim(prim_path).GetReferences().AddReference(shot_stage.GetRootLayer().identifier, prim_path)

# Export the new stage to the output path
render_layer_stage.GetRootLayer().Export(output_stage_path)

Example output:

#usda 1.0

def "world"
{
    def "chr"
    {
        def "chr_A_0001" (
            prepend references = @sequences/000994/0010/shot.usda@</world/chr/chr_A_0001>
        )
        {
        }

        def "chr_B_0001" (
            prepend references = @sequences/000994/0010/shot.usda@</world/chr/chr_B_0001>
        )
        {
        }

        def "chr_C_0001" (
            prepend references = @sequences/000994/0010/shot.usda@</world/chr/chr_C_0001>
        )
        {
        }
    }
}

Now I’ve tried this in actual shots using a regular expression to get all the rocks assets as an example and the results seemed to be exactly what I was looking for.

A new layer with only the prims I want to render. They are also referencing the shot so the same layer would work even when new opinions are made to the prims in the composed shot.

This allows me to isolate and override the specific prims and render settings and can be done so for each render layer I can come up with.

Is there some downside to this that I am not seeing, or a better way?

Any insight into this would be much appreciated.

Cheers,

Jason Coelho

Hi Jason,

I think it can be made simpler.
You can think of a render layer as just another layer on top of everything. In that layer, you can deactivate the prims you don’t want and keep all the others exactly at the same location in the original hierarchy. Then you can override anything you like (material binding, hold-out matte attribute, light intensity, etc.) inside that layer.

So if you have a shot.usd which is its own layerStack and sublayers layout.usd, anim.usd, fx.usd and lighting.usd, you can then create a new file called shot_characters.usd which sublayers shot.usd and on top of it sublayers your render layer called characters_only.usd which contains all the deactivation and other overrides. You can than have another one called shot_props.usd which sublayers shot.usd and props_only.usd.

If the render settings were all set in the lighting layer, both shot_characters.usd and shot_props.usd will share the same settings and they will be updated if the settings change in lighting.usd while still being able to override the ones you want.

Then all you need to do is to send shot_characters.usd and shot_props.usd to the farm.

As I understand it, the new Expression Variables that were introduced in USD 23.08 will eventually be used in collections, making this process even more dynamic. Perhaps there’s a way to use them now for that purpose, actually. I haven’t investigated that yet.

Cheers,
F

Hi @flord,

Thanks for your insight!

I did consider Sub-layering the shot into a new layer like you mentioned above but I had apprehensions about automating the deactivation of the prims. I fear that there would be more room for unintended results using that method, though that may not be the case.

I might not have described the workflow as well as I could in my post, but the benefits you pointed out like having the render setting shared if there are any updates from a layer like lighting.usd would still hold true, so long as the render settings prim were added to the layer, same with the lights etc.

Likewise the intent is that when a prim is added the prims would fall into the same hierarchy as they do in the shot they are referenced from.

One weakness in my method would be that without the deactivated prims you can not as easily modify the render layer without some tooling around it. In your example it would be very easy for someone to simply re-activate a prim that they want added.

I would very much like to start using newer features like the Expression variables but currently I am bound to what release of Maya or Houdini are building USD to. I think in our case its USD 22.11

Thanks again for the feedback!

Cheers,

Jason Coelho

If you haven’t already, check out this thread. There might be some interesting insights for what you want to achieve.

F