Hi all,
In the wonderful world of loading in scene caches into Gaffer, I'm finding that out of the box it has quite a few limitations unless you're willing to pull your sleeves up and make custom code. I'll start with a bit of a brain-dump that'll paint a picture first.
So outside of using an external tool to build your scene for you eg. Houdini Solaris, the general approach is to have Alembics/VDBs/USDs/(.SCCs too but not for outside users/studios usually) brought in, using convenience nodes like `CollectScenes` which can be used to wrap up a lot of this without delving into C++-land (eg. drive the CollectScenes node using an expression, that could for instance load a JSON file or query a DB for what files to load in).
Or the other approach is to create an in-memory OpenUSD in an expression, do your operations in pure OpenUSD, and do a side-load into the SceneReader with a specific string to the fileName plug that will reference the memory pointer that way. Now I commend the thought process behind this approach, I *think* this is a massive hack ultimately and not something to use in a serious production sense...
So now I'll go over what currently exists at a studio, and what the studio plans to go towards. But for this post I'll just focus on how to solve the legacy approach as these scenes need to open up without too much fuss with minimal external conversion logic, and the 'new' way is a long enough time away from the present...
Legacy:
- A .JSON file explains what Alembic assets exist in a scene, and with their instanced transforms
- An asset loader that takes the above file, but also will splice in lookdev files, FX elements, procedurals (.klf, additional .abc's, vdb's, Yeti hair, etc.)
New:
- Everything OpenUSD more or less
- Custom asset resolver for OpenUSD that talks to shotgrid/flow for 'ground truth' publishes
The 'CollectScenes' approach is probably the more sensible way, as it also gives you additional control and visibility over what is coming into the scene (and if you want to swap out manually to your own version or omit caches coming in). However, assigning lookdev from something like a `USDLayerWriter` I can't really see a way to layer this back on when using this approach as the caches are 'Cortex/Gaffer-native' at this stage. The other thought was to 'side-car' an empty .scc file with only the hierarchy and the shader assignments and load this in and do a `MergeScenes`, but I'd like to stick to a USD-native way and not introduce .scc files...
The latter I've had some thoughts over, but it always seems to go towards making custom C++ code eg. duplicate the Gaffer SceneReader node, and make it like a mini-USD stage builder of sorts with a flashy UI to pick and choose what caches go into your USD stage file to then load in, including the lookfile (a .usda layer). The other thought was to make a custom scene interface that holds IECoreUSD::USDScene, that just loads in this JSON file + lookfiles + FX elements, etc. that just converts to a USD in-memory stage, and passes it directly to the USDScene as an internal member (and a bunch of m_usdscene-> pimpl redirects). That's a black-box though as SceneReader is too basic here to fine-tune with just a `fileName` string...
Another thought, making a 'MergeScenes'-like node that takes in a lookdev USD layer file might be the way to go, but I think that's tricky as the incoming scene is already Cortex/Gaffer-native and the .usda I guess would have to be interpreted as a complete scene and not a layer 'over', so it'll be purely based on hierarchy-matching which *should* be ok...
Anyways this is getting quite a bit lengthy, and I'd like to hear some input that others have over this. Ultimately I think I'll need to write something, but I just want to be smart about it.
Cheers