This got started from a question on the Renderman forums about the difference between ST and UV. Renderman uses UV and ST to differiate between “implicit” and “explicit” texture coordinates. Implicit is automatically defined by the geometric shape and explicit is manually defined by the user.
With polygons and subdivision geometry, Renderman uses ST coordinates for texture mapping (it converts Maya UVs to Renderman STs behind the scenes). But it also automatically assigns UV coordinates to each face on the geometry, you might ask why would you need this?
For a while I’ve wanted to implement colour temperature control into my lighting workflow but I’ve never been able to figure out how it’s calculated. Then I came across this site, which has already mapped out blackbody temperatures to normalised sRGB values.
Using this as a starting point I mapped out the values into a SL function…
color blackbodyfast( float temperature;)
uniform color c =
float amount = smoothstep ( 1000, 10000, temperature );
color blackbody = spline ( "catmull-rom", amount, c,
I decided rather than map every temperature value from 1000K to 40000K, I decided just to deal with 1000K to 10000K using the CIE 1964 10 degree Colour Matching Functions – only because of the later date of 1964, I couldn’t see (nor greatly understand) the difference between the colour matching functions. The original function I wrote called blackbody used every value of the kelvin scale from 1000K to 10000K, this resulted in an array of 90 values. The modified one above uses every 6th value which brings the array size down to 16 values, in my tests I didn’t notice a speed difference using 90 values, but looking at a comparison of the two functions I couldn’t see enough visual difference to bother using the full 90 steps.
There is a slight peak where the warm and cool colours meet in the 90 step version. It’s a bit more obvious looking at the image in linear light.
Because the values are in sRGB, they need to be converted to Linear before getting used in the shader. The SL used in the main body of my test surface looks something like this…
uniform float temperature = 5600; #pragma annotation temperature "gadgettype=intslider;min=1000;max=10000;step=100;label=Temperature;"
color blackbody = blackbodyfast (temperature);
blackbody = sRGB_decode(blackbody);
Oi = Os;
Ci = blackbody * Oi;
Used in a light shader the output looks something like this…
The only problem now is that 3Delight doesn’t show a preview of light shader or more importantly the colour temperature in the AE settings for my light.
To get around this I decided to implement an expression which changed the colour of the Maya light that my 3Delight shader was attached to. Because MEL doesn’t have a spline function like SL does I had to improvise using animation curves. First up the MEL to create the three curves that I need to create the RGB colour temperature.
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”.
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
When you create a custom SL shader in 3Delight it’ll create a automatically create a shader which looks like this in Maya. Now the following UI doesn’t look very useful – the names we’ve called our variables vary in how descriptive they are – which isn’t very useful if others are going to be using this shader
This is based off a shader which looks like this the following SL code.
This will create a shader that looks like this. The hint will be displayed either in the Maya status line or as a tool-tip if you hover the cursor over the UI element.
You can place the #pragma lines anywhere in your SL file, to see them you will need to re-compile the shader and then reload the shader inside Maya by right clicking on the shader, selecting “reload shader” and then selecting the shader in either the Assignment Panel or the Outliner.
// decode from sRGB luma to linear light
float sRGB_decode_f(float F)
if(F <= 0.03928)
lin = F/12.92;
lin = pow((F+0.055)/1.055, 2.4);
color sRGB_decode(color C)
setcomp(D, 0, sRGB_decode_f(comp(C,0)));
setcomp(D, 1, sRGB_decode_f(comp(C,1)));
setcomp(D, 2, sRGB_decode_f(comp(C,2)));
The first function sRGB_decode_f does the majority of the work, the second function sRGB_decode uses that in order to operate on an input colour. To use this in SL we would use something along the lines of this. The first line here creates a colour variable with a mid-grey value in sRGB space. The second line converts that colour into a linear colour.
color myColour = (0.5);
myColour = sRGB_decode(myColour);