I’ve been toying with blender for the last 6 or so months. Working in the Visual Effects industry has its perks- the fact that I have daily access to some seriously kickass artists who have worked on some seriously big films is a huge plus.
I’m creative at heart (I grew up through school wanting to be a film editor, and started studying to that effect straight of out school), but I’m generally more technical in most aspects of my life… Mostly solving technical problems in creative ways- I used to be a software developer, and before that a HTML and CSS monkey…
Let me be clear, I’m not an artist- but I am creative, and I have been for as long as I can recall.
I’ve struggled to find ways to express that creativity in a technical manner, until I discovered Blender, and by extension, Open Shading Language.
I’ve also been fascinated by light for a long time, how it bounces off structures and illuminates in certain ways to represent certain things… In my technical life as a Systems Administrator, this is understanding how Fibre Optic cables can transmit data packets… But to my creative side it’s a whole new world.
Iridescence is a phenomenon where a surface reflects light at different wavelengths depending on the angle they’re viewed at thanks to the microscopic surface or coating of the structure- examples include butterfly wings, beetle carapace, bubbles, oil slicks, etc. – it’s the pretty, colourful, rainbow stuff.
I have tried to emulate the pretty rainbow stuff using Open Shading Language (Written by the same clever dudes at SPI who wrote OpenColorIO and OpenImageIO).
Open shading Language is often grouped with the likes of RSL and GlSL, given that they are all formal programming languages designed for the express purpose of shading 3D models.
It, like its kin, has a C-like syntax, which happens to fall neatly into my particular skill set.
The video shows a simple iridescent effect, even if the visuals themselves are a little crude. The next plan is to periphery simulate a floating bubble using the shader.
I’m taking the BSDF from the shader and mixing that using layer weight with a transparent shader to simulate the effect while keeping render times low.
The shader code is below- it’s a bit rough and it can definitely be made better, but it works.
shader iridescence (
float WMin = 430.0, // minimum visible wavelength
float WMax = 680.0, // maxiumum visible wavelength
float Size = 5, // Coverage
int Axis = 0, // 0 for X, 1 for Y, 2 for Z
float Shift = 0, // Lateral shift based on Axis
float Intensity = 1, // brightness of colour
float RoughY = 0.5, // Roughness of Y for BSDF only
float RoughX = 0.5, // Roughness of X for BSDF only
output color ColOut = 0.8,
output closure color BSDF = diffuse(N)
) {
point ObjLoc = point("object", 0,0,0); // object origin
point CamLoc = point("screen", 0,0,0); // camera origin
point WldLoc = point("common", 0,0,0); // world origin
// get value of pixel based on distance between world, camera and object
// multiply the values by the location of the point being rendered to simulate the effect regardless of whether the object or camera moves.
float ColMask = distance(WldLoc*P,ObjLoc*P,CamLoc) * (P[Axis] * CamLoc[Axis] + Shift) * (1/Size);
// use value from above to determine wavelength
float WavLen = (WMax - WMin) * ColMask + WMin;
// adjust the colours if they fall outside visible wavelength
if (WavLen < WMin) { WavLen = WMin + (WMin - WavLen); } if (WavLen > WMax) {
WavLen = WMax + (WavLen - WMax) * 0.05;
}
// colour, can be plugged into a Shader node... or anything else that accepts colour.
// last color function here balances out RGB a bit, as blue and green seem to be more prevalent in real life iridescence.
ColOut = wavelength_color(WavLen) * Intensity * color(0.05,0.6,0.9);
// BSRF- uses ColOut as above- GGX used here, but that's not required.
BSDF = microfacet("ggx", // distribution function
N, // normal
I, // reflectance vector
abs(RoughX), // x roughness
abs(RoughY), // y roughness
2, // IOR
0) // 0 means reflect
* ColOut;
}