Section 4.8.4.6.3
Caustics And Normals

POV-Ray makes use of surface normal perturbation in a way that is more unique than people generally stop to think. When we apply a surface normal in a texture we are actually not altering the surface at all, but rather telling POV-Ray to treat the surface as if it were altered, for purposes of computing the illumination falling on each individual spot. In short, it is a trick of the light and shadow which, supposing only that we don't see it at too sharp a viewing angle, effectively creates the illusion of distortions in the surface of an object.

Caustics are also a synthetic trick, as we saw above, and sure enough, they have been designed to react to texture normal patterns as if those patterns were genuinely there. Remember the drinking glass experiment? If we found a glass with patterns etched into the surface we probably noted that the pattern showed up in the caustics cast by the glass too. When we have a transparent surface with a normal applied to it, it causes the caustics cast by that surface to mimick the normal pattern, so that it shows up in the shadows.

Following is an example of what we mean: it is a simply meant to represent water in a swimming pool. We have distilled this down to a plane above to represent the water, one below to represent the floor of the pool, a camera just below the waterline, looking at the floor, and a light source high above (see caustic2.pov).

#include "colors.inc" // Our camera is underwater, looking at the bottom of // the pool for the best view of the caustics produced camera { location <0, -5, 0> look_at <0, -10, -5> } light_source { <0, 100, 49.5> color White } // the bottom of the pool... plane { y, -10 texture { pigment { color rgb <0.6, 0.7, 0.7> } finish { ambient 0.1 diffuse 0.7 } scale 0.01 } } // and the surface of the water plane { y, 0 texture { pigment { rgbf <0.6, 0.67, 0.72, 0.9> } normal { bumps .6 scale <.75, .25, .25> rotate <0, 45, 0> } finish { caustics .9 } } }

The bumps we have given the water plane are meant to represent the small, random crests and troughs that form on a pool when a light breeze blows over it. We could have used ripples or waves as well, like something had recently splashed into it at some point, but the bumps will work well enough for an example.

We notice that our view of the pool floor shows dozens of tiny caustic light spots, corresponding approximately to a random bump pattern. If we like we can try putting in ripples or waves and watch the pattern of the caustics change. Even though a flat plane itself would cast no caustics (we could try without the normal), POV-Ray's faked caustic generation knows that if the surface was really bumped like this normal is indicating, the refraction of the bumped surface would be just enough to concentrate light in caustics throughout the bottom of the pool.

We see that just as with a curved surface, such as the sphere previously, normal patterns also trigger the appearance of caustics cast by an object. Interestingly enough, this alone would be proof that the caustics really are faked: our water hasn't even been given any refraction properties in its finish, yet the caustics are still there just the same!


Section 4.8.4.7
Using Iridescence

Iridescence is what we see on the surface of an oil slick when the sun shines on it. The rainbow effect is created by something called thin-film interference (read section "Iridescence" for details). For now let's just try using it. Iridescence is specified by the irid keyword and three values: amount, thickness and turbulence. The amount is the contribution to the overall surface color. Usually 0.1 to 0.5 is sufficient here. The thickness affects the busyness of the effect. Keep this between 0.25 and 1 for best results. The turbulence is a little different from pigment or normal turbulence. We cannot set octaves, lambda or omega but we can specify an amount which will affect the thickness in a slightly different way from the thickness value. Values between 0.25 and 1 work best here too. Finally, iridescence will respond to the surface normal since it depends on the angle of incidence of the light rays striking the surface. With all of this in mind, let's add some iridescence to our glass sphere.

sphere { <0,0,0>, 1 pigment { White filter 1 } finish { ambient .1 diffuse .1 reflection .2 refraction 1 ior 1.5 specular 1 roughness .001 fade_distance 5 fade_power 1 caustics 1 irid { 0.35 thickness .5 turbulence .5 } } }

We try to vary the values for amount, thickness and turbulence to see what changes they make. We also try to add a normal block to see what happens.


Section 4.8.5
Halos

Important notice: The halo feature in POV-Ray 3.0 is somewhat experimental. There is a high probability that the design and implementation of these features will be changed in future versions. We cannot guarantee that scenes using these features in 3.0 will render identically in future releases or that full backwards compatibility of language syntax can be maintained.

Halos are a powerful feature that can be used to create a lot of different effects like clouds, fogs, fire, lasers, etc. The name actually comes from the ability to render halos with it, like the ones seen around the moon or the sun.

Due to the complexity of the halo feature and the large amount of parameters provided it is very difficult to get satisfying results. The following sections will help to create a halo step by step, starting with the basic things and going to the more subtle stuff.

