Rendering Overscan in Maya

There are a few attributes in Maya you can change in order to render the image with overscan. The first is resolution, while the second is either camera scale, focal length, field of view, camera aperture, camera pre-scale, camera post-scale or camera shake-overscan. I use camera scale as it’s more intuitive numbers you need to enter and it doesn’t mess with the camera aperture, focal length or field of view.

In order to render and work with overscan correctly, it needs to be done relative to your format your working with – this is typically your final output resolution inside Nuke, but it could also be the resolution of a matte-painting or a live-action plate. The way to figure out the amount of overscan to use is simple and we can use one of two methods, either based on a multiplier or based on the amount of extra pixels we want to use.

The simplest method to me is based on a multiplier. If our format size is 480*360 (as above) and we wanted to render the image with an extra 10%, we multiply the resolution by 1.1 and set the camera scale to 1.1. Like so…

Then in Nuke all we need to do is apply a Reformat node and set it to our original render format of 480×360, the resize type=none and keep preserve bounding box=on  – this has the effect of cropping the render to our output size but keeping the image data outside of the format. Or additionally you can set the reformat like so… type=scale; scale=0.90909091; resize type=none; preserve bounding box=on. Instead of typing in 0.90909091, you can also set the scale by just typing in 1/1.1 …

If we instead wanted to render an extra 32 pixels to the top, bottom, left and right of our image – making the image 64 pixels wider and higher – we need to do things a little bit differently as we need to change the camera aperture. The reason for doing this is that adding the same number of pixels to both the width and height results in a very slight change to the aspect ratio of the image.

new width = original width + extra pixels
new height = original height + extra pixels
overscan width = new width / original width
overscan height = new height / original height
new aperture width = original aperture width * overscan width
new aperture height = original aperture height * overscan height

So using our 480×360 example from above. If we wish to add an extra 64 pixels to the width and height we would calculate it like so…

480 + 64 = 544
360 + 64 = 424
544 / 480 = 1.13333333
424 / 360 = 1.17777777
1.417 * 1.13333333 = 1.606
0.945 * 1.17777777 = 1.113

Same as before in Nuke we then apply a Reformat node with the following settings. type=to box; width/height=480, 360; force this shape=on; resize type=none; preserve bounding box=on

More VRay Scene Access… or some more random tidbits

Following on from the last post. Here are another example of how you can mess around with VRay scenes using Python.

figure 1: transform += random() * 2, random() * 2, random() *2

This collection of cubes was created using only one cube, it’s been instanced 2500 times and moved about randomly, to do this I’ve used the random module in Python which is handy for doing random number things.

# figure 1
from vray.utils import *

import random as r

l=findByType("Node") # Get all Node plugins
v=Vector(0.0, 0.0, 0.0)
for x in range(2500):
	dupl = l[0].duplicate('dup' + str(x))
	v = Vector(r.random()*2, r.random()*2, r.random()*2)
	t.offs += v
	dupl.set("transform", t)

The r.send(1) is used to create a seed point for any future calls to random module, this means that the random numbers chosen are going to be the same each time we render the image – if we’re making changes to the render we don’t want the position of the cubes to change each time we render.

The v variable is used to store the random number we’re using to offset the transform, at the moment this is just is using random.random() which produces random values between 0 and 1, in the above example this has the effect of moving the cubes only along the positive xyz axis. There is also random.uniform(min,max) which produces random values between the min and max numbers we give it.

figure 2: transform += uniform(-1,1) * 2, random() * 2, random(-1,1) * 2

Here the effect moves the cubes along positive and negative XZ. I’ve keep the Y axis in positive space so that the cubes don’t go through the ground plane.

# figure 2
from vray.utils import *

import random as r

l=findByType("Node") # Get all Node plugins
v=Vector(0.0, 0.0, 0.0)
for x in range(20):
	dupl = l[0].duplicate('dup' + str(x))
	v = Vector(r.uniform(-1,1)*2, r.random()*2, r.uniform(-1,1)*2)
	t.offs += v
	dupl.set("transform", t)

OpenEXR and 3Delight

The OpenEXR format has a number of useful features which are super handy for CG animation and VFX such as saving the image data in either half or full floating point, setting data-windows and adding additional metadata to the the file. 3Delight for Maya allows you to use all these features, but doesn’t cover how to use them in the documentation (at least I couldn’t find mention of it).

In order to use gain access to these features you need you need to add an extra attribute to the render pass called “exrDisplayParameters”. In the example below, the name of my render pass is called “beauty”.

addAttr -dt "string" -ln exrDisplayParameters beauty;
setAttr "beauty.exrDisplayParameters" -type "string"
"-p \"compression\" \"string\" \"zip\" -p \"autocrop\" \"integer\" \"1\" ";

The string attribute should end up looking like so in the attribute editor…

-p "compression" "string" "zip" -p "autocrop" "integer" "1"

The above sets the compression type to zip and to also tells 3Delight to autocrop the image when it’s rendered. Auto-crop adjusts the bounding box of the data-window (or ROI, region-of-interest) to only contain non-black pixels (I believe it does this based on the alpha channel), this allows Nuke to process the image quicker as it only calculates information within that data-window. See this tutorial on Nuke Bounding Boxes and how to speed up your compositing operations.

The basic syntax of the parameter string is easy enough to understand, the three arguments passed to the -p flag are name, type and value.

-p "[name]" "[type]" "[value]"

You can also add additional metadata to the header of the EXR render. For example you may wish to include things such as

  • Project, scene and shot information.
  • Characters or creatures in the shot.
  • Model, texture, animation versions used.
  • Maya scene used to render the shot.
  • Focal length, Fstop, Shutter Angle, Filmback size.

3Delight already includes some metadata already with the EXR, so you don’t need to add information for the following…

  • Near and far clipping planes.
  • WorldToCamera and WorldToNDC matrices. The Nuke Python documentation has info on how you can use this to create cameras in Nuke based of this data.

You can add this metadata using the “exrheader_” prefix and then the name of your attribute. The following will add three metadata attributes called “shutter”, “haperture” and “vaperture”.

-p "exrheader_shutter" "float" "180" -p "exrheader_haperture" "float" "36" -p "exrheader_vaperture" "float" "24"

While the following will add the project name “ussp” and the maya scene name that was used to render the shot…

-p "exrheader_project" "string" "ussp" -p "exrheader_renderscene" "string" "h:/ussp/bes_0001/scenes/"

The easiest way to get information from your scene to this parameter pass is to set up a Pre-Render MEL script in your render-pass along the lines of…

string $sceneName = `file -q -sn`; //Grab the name of the current scene.
string $projectName = `getenv "PROJECT"`; //This assumes you have an environment variable called "PROJECT" with the project name setup already.
string $parameters = "";
$parameters += (" -p \"exrheader_renderScene\" \"string\" \"" +  $sceneName + "\" ");
$parameters += (" -p \"exrheader_projectName\" \"string\"" + $projectName + "\" ");
setAttr ($pass + ".exrDisplayParameters") -type "string" $parameters;

See the 3Delight documentation has more information on what type of metadata you can add  to the EXR.