iridescence_2d

Iridescence on surfaces is an interesting effect and can be a challenge to get looking correctly. This effect occurs for example on some animal skin as well as on surfaces covered in oil under certain conditions. Because it is a very specific look it can often times require lots of iterations until the client is happy with the result, so quick turnarounds are often neccessery. Luckily it also often times is quite a subtle effect so it’s a good candidate to try and look develop in 2D instead of constantly re-rendering your CG.
On a recent project I was working on an environment that has been covered in oil. The client requested a subtle iridescence effect on it. The whole environment was expensive to render so turnaround would be very slow so here’s what I did to lookdev the iridescence effect in Comp.
The theory of iridescence is pretty simple. It’s the change of hue over a surface depending on the angle you are viewing the surface. First of all getting that hue range in across an image is fairly simple. Hue is represented in Nuke in a 0-1 range. values above 1 and below 0 repeat the hue pattern. With the help of a Colorspace node you can easily transfer a black and white ramp into a shifting hue across the image. Assuming you have a ramp for red (Hue), constant white for green (Saturation) and constant white for blue (value/luminance) you can get a simple hue ramp:
01_ramp
Now it would be great to have a bit more control over the hue. You might want to compress/expand or offset the hue range. Unfortunately Nuke’s built-in Hueshift node does… some weird stuff. So I created a simple Gizmo to adjust the Hue properly:

As you can just use a black->white ramp and transform it to a hue range it’s simple to do that on a rendering depending on viewing angle as well. All you need is a Fresnel pass. If you don’t have one another option would be to output camera normals and use the blue channel, which is essentially the same thing:
02_fresnel
It looks slightly psychadelic as is, but if you mix it into your speculars for example towards the glancing angles it doesn’t look too bad :)
03_baseRender
Something that always helps making things look more realistic is variation. At the moment There’s a constant change in color across the surface. Every angle that faces 60┬░ away from the camera has exactly the same color for example. It would be nice to add some variation to that. In most shading systems you could modify this falloff with a few noises and luckily you can do exactly the same thing in Nuke. Nuke features some basic expressions that allow for the creation of noises through 3d Position data (Pref for moving objects such as characters, Pref or Pworld for static objects such as environments). Those expressions would be the turbulence, random and fBm noise functions – syntax reference HERE.
So we could start with a simple fBm noise function to wrap around our model. If you shuffle out the 3d Position data and add an expression node you can specify the function in there:
04_baseNoise
In this case I’m using fBm(r,g,b,10,1.3,1) which, if you refer to the docs, creates an fBm on the x,y,z positions (r,g,b here), with 10 octaves, a lacunarity of 1.3 and a gain of 1. Now, as you can see the noise is very uniform, which gives away the fact that it has been procedurally generated. What I usually do to get a bit more randomness is mixing multiple noises together. One thing I often do in 3d shading networks is to experiment with modifying noise parameters (such as time offset, lacunarity, etc.) with other noises. This usually gives a good starting point for random patterns. In nuke this is possible as well, even tough it’s a bit more cumbersome.
So I’d like to create a second noise to drive the lacunarity for example. I will use a simple random function which gives me a simple normalized random noise. I would however like my lacunarity rather be between 0.4 and 1.4 instead of between 0 and 1, so I’m offsetting the random function by 0.4 after its generated. Also I would like to pipe the output of this noise in an arbitrary secondary channel (in this case noise01), because it’s sole purpose will be to drive the lacunarity of the other noise:
05_driveLacunarityNoise
So what I can do now, is to use this noise01 channel to modify the lacunarity of my fBm noise. This will give me random lacunarity values across the surface:
06_drivenLacunaritySwirls
This gives a nice swirly look which can be used to randomize the oil a bit. In this case I’m multiplying the final noise by a factor of 0.2 with the fresnel pass before converting it to HSV. Here’s a comparison of just the fresnel pass and the fresnel pass multiplied with the swirly noise:
07_orig_iridescence08_modified_iridescence
As Iridescence is an effect that often has stronger presence towards the glancing angles you can mix it into your speculars with the fresnel mask. Of course you can take it further and modify that mask you mix it in with other noises, etc. to give it an even more random appearance. The options are limitless :)
Here’s a testrender with just simple modifications that gives a good starting point:

Also for anyone interested the Nuke script with all the examples shown can be obtained HERE.