
This is a work in progress. I’m still cleaning this, but would like to hear if this loads for peeps. The documentation is being updated for clarity.
Why?
Basic idea is to use embedded metadata creatively. In this case, the lens assets are written into a 24×24 image SEQ that contains custom keys that the setup looks for. Once loaded, lenses are controlled by two knobs: DISTANCE and IRIS, just like a real-deal lens. Using these controls, the data is TW (slipped) so that mapped values for distortion, vignette, etc go along for the ride.
The data from the lens assets can be transferred to CG renders w depth, allowing creative control over distance and iris to work on any render.
Here’s a link to the Lenswork node bin to unzip and load into user/project bin:
This is what the bin looks like.

This is what the LensSEQ assets look like. The length of the clip is determined from the diameter and rotation limits of the distance and iris of the lens. You can see at the bottom some of the embedded Cinelens metadata keys. Some are animated, some not. The animated ones are mapped to the pulls of DISTANCE or IRIS.

The Action node CAM_MASTER includes two GLSL shaders for storing variables and an axis to control DISTANCE (position Z) and IRIS (position X)

The whole setup. May take a bit to load first time. After that pretty snappy, even on intel Mac.

The Lens UI shader is largely a bunch of toggles to turn on/off. Set a context to the end of batch and then play with these to see what they do.

Work in 2-up view to make easier. ALL controls are in CAM_MASTER. NO keyframes exist in setup. This is where you control DISTANCE and IRIS throws. Also toggles for the UI.

The lens data comes from the LensSEQ asset. All distortion, vignette, Lens Make, etc. is embedded in the metadata or what appears to be a very small image sequence clip. This makes asset very lightweight. This data gets controlled then put onto your own CG.

The setup includes two parts. The first is SOURCE.

In a perfect world, this would load all the data from the LensAsset SEQ and slip it around, but metadata doesn’t like to update in all tools. This can also make unstable. Occasionally you might need to frame forward to refresh. The workaround for this is to BAKE all the channels into Action like an FBX. These act as a bunch of points w animated data. I’ve purposely left this using many axis in Action. This you can test w diff apps as FBX and makes readable what each axis is controlling. Going between apps, you need to pay attention to scale. In my case, coming from Houdini, I’m using meters. This is obvious on distance, but you don’t want to scale most other data types.
After you change lens, just copy/paste all the nodes from UNBAKED, clear any existing nodes into BAKED, then paste. Make sure the batch is as long as the LensSeq clip. (T-double click on the LensSEQ). Do NOT change names of axis or actions. These are picked up by expressions automatically in LENS WORKS. Bake all animation curves for the whole Action node. Baking can take a few minutes, which is a drag.
Fortunately, you can save your pre-baked lenses to another action before clearing. This will save you a lot of time. After you switch to another LensAsset SEQ, copy and paste the saved pre bake so you don’t need to always get slowed down by baking time.

The other side of the setup is THE_WORKS.

Hook up the MUX from SOURCE to the HOOKs in works. Expressions load automatically but clips need to be hooked up. Then you can change to your own CG render.
Inside WORKS can be intimidating. I’ve left a MAP in the bin to drag out.

You can either ungroup WORKS or jump into the group to see what’s inside. Place the parts on the MAP for clarity.

Each section is designed to be modular. Encourage peeps to come up w your own solves to hook up to either existing metadata keys or create new ones. Tweak or replace solves for Defocus, Distortion, Flares, Glares, Grain etc… Even tho you CAN put keyframes in here, strongly suggest otherwise. That way you can always just pull a fresh one from bin. Keep procedural. Then it works for ANY input.