STMap_BBox

Today I’m releasing STMap_BBox, a C++ plugin for Foundry Nuke. It does the same thing as Nuke’s native STMap node, but with one additional calculation for also warping the Bounding box.

Download the plugin from my Github:
https://github.com/CreativeLyons/STMap_BBox-public/releases/latest

Instructions on installation are in the README.md file in the download, and are also briefly mentioned in the video.


Lens Distortion Workflow


This plugin is mainly to help make the STMap node more useful in the STMap Lens Distortion workflow.

All plates have lens distortion, and it’s essential in compositing to undistort the plate, and to redistort any element to match the plate distortion. We are constantly jumping between undistorted and redisorted states depending on the task: paint outs, roto, CG, 2D elements, tracking, projections, etc.

It’s fair to say that lens distortion is one of the most common things we do in our nuke scripts.

Most Tracking software, like 3D Equalizer, Syntheyes, even Nuke itself, can export a Lens distortion plugin or node to do the actual lens distortion. They also have the ability to export a Lens Distortion UV map.

A UV map is just a utility image with data that tells Nuke where to warp the image to on each pixel. Using a UV map with the STMap node yields an identical result to using the actual lens distortion node itself. You’d need to save 2 images to disk, an Undistort map, and a Redistort map. In most cases these are static, but sometimes there is an animated lens distortion map needed (full-framerange) because of lens breathing or rack focus.

Why use an STMap workflow over just using the actual lens distortion node?

There could be a few reasons:

  1. You might not have the lens distortion plugin installed. These Tracking softwares ship with their own plugins, specially designed to work with the data that the software is exporting. If you don’t have the plugin installed, you won’t be able to reproduce the distortion. But with the exported UV map / STMap workflow, you can.
  2. Easy to share. This UV map is an image format, usually 32 bit exr for uncompressed data storage. This makes a UV map more universal than say a .nk file, or a plugin file, specific to any software. In fact it’s a software agnostic way of reproducing the same distortion, with the same UV map, anywhere.
  3. Easy to swap out. It can be much easier to swap out or update one single source of true, rather than finding and swapping all the Lens Distortion nodes everywhere in your nuke script.

I’d like to focus on the last point, because this really is what makes this STMap Lens Distortion powerful, especially when paired with a tool like Adrian Pueyo’s Stamps, a hidden input system for Nuke.

When using a template, or just using another shot’s nuke script as a base, you need to swap out all the lens distortions for the correct distortion for that unique shot. Instead of manually needing find and replace each Lens Distortion node everywhere in your script. Hoping and praying that you didn’t miss any (we’ve all had it happen).

The UV map / STMap workflow allows use to have 1 source of truth for our lens distortion, and makes swapping out the old Lens Distortion for a new Lens Distortion as easy as swapping out that map. Every lens distortion is updated instantly.

Pairing this with a template workflow, and checking on “auto-reconnect” on the stamp children. You can actually save a template that will automatically sync and connect to your redistort or undistort maps in your nuke script when the template is brought in. This saves precious time and always ensures you didn’t forget to lens distort, and that you are using the shot’s very own distortion maps.

What’s the catch?

Unfortunately, Nuke’s native STMap node only distorts the Image channels, not the Bounding Box of the image. In fact, because warping the image while keeping the original bounding box would probably make it go out of bounds (stretchy pixels) nuke defaults to just using whatever the `stmap` input BBox is. This is a safe bet, because the image will never warp outside of the UV map image (because that image is telling it where to warp to) so there is no risk of the BBox being too small, and it also eliminates the need to do any extra bounding box calculation.

Because all redistort and undistort maps on plate distortion are the roughly size of the full plate format, or bigger in the case of large undistort with overscan, it means that even if your src input BBox is small, it will replace the BBox with the full format after the distortion warp.

Have a look at the difference in Bounding Box size after using the Lens Distortion node (left) and after using the equivalent STMap workflow (right).

The problem with discarding the input Bounding Box and making it the full frame format is that this creates a compounding effect on later calculations. One of the things nuke does best is optimize for only calculating what it needs to inside of that Bounding Box. If the BBox is 400×400 pixels, then nuke is only computing those 400×400 pixels on your heavy node. If you replace that with a 4k full format bounding box, even though the input area needed is really only 400×400, Nuke now has to calculate the full 3840×2160 worth of pixels.

That specific scenario would be 52x more pixels to calculate, a whopping 5,000% increase… yikes.

Since undistorting and redistorting is happening dozens of times in nuke scripts, you can imagine the effect that tossing away a small bounding box for the full format can have on the entire nuke script.

If we put a Defocus node with a very large value, 400 for example, you will see the Viewer scanline crawling to calculate the full format, every single pixel. Whereas with that same Defocus node, on a smaller area BBox input, it can calculate nearly instantly.


STMap_BBox

Preserving the tight Bounding Box after the distortion is exactly what STMap_BBox was made to solve.

I could not use a blinkscript node because Blinkscript nodes do not touch the BBox, instead I needed to Recreate the STMap node, and add in the additional BBox calculation.

How it works:

The STMap_BBox node samples samples the 4 corners of the source BBox, as well as several points along the edges for irregular shaped warps where bowing of the center of the edge may go wider than the corners.

It then uses the UV Map input to calculate where those points end up after the warp. It then adjusts the BBox to cover the max warp along each edge and draws a final resolved BBox, encompassing the entire warp area. There is also a padding of +2 pixels for safety.


Additional Knobs to know

The STMap BBox has the identical settings to Nuke’s native STMap node, but with a few extra settings for BBox control.

  • Adjust BBox – Adds additional padding to the BBox if needed
  • Intersect Checkbox – Enables the additional BBox calculation. Disabling will skip the BBox calculation, essentially making this Node back into the native STMap node in nuke.
  • Limit BBox to – Allows you to choose the maximum size the BBox is allowed to grow until.

Here is a visualization of the different options for Limiting the Max BBox size to (click to view full size):

  • Union BBox – (Default) Combined maximum of src and stmap input BBoxes
  • STMap BBox – stmap input BBox
  • Src BBox – src input BBox
  • Format – the format
  • Overscan – the format + an Overscan Scale amount, controlled by the Overscan Scale slider

The Overscan Scale knob is default to 1.2, which is the same as if you were to take a Transform node and scale the image up by 1.2 from it’s center. This is useful for undistort.

The Overscan setting is most useful if you have a massive rotoshape, whole bounding box is way bigger than the format or stmap input and you wish to limit it to the format + some overscan padding relative to the format size.


Limitations

The best use-case for the STMap_BBox is static lens distortion warping.

Nuke is able to cache the static frame UVMap and use that to calculate the warp of the input BBox on each frame. It is fast, efficient, and stable.

Where the node runs into trouble is actively changing, high frequency, large distance warps, that are changing every frame.

For my tests, I used an animating noise pattern to heavily distort the image on each frame.

The node runs into trouble because Nuke has to “find” the points on along the BBox each frame, and the larger the distance of the warp, the more time it takes to search and find where the points have gone. This can eat up Nuke’s memory and even cause a crash.

If you need to do a warp like this, I would use the native STMap node that never bothers with this calculation or simply uncheck the “intersect” option in the STMap_BBox to skip the BBox calculation.

I would stick to Lens Distortion scenarios. Animated lens distortion maps (full framerange) should also be fine to use.

It’s more about the large-distance warping and changing every frame that seems to eat up RAM. Lens Distortion warps usually have a pretty limited warp radius and thus the node is easily able to find where the point has warped to by looking at a smaller radius instead of searching the entire format.


Difference between C++ Plugins and Gizmos or Groups

Please remember, this is a C++ Plugin Node, not a Gizmo, and not a Group. In order to use this tool, you need to have this plugin installed.

This makes it fundamentally different from a Group, or a Gizmo, which you could always export to Group if sharing with someone who does not have the Gizmo installed. You cannot export this to a Group, because it is an actual Node in nuke.

If another colleague, or the render farm, does not have this tool installed, then it will error, the same as a missing gizmo.

Luckily, the Image result of the STMap_BBox is identical to that of the native STMap node. So in a worst case scenario, you can always swap it out for a regular STMap and still get the same result, or write a python script to replace all STMap_BBox nodes with STMap nodes.

OS and Nuke Version dependencies

Nuke C++ plugins are compiled plugins. Meaning it turned readable human code into machine code. Compilers convert the code into the C++ plugin file.

However, each OS (Mac, Linux, Windows) converts C++ into a different filetype.

And every Nuke Minor version, Nuke 16.0 vs Nuke 16.1 for example, is slightly different and requires a new compile. Internal modules and commands may have moved or been renamed between Nuke versions, and the compiler bakes those paths into the plugin. Meaning using the plugin compiled for Nuke15.v1 with Nuke 16.0 will not work and will error out if the wrong plugin is loaded.

As a result, I created some auto-loader python code, which will correctly identify which plugin to load based on OS and Nuke version. If it cannot find the right OS or Nuke version, then the auto-loader will skip the load, ensuring that Nuke still starts safely.

You do not need to do anything, this is happening under the hood on Nuke start and ensures that the same package can be used anywhere and that the install is minimum, just pointing Nuke to the STMap_BBox folder.

I am currently supporting Mac and Linux, every Nuke Minor version from 15.0+ and will continue to update with each Nuke Minor version.

I am hoping to get my hands on a windows setup to compile on Windows machines as well. If there is enough demand, please reach out to me or create an issue on Github with Windows request and I can try and support it ASAP.


Download

Head to the latest Release page:
https://github.com/CreativeLyons/STMap_BBox-public/releases/latest

Download the STMap_BBox .zip in the Assets:


Install

Have a look at the README.md file that comes in the .zip for install instructions, but I’ll list the same steps below:

The easiest way to install would be to:

1. Download and unzip the .zip folder from the Release page

    2. Drag and Drop the STMap_BBox folder into your ~/.nuke/ folder

    3. Mac Users will need to unlock permissions so Mac can allows use of the C++ plugin. It’s a classic Mac permissions block since this is some C++ code from Github. Once the STMap_BBox folder is in your .nuke folder, open a terminal window and run this command:

    xattr -cr ~/.nuke/STMap_BBox

    If you installed it somewhere else, you can replace that last path with where ever you have put the folder. You can also simply drag a folder into the terminal window and it will enter the folder path for you.

    4. Add this line to ~/.nuke/init.py (create the file if missing):

    nuke.pluginAddPath("./STMap_BBox")

    Alternatively, point to wherever on the server you placed the STMap_BBox folder:

    nuke.pluginAddPath("/Replace/With/Path/To/Your/STMap_BBox")

    5. Restart Nuke. Find the node under Nodes → Transform → STMap_BBox, or type STMap_BBox in the Tab search.


    Thanks for trying the tool, I hope that it optimizes your lens distortion workflows.

    If you have any issues or requests, you can create a github issue here:

    https://github.com/CreativeLyons/STMap_BBox-public/issues

    Nuke Survival Toolkit Release v1.0.0

    I’m happy to bring you a side project I’ve been working on for awhile,
    The Nuke Survival Toolkit!

    The Nuke Survival Toolkit is a portable tool menu for the Foundry’s Nuke with a hand-picked selection of nuke gizmos collected from all over the web, organized into 1 easy-to-install toolbar.

    Link to the Github Release page:
    https://github.com/CreativeLyons/NukeSurvivalToolkit_publicRelease/releases

    Link to the Online Google Documentation for full res images and gifs, as well as a nice navigation panel to help search for tools:
    https://docs.google.com/document/d/1s9KoiO7MpaLZfKsgIhVnzzpSrdVpTuUhpf-DaOWHWq0/edit?usp=sharing

    Many thanks to all the tool contributors out there who made this tool menu possible.

    Special thanks and shout-out to Adrian Pueyo for the inspiration and guidance to be able to finish this project. This toolkit contains exclusive AP tools from Adrian and myself that have not been release publicly until now! Make sure to check out all tools with an AP or TL tag at the end.

    Any feedback is welcome,
    Best,
    Tony

    DirectionalBlur

    Directional Blur

    Select the rotation angle and size of the blur. Choose between blur and defocus. Has a perpendicular blur that blurs in the perpendicular direction to the angle chosen.

    Some helpful options for managing your BBox.

    Has channels, mask, mix, etc

    View the demo here on youtube:
    https://www.youtube.com/watch?v=BrioyN9YMA8&feature=youtu.be

    Or on vimeo:
    https://vimeo.com/348730566

    Download the tool on Nukepedia:
    http://www.nukepedia.com/gizmos/filter/directionalblur

    Download at my github where you can find a repository of all my tools in one place:
    https://github.com/CreativeLyons/Lyons_Tools_Public/blob/master/06_Filter/DirectionalBlur.nk

    Enjoy!

    BinaryAlpha

    BinaryAlpha_SplashPage_v01.jpg

    Binary Alpha is a very simple, yet super convenient expression that I use all the time, and decided to turn into a quick gizmo.

    It analyzes a choice of the RGB, RGBA, or Alpha input and outputs an Alpha Channel (or RGBA result) that is Binary, 0 or 1.  Any Pixels that are not 0 will be turned into 1 (negative numbers also), and 0 will remain 0.  

    This is perfect for those “blur, unpremult, set alpha, blur” for tricks extending colors, or if you need a quick matte for finding any rgb color above or below 0, in a CG render passes for example.

    The good ol’ blur/unpremult/blur ❤ :

    BinaryAlphaExample_v03_copy_2.gif

    Basic properties:

    binaryAlphaSettings_jpg.jpg

    The literal tcl expression is just:

    r!=0 || g!=0 || b!=0 || a! = 0 ? 1 : 0

    Which in english, translates to something like: 
    “if red is not 0, or green is not 0, or blue is not 0, or alpha is not 0, then be 1, or else, be 0”
    So it will include negative pixels as an output as 1 as well.

    Super simple but hopefully a time saver if you are like me and hate remembering expressions.

    Find the tool on nukepedia here:
    http://www.nukepedia.com/gizmos/channel/binaryalpha

    You can also download this tool at my github, where you’ll find all my public tools in one place:
    https://github.com/CreativeLyons/Lyons_Tools_Public/blob/master/04_Channel/BinaryAlpha.nk

    Enjoy

    BlacksMatch

    For those who just want to quickly see what the tool does, I’ll include a time-stamped link to that part of the Demo here:
    https://youtu.be/Kw3bcsmkGuk?t=2145

    BlacksMatch recreates a Toe operation with merge nodes, meaning you can now plug in an external image are your black color and it will perform the operation taking each pixel’s value into account as the blackpoint.  

    You can control the Multiply, which is how far above the blackpoint the blacks match with stop affecting your midtones and highlights.  For example, if you plugged in 0.15 and had the multiply set to 2, then values above 0.3 remain unaffected.  

    The “falloff” or Gamma control just controls the falloff of the curve into your blackpoint color.  if it’s really high, it will act more like a screen or plus (still ending at the blackpoint color times your multiply control), and if it’s really low, it will act more like a clamp.  Your blackpoint will not ever fall below your input color while you manipulate the curves.

    There is a preview plotscan button that helps you visualize how your curve is behaving with your settings.  Just move the plotscan picker around and it will sample your blackpoint color at that area and give you an overlay of your curve.  (Don’t forget to turn it off when you are done)

    I personally think this is a tool every comper should have in their toolkit, as it’s by far the most controlable way to match your blacks properly!

    The settings of the BlackMatch Tool and a wipe from the tutorial:

    BlacksMatchTutorial_ThumbforNukepedia.jpg

    There is a full video Tutorial about the BlacksMatch workflow, along with a Tool Demonstration at the end.  If you want to know how I made it and whats going on under the hood, please watch the whole video. It might give you some ideas of how to re-think your matching blacks workflow.


    Here is the Flow Chart for the Blacks Match Workflow:

    Our goals are:

    1.) Nothing should fall below the blackpoint value

    2.) The blackpoint should affect the mids/highs as little as possible.

    The Most important thing to remember is to try and not adjust any color corrections after you apply your blackpoint.


    Here’s a few examples of the importance matching blacks can be to your image:

    Here is a picture with just some beauty rendered statues, color corrected and placed into our scene, no blacks match… stands out quite a bit:

    Here is a before picture is we just turn off all the color and detail and just place “pure black” statues into our scene:

    If we start sampling the colors around the surrounding areas of the statues and applying theses as our blackpoint, still ignore any midtone/highlight color or detail. We can actually see our statues are fitting in quite nicely. You can think of it like “if there were pure black objects in my scene in that area, what would it look like?” and we are getting pretty decent results:

    And here is the image with our matched blacks properly combined with our midtones and highlights. But there is a lot of operations used to combine the blackpoint with the midtones and highlights. So let’s take a look at all of them, and study the best way of combining these:

    For the second part of our goal, the blacks should affect our midtones and highlights as little as possible. We have to look at different operations of how to apply our blackpoint:

    Here’s some graphs comparing the most common operations of how to match the blackpoint and what they are doing to a 0-1 curve.

    Here’s a closer look at the curves next to each other:

    Here is just an overlay of all the curves on top of each other to compare them to one another:


    Here is a close up of a Clamp operation:

    Here’s a close up of the plus operation:

    Here’s an example of a Screen operation:

    A close up of a Hypot operation:

    A close up of a Toe operation:


    Let’s now talk about the Good, the Bad, and the Ugly… starting with the bad:

    A screen and lift do a sililar operation between 0-1, but the screens influence stops at 1, where as a lift is actually using 1 as a pivot point to lift the blacks and lower the highlights above 1. If you set a lift to 1, it will completely decontrast the image, sandwiching every pixel and turning the entire frame to 1.

    No matter if you leave a color correct at default range, or start adjusting the range curves, the color correct produces some very strange results because of the S-curve it generates. Because it is sampling the luminance from the bg image, if you enter a black point number higher than the luma key it is calculating, than the curve will first be your black point color, then dip back down to the midtone color and rise back up to your highlights. This creates a really strange image that you’ll want to avoid.

    Avoid Lift on a Grade, and avoid ColorCorrect nodes for adjusting your blackpoint.


    The Ugly:

    Both Clamp and Plus are at the Extremes of our operations, and have the least appealing qualities. You can acheive much more control and better operations using our remains screen, hypot, and toe operations. Here is the gif of the curves compared to one another again so you can see that clamp and plus are at the extremes:

    Screen and Hypot are perfectly fine operations, but offer limited control. and Toe… Well we can’t even input an image, and we don’t even know what exactly it is doing. There’s very little documentation on it. Let’s try to reconstruct it:

    With a little bit of fiddling around. We can see the top of the toe operation is exactly double the value of the blackpoint… We need to start by re-creating a screen, which is basically an inverted luminance key, used as a mask, that is plusing out blackpoint. From there we can create a screen operation that instead of end at 0-1, ends at 0 to 2x the balckpoint value, and you can see in the example above we have a mini triangle encompassing our toe operation. There it’s a matter of using a gamma of 0.5 on the luma-key mask and we have our toe.

    So to reiterate:

    A toe is an inverted luma-key, that instead of 0-1 is 0-‘2x the blackpoint color’ and then is gammed by 0.5 and is used as a mask to plus the blackpoint color over the image.

    I know… that’s a mouthfull. But what we take away from making this toe for ourselves is that we have controls over 2 things. The multiply of how far above the black color it is affecting our midtones and highlights. And the gamma curve that is controlling our falloff of the curve towards the blackpoint value.

    With this knowledge and math, we can create a tool that uses merges to do our math operations, which mean me can plug in an external image as out blackpoint and expose controls for the mult (above the blackpoint) and gamma (falloff) of the curve. And now we have our BlacksMatch tool.


    Download the tool from Nukepedia here:

    http://www.nukepedia.com/gizmos/colour/blacksmatch_20

    Or download the tool from my github, where you can find a repository with all my tools in one place:

    https://github.com/CreativeLyons/Lyons_Tools_Public/blob/master/05_Color/BlacksMatch.nk


    I’ve received a few requests for the script and images I’ve used in the tutorial, so I’ve put together a folder on my dropbox for you guys to download and play around with.
    This is a preview of the part of the script I am saving for you. It includes the statues over the temple example, a couple of the simple shapes over complex black level images, and the part of the script that I recreated the toe, with the animating graph.

    I’m also adding a reference image folder, with some of the cool hazy/foggy complex black point images I found while researching this topic. Maybe they will be good practice for you to bring into nuke and play around.

    Finally I am adding in the original statue exr render, with some passes: beauty, depth, position, and normals, in case you want to try and color correct and match the statue render into any of these images or your own backgrounds. Thanks to Ernest Dios for the render.

    Here is the dropbox link to the project files:
    https://www.dropbox.com/sh/p47aquatmp1cai7/AAAnt_Lr4slT2RmK5znV50L3a?dl=0