It is also helpful to read the halo reference sections to get a better understanding of the halo feature. One should especially read the sections "Empty and Solid Objects" and "Halo Mapping" because they are essential for understanding halos.


Section 4.8.5.1
What are Halos?

Halos are a texture feature allowing us to fill the interior of an object with particles. The distribution of these particles can be modified using several density mappings and density functions. The particles can emit light to give fire- or laser-like effects or they can absorb light to create clouds or fog.

A halo is attached to an object, the so called container object, just like a pigment, normal or finish. The container object is completely filled by the halo but we will not see anything if we do not make sure that the object is hollow and the surface is translucent. How this is accomplished will be shown in the next section.

When working with halos we always have to keep in mind that the container object has to be hollow and translucent.


Section 4.8.5.2
The Emitting Halo

We start with one of the simpler types, the emitting halo. It uses particles that only emit light. There are no particles that absorb the light coming from other particles or light sources.

Section 4.8.5.2.1
Starting with a Basic Halo

A clever approach in designing a nice halo effect is to start with a simple, unit-sized shape that sits on the coordinate system's origin.

In the first example (halo01.pov) we try to create a fiery explosion, which the sphere is best suited for. We start with a simple scene consisting of a camera, a light source (we don't care about shadows so we add the shadowless keyword), a checkered plane and a unit-sized sphere containing the halo.

camera { location <0, 0, -2.5> look_at <0, 0, 0> } light_source { <10, 10, -10> color rgb 1 shadowless } plane { z, 2 pigment { checker color rgb 0, color rgb 1 } finish { ambient 1 diffuse 0 } scale 0.5 hollow } sphere { 0, 1 pigment { color rgbt <1, 1, 1, 1> } halo { emitting spherical_mapping linear color_map { [ 0 color rgbt <1, 0, 0, 1> ] [ 1 color rgbt <1, 1, 0, 0> ] } samples 10 } hollow }

We note that the sphere is set to be hollow and has a translucent surface (the transmittance channel in the pigment's color is 1), just like it is required for halos. We also note that the plane has a hollow keyword even though it has no halo. Why is this necessary?

The reason is quite simple. As described in section "Empty and Solid Objects" there can be no halo inside any other non-hollow object. Since the camera is inside the plane object, i. e. it is on the side of the plane that is considered to be inside, the halo will never be visible unless the plane is made hollow (or the negative keyword is added to bring the camera on the outside side of the plane).

What do all those halo keywords and values mean? At the beginning of the halo the emitting keyword is used to specify what type of halo we want to use. The emitting halo emits light. That is what is best suited for our fiery explosion.

The spherical_mapping and linear keywords need a more detailed explanation of how a halo works (this is also done in chapter "Halo" in more detail).

As noted above the halo is made up of lots of small particles. The distribution of these particles is described by a density function. In general, a density function tells us how much particles we'll find at a given location.

Instead of using an explicitly, mathematical density function, halos rely on a given set of density mappings and density functions to model a variety of particle distributions.

The first step in this model is the density mapping function that is used to map three-dimensional points onto a one-dimensional range of values. In our example we use a spherical mapping, i.e. we take the distance of a point from the center of the coordinate system. This is the reason why it is clever to start with a container object sitting on the coordinate system's center. Since all density mappings are made relative to this center we won't see anything if we start with an object sitting somewhere else. Moving the whole object (including textures and halos) to another location is the correct way of placing a container object.

Now we have a single value in the range from 0 to 1. This value will be transformed using a density function to get density values instead of distance values. Just using this single value won't work because we want to have particle distributions were the density decreases as we move from the center of the container object to the outside.

This is done by the density function. There are several alternatives available as described in the halo reference (see section "Density Function"). We use the simple linear function that just maps values between 0 and 1 onto a 1 to 0 range. Thus we get a density value of 1 at the center of our sphere and a value of 0 at its surface.

Now that we have a density function what do we do to see something? This is where the colour_map keyword comes into play. It is used to describe a color map that actually tells the program what colors are to be used for what density. The relation is quite simple: colors at the beginning of the color map (with small values) will be used for low density values and colors at the end of the map (high values) will be used for high densities. In our example the halo will be yellow at the center of the sphere where the density is greatest and it will blend to red at the surface of the sphere where the density approaches zero.

The transmittance channel of the colors in the color map is used to model the translucency of the density field. A value of 0 represents no translucency, i. e. that areas with the corresponding density will be (almost) opaque, while a value of 1 means (almost) total translucency.

In our example we use

color_map { [ 0 color rgbt <1, 0, 0, 1> ] [ 1 color rgbt <1, 1, 0, 0> ] }

which results in a halo with a very translucent, reddish outer area and a nearly opaque, yellowish inner areas as we can see after tracing the example image.


The basic halo used in modelling a fiery explosion.

There is one parameter that still needs to be explained: the samples keyword. This keyword tells POV-Ray how many samples have to be taken along any ray traveling through the halo to calculate its effect. Using a low value will result in a high tracing speed while a high value will lead to a low speed. The sample value has to be increased if the halo looks somewhat noisy, i. e. if some artifacts of the low sampling rate appear. For more details see section "Halo Sampling".

A good starting value for the number of samples is 10.


Section 4.8.5.2.2
Increasing the Brightness

The colors of the halo in the above image are somewhat dim. There is too much of the background visible through the halo. That does not look much like fire, does it? An easy way to fix this is to decrease the transparency of the particles in the areas of high density. We do this by using use the following color map instead of the old one (the negative transmittance is correct).

color_map { [ 0 color rgbt <1, 0, 0, 1> ] [ 1 color rgbt <1, 1, 0, -1> ] }

Looking at the result of halo02.pov we see that the halo is indeed much brighter.


The halo is much brighter now.


Section 4.8.5.2.3
Adding Some Turbulence

What we now have does not look like a fiery explosion. It's more a glowing ball than anything else. Somehow we have to make it look more chaotic, we have to add some turbulence to it.

This is done by using the turbulence keyword together with the amount of turbulence we want to add. Just like in the following example.

sphere { 0, 1 pigment { color rgbt <1, 1, 1, 1> } halo { emitting spherical_mapping linear turbulence 1.5 color_map { [ 0 color rgbt <1, 0, 0, 1> ] [ 1 color rgbt <1, 1, 0, -1> ] } samples 10 } hollow }

Adding turbulence to the halo moves all points inside the halo container in a pseudo-random manner. This results in a particle distribution that looks like there was some kind of flow in the halo (depending on the amount of turbulence we'll get a laminar or turbulent flow). The high turbulence value is used because an explosion is highly turbulent.

Looking at the example image (halo03.pov) we'll see that this looks more like a fiery explosion than the glowing ball we got until now.


Adding some turbulence makes the fiery explosion more realistic.

We notice that the time it took to render the image increased after we added the turbulence. This is due to the fact that for every sample taken from the halo the slow turbulence function has to be evaluated.


Section 4.8.5.2.4
Resizing the Halo

There is one strange thing about our fiery explosion though. It still looks like a sphere. Why does this happen and what can we do to avoid it?

As noted above adding turbulence moves the particles inside the halo container around. The problem is that some of the particles are actually moved out of the container object. This leads to high densities at the surface of the container object revealing the shape of the object (all particles outside the container are lost and will not visible resulting in a large, highly visible density change at the surface).

An easy way of avoiding this is to make sure that the particles stay inside the container object even if we add some turbulence. This is done by scaling the halo to reduce its size. We do not scale the container object, just the halo.

This is done by adding the scale keyword inside the halo statement.

sphere { 0, 1 pigment { color rgbt <1, 1, 1, 1> } halo { emitting spherical_mapping linear turbulence 1.5 color_map { [ 0 color rgbt <1, 0, 0, 1> ] [ 1 color rgbt <1, 1, 0, -1> ] } samples 10 scale 0.5 } hollow scale 1.5 }

The scale 0.5 command tells POV-Ray to scale all points inside the halo by this amount. This effectively scales the radius we get after the density mapping to a range of 0 to 0.5 instead of 0 to 1 (without turbulence). If we now add the turbulence the points are allowed to move half a unit in every direction without leaving the container object. That is exactly what we want.

To compensate for the smaller halo we would get we scale the sphere (and the halo inside) by 1.5.

Looking at the new example image (halo04.pov) we will no longer see any signs of the container sphere. We finally have a nice fiery explosion.


Resizing the halo makes it look much better.

The amount by which to scale the halo depends on the amount of turbulence we use. The higher the turbulence value the smaller the halo has to be scaled. That is something to experiment with.

Another way to avoid that points move out of the sphere is to use a larger sphere, i. e. a sphere with a radius larger than one. It is important to re-size the sphere before the halo is added because otherwise the halo will also be scaled.

We note that this only works for spherical and box mapping (and a non-constant density function). All other mapping types are (partially) infinite, i. e. the resulting particle distribution covers an infinite space (see also "Halo Mapping").


Next Section
Table Of Contents