Monday, July 28, 2008

Six Tuts On Light And Shade, Part V, Candle Light

Sunny AfternoonTwilightMoonlightElectricalCandle LightUnderwater


Ahoy, and welcome back to the fifth part of our lighting tutorial series! Interestingly the general matter on this one will technically be the same as the last time, where we discussed the behavior of electric light bulbs, however the result will be considerably different. So lets turn off the lamps and fetch the matches, to get our candle light tutorial started.

In the last tutorial we already learnt the technical aspects of heated bodies, like tungsten filament, or wick. It became clear that in a simplified yet meaningful way the emitted color always has a very determined type, only depending on the temperature of the heated body. And curiously this special rule does not depend at all on the material of the heated body. So we can pick up where we left, and simply translate this rules to our new topic.

Lets recall the behavior of a heated 'black body'. Whenever matter is heated, it emits photons with certain intensities at distinct frequencies. This 'fingerprint' of the radiation is then called a spectrum. Now a black body is an 'ideal physical model' which absorbs all radiation and which does not reflect any at all. The interesting thing about this is that the spectrum ('color') of such a body is strictly defined by physical law, and is solely dependant on the actual temperature of the body. Of course this is somewhat simplified, as the actual emission spectrum of our heated material (i.e. carbon and hydrogen, bounded in the, lets propose, paraffin of our candle) is neglected this way. Still this 'ideal model' does a good job at simluating our situation.

Now that we have an idea of how to model the color of our candle-light we can start to give it shape. According to gravity and buoyancy laws (hot things move upwards due to their lower density), the candle flame has this wellknown 'drop shape'. If you ever wondered how a candle burnt at zero gravity, see the right side of Fig. 1 - the hot and 'lighter' gas does not circulate ('convect') as well as down here on earth, instead it spreads uniformly and no oxygen (although available!) raises after it, so it is likely forced to extinguish soon.

Fig. 1

For the sake of simplicity I decided to use a simple fotograph of a candle flame as a so called sprite, or billboard object (Fig. 2). I already adapted the image's hue to the temperature we will be using later on, which you might want to consider too, but more on this shortly.

Fig. 2

The billboard is then placed closely to the wick (Fig. 3), to model the flame. This is a simple and popular method of representing rather complex to shape or simulate stuff, be it flames, snow, leaves, grass, pylons, and probably an arbitrarily huge bunch of other things one could think of.

Fig. 3

It obviously makes sense to take care of certain factors when dealing with such 'tricks', so I adjusted all necessary render flags of this sprite, to avoid render artifacts (Fig. 4). For example it of course does not make sense to let this helper object cast shadows (after all it is replacing a light emitting entity), or to leave it visible to reflections or refractions (the actual light will handle this later on with the 'highlights').

Fig. 4

The next rational step in our abstraction of the candle light is to build the actual light emitting 3d representative. I chose a spherical area light for this job, with a little scale in the 'up' direction' (Fig. 5). I placed it closely to where our 'fake' flame is, right above the wick. Since we took care of the sprite's render flags it does not interfere with the light at all.

Fig. 5

Now that we have our light source constructed, we shall give it life with an appropriate color. As described earlier, we have robust guidelines on how to deal with this, in order to create naturally looking candle light. We solely need to know the approximate temperature at which a candle flame burns in average. The sources on this however seem to diverge quite a bit; some state a temperature of around 1300 Kelvin (~1000 degree Celsius, or ~1800 degree Fahrenheit) and some even state it at around 2300 K (~2000 °C, or ~3600 °F). I went for the middle of these values, and decided for a temperature of 1800 K, which equals to around ~1500 °C or 2800 °F. This is the tempereatre (color) we should align our candle sprite texture to, in order to yield a convincing congruence in the rendering.

There are many Kelvin-to-color converters on the internet which we could use to obtain the desired color, but luckily there is also a built-in tool that ships with mental ray for Maya. It is called mib_blackbody and can be found under the mental ray lights tab of the 'Create Render Node' menu in the hypershade (Fig. 6).

Fig. 6

This node only has two attributes we need it to feed, the temperature (in Kelvin, or 'absolute' temperature), and an intensity value (Fig. 7). If we wanted to really (really!) exactly simulate a candle light, or any light at all, we would have to actually know it's luminous power, also called luminous flux or lumen (read on this link for further information), and then we would have to convert this value into the Maya/mental ray world with some effort on both the emitting (light) and receiving (camera) side. Maya 2008 has some built-in improvements on this, however, since we dont do a radio-/photometric scientific simulation we simply GUESSTIMATE the intensity. I went for a value of 2500. To finally make use of this little tool, I connect it to the light's color slot - the light's intensity is left at 1.0 (this is handled by the mib_blackbody), and I also make sure the decay rate is set to 'Quadratic'.

That's pretty much it for the scene part, lets head over to the rendering department.

Fig. 7

We prepare the final gathering settings for quick yet meaningful convergence of the indirect illumination (Fig. 8). We only need few rays (32) and a coarse point density (0.5) for our preview. Of course we will refine everything for our final image. I left the final gather 'mode' at automatic, i.e. the 'Optimize for Animations' and 'Use Radius Quality Control' are kept OFF.

Fig. 8

The trace depths however need to be increased, along with the general raytracing settings; I decided for 2 'bounces', as well for the diffuse contribution, which I revise in the miDefaultOptions node (Fig. 9): although I turn them ON in the render globals, they are stuck at 1 bounce due to a little bug. I want them to be of depth 2, so I adjust them 'under the hood' in the miDefaultOptions.

Fig. 9

Before we actually render, we must care about the color space, so its time for our little gamma-mantra (since we dont want odd and cg-ish looking, grungy true-linear shadings). Thus I put ourselves into the right color space, which is sRGB, the commonly used space for things like photographs. Although we cannot precisely apply this color profile right away (at least not easily in mental ray for Maya 8.5), we simply apply a so called gamma correction curve of value 2.2 to our image, which usually is sufficient. This implies some caution: because the textures we usually use are already in sRGB, or hence gamma corrected, we need to un-gamma them before we correct the whole image again. That seems awkward and unnecessary but makes total sense for a reason - if we want the (gamma corrected/sRGB) texture to look like we are used it to look like, we need to remove the gamma correction first, before we RE-apply it on the whole image. Odd stuff, but makes our picture look pretty and more natural.

Thankfully mental ray has this remove-texture-gamma-and-re-apply-it thing built in already, and we simply set the desired gamma correction value in the framebuffer>primary framebuffer tab of the render globals (Fig10). However, mental ray wants us to actually specify the inverted function, which is 1/2.2=0.455 in our case. For more information on the gamma issue, I encourage you to read the 'Note on Color Space' in the very first part of this tutorial series.

Fig. 10

A quick test render yields some strange, blotchy artifacts though (Fig11). This is due to the close proximity of certain objects to the area light - we would have to either move them (or the light) a little farther away, or exclude them from the final gathering and reflection/refraction computation somehow. Since we obviously have a great demand to keep the light close to the candle, we are forced to take the latter solution.

Fig. 11

We simply switch OFF the corresponding render flags in the candle's and wick's shape node (Fig12). This basically cures the bright-blotches-problem. To furthermore suppress this kind of blotches, I decided to use a final gathering filter of 1. This filter should be handled with care, and only be used as a last resort.

Fig. 12

Another test rendering verifies this (Fig13), and we have takeoff clearance. Lets raise the quality to something more usable (which basically means we are extending the flaps, to stay in the metaphor).

Fig. 13

First, lets raise the general sampling settings (Fig14). The minimum level is kept at 0, the maximum level is set to 2, which means a maximum of 4^2, or 16 samples per pixel (whereas the rule is 4^n, and n means the sampling level). The contrast is lowered to 0.05 each. I usually use a narrowed gauss filter of width 2.0 (default is 3.0!) both in x and y, which gives sharp, fast and nice sample filtering.

Fig. 14

In the end, lets give the final gathering a final quality (Fig15). I rose the rays (accuracy) to 64, and the point density to 2.0, which should be more than enough for our still image.

Fig. 15

I also turned on the 'detail ambient occlusion' mode of the mia shaders. All you need to do is to select all the mia shaders in the hypershade, open up the attribute spread sheet, and set the Ao_on attriubte to 1 (ON) (Fig16). This ensures we see all the little details that are too small to be captured properly by a rather coarse final gathering solution.

Fig. 16

Last but not least, we could go for a floating point framebuffer, if we liked. To do so from within the render view and without going to a batch, we simply had to switch the framebuffer to either RGBA (Float), or RGBA (Half), turn the 'Preview Convert Tiles' ON, the 'Preview Tonemap Tiles' OFF, and use an appropriate file format, like OpenEXR (Fig17).

Fig. 17

Thats it. I came up with this final interpretation, after going through a few color, white-balance and contrast image operations (Fig18).

I hope you enjoyed following our little candle light exercise as much as I enjoyed writing it! And I'd be glad to welcome you next time to our final part, which is probably the most challenging and most definitely the eeriest one: about underwater lighting!

Discuss on cgtalk

Fig. 18


Original concept and geometry - Richard Tilbury

Original idea - Tom Greenway

Editor - Chris Perrins

Tutorial - floze

Sunny AfternoonTwilightMoonlightElectricalCandle LightUnderwater


  1. Wow~I am looking for making a candle light in the scene for a long time !! Thanks your~