The Online POV-Ray Tutorial

POV-Ray Language Things

This section covers POV-Ray directives, object transformations, and various miscellaneous features. These include

Background

The background statement allows you to change the background color of the image. Any rays which do not strike any objects are colored with the background color. This must be a solid color; fancy pigments and textures are not allowed. Also, Objects do not cast shadows on the background. All in all, the background will look positively flat, but it also requires no extra effort from the POV-Ray to change the background color. This effect sometimes be exactly what you need, other times it'll just make your scene look strange. The syntax for specifying the background is as follows.

background {
   color color-spec
}

color-spec is any solid color, whether declared with a name or defined with rgb. Here are two example background statements.

background {
   color Red
}

background {
   color rgb <0.3, 0.6, 0.7>
}

Note that you should only have one background statement in your scene file. If you want a textured background, try using a "sky sphere." This is a large sphere (radius of maybe 10000) on which you place a texture. Note that the texture will doubtless have to scaled up (by a factor oy maybe 5000. it depends on the texture). If you don't want objects to cast shadows on your sky sphere, include the following statements in the sky sphere's finish.

finish {
   diffuse 0
   ambient 0.7
}

This will make your sphere look somewhat flat, too, but that may be the effect you want from your sky. As always, experiment with it until you get something you like.


Clock

"clock" is a float whose value is controlled by the +K command-line parameter. You can use it to create simple animations with ease (although it won't help you with complex stuff). For example to make a simple animation of a sphere orbiting the origin, you might try this

sphere {
   <5, 0, 0>, 1
   rotate clock*y
}

Then you could render this scene with +K0, +K15, +K30, etc, to get your frames. This is much more convenient than modifying your scene file for each frame. The value of clock is 0 if no +K argument is given to POV-Ray.


Comment

Comments are used to describe what you were thinking in English (or whatever language you speak). Commenting a scene makes it much easier to return in a week and modify it. Nothing's worse then having a scene that you can't do anything with because you can't figure out what you meant.

Comments in POV-Ray follow the C++ syntax. By putting the characters "//" on a line, any characters after it (on that line) will be ignored. This kind of comment ends when the line does. You can also start a comment with "/*". Then, any and all characters will be ignored until POV-Ray sees a "*/" to end the comment. This kind of comment can stretch as many lines as it needs to; it won't end until a "*/" is read. Here are some examples of comments.

/* following these line, there will be
   a sphere declaration
   just
        so
           you
               know */

sphere {
   <1000, 0, 0>, 10
   pigment { color Red }
   rotate 45*y              // rotate sphere into position
}

That code segment demonstrates both kinds of comments. Note that you can include //'s in /**/ comments without a problem. But including other /**/ comments inside a /**/ comment may or may not work. Take for example

/* outer comment
      /* inner comment */
   boogaboogabooga
*/

With this segment, the first */ encountered ends the comment. Thus the "boogaboogabooga" is (unsuccessfully) parsed by POV-Ray, which promptly generates an error. However, in some versions of POV-Ray, you are allowed to nest comments, so the previous example may not apply to you.

Comments are also useful for when you're debugging a scene. If there's some object that's generating an error, but you don't know what it is, you can go through and comment out blocks of code. If the error goes away, you know that the code you just commented out was causing it.


#declare

The declare directive is used to create object definitions without actually creating the objects. It can be used with floats and vectors to declare constants, or to declare pigments, finishes, textures, objects, or anything else in POV-Ray. Note that declare does not create a macro. To use, for example, a declared texture, you need to enclose the name in texture statement. Declares are incredibly useful for creating several duplicates of a very complex object. For example

#declare Complex_Object = union {
   /* pages and pages of object code is omitted */
}

object {
   Complex_Object
}

object {
   Complex_Object
   translate <5, 0, 0>
}

object {
   Complex_Object
   translate <-5, 0, 0>
}

Once an indentifier is declared, that identifier can be used anywhere in the scene after the declaration. You can also use declared things in other #declare statements. Note that declared names, as with everything else in POV-Ray are case sensitive. The POV-Ray authors recommend that your declared names should have some upper case letters in them to distiguish them from built in things, and to keep them from conflicting with reserved words.

One thing to keep in mind about declared objects is that any texture statements inside the #declare will override any applied to the object outside the #declare. Take, for example, the following segment

#declare Ack = 2
#declare Moo = 0.6

#declare Blue = color rgb <0, 0, 1>
#declare Green = color rgb <0, 1, 0>

#declare SomewhatBumpy = normal { bumps Moo }

#declare Spheres = union {
   sphere {
      <-1, 0, 0>, Ack
      pigment { color Green }
   }
   sphere {
      <1, 0, 0>, Ack
   }
}

object {
   Spheres
   pigment { color Blue }
   normal { SomewhatBumpy }
}

Note that #declares can be used to improve readability (as with Green and Blue) and to degrade readability (as with Ack and Moo). In some cases, it really does make more sense to just use the number.

This will produce a smooth green sphere and a bumpy blue one. Note that the normal in the object statement won't apply to the green sphere, because the pigment carries an implied texture. This implied texture includes a normal statement which won't be overridden.

The methods for declaring all the various types of things that you can declare (almost anything, as noted above) are covered in a great deal of depth in the POV-Ray documentation, so they won't be duplicated here.


#default

The #default directive is used to modify the default texture for all the objects in a scene. For example, if you want to remove all the ambient lighting from everything in a scene, you could go to every object and add

finish {
   ambient 0
}

But this gets tedious for large scenes. Instead, you could just put the statement

#default {
   finish {
      ambient 0
   }
}

This tells POV-Ray to automatically include "ambient 0" in every object. You can also specify a default pigment (normally solid, flat black) or a default normal (normally flat). As another example, if you wanted every object in a scene to be heavily dented and red (unless you specified otherwise in the object declaration), you could do

#default {
   pigment { color rgb <1, 0, 0> }
   normal { dents 1.0 }
}

The #default directive is basically just a time saver. It saves you from having to type or block copy the same thing over and over and over and . . . well, you get the idea.


Fog

The fog statement allows you to add fog of any color and density to your scene. POV-Ray models fog by calculating the distance to an intersection, and then mixing in the fog's color based on that distance (higher distance = more fog color). Computing fog is computationally cheap and can add a great deal of realism to a scene. The basic form for declaring fog is

fog {
   color color-spec
   distance dist
}

color-spec is any solid color. Any filter component for the color will be ignored by POV-Ray. dist is a float specifying the distance at which the color will be 63% the fog color. The equation for calculating fog density is as below. depth is the distance to the intersection, and dist is the value specified above.

fog density = 1 - exp(-depth / dist)

The exp function raises e (2.718281828459...) to the power of its argument.

So when depth and dist are the same, you get

1 - exp(-1)
1 - 0.3679
0.6321

which corresponds to 63% fog color. The other 37% of the color comes from the pigment of the object. Note that this function will never actually reach 100% fog color. However, at a depth of 3 * dist the color will be 95% fog. The value of the color being mixed with the fog at this point doesn't really matter. The value you specify for the fog distance should depend on the extent of your scene.

To compare, here are two scenes, the first without fog, the second with some rather surreal bright blue fog thrown in.


#include

The #include directive is used to include other scene files in the current one. The effect is exactly as if you had typed the contents of the file in at that location. The syntax is pretty simple,

#include "filename"

filename is the name of the file you want to include. The quotes are necessary. This is the best way to use the standard POV-Ray libraries. For example, there's an include, colors.inc, which contains a great many color declarations. To get access to them you just need to put

#include "colors.inc"

at the top of your file. Note that when you include a file with declares in it, the names which are declared are only accessible to things below the #include in your scene. The convention is to name files which are intended to be #included with the extension ".inc", but this is not required.

Another thing you can do is easily group objects together. If, for example, you have a file with a large number of objects in it, and you want to group and use these objects as one in another scene, you could do

union {
#include "objects.inc"
}

It is legal for include files to include other files. POV-Ray will generate an error, though, if you go more than ten levels deep with nested includes. This shouldn't be a limitation. If it is, you need to rethink how you're putting your scene together.


#max_intersections

The #max_intersections directive controls memory allocation for an internal data structure called "I-Stacks". These data structures are used to store information about object intersections while rendering a scene. However, if you are rendering a particularly complex scene, these stacks can overflow, resulting in scene errors. If, in the POV-Ray status report (after the render) you see "I-Stack Overflows" listed with the statistics, you need to increase the value of this parameter. The default value is 64. Really, you just need to increase the value upward until all the "I-Stack Overflows" disappear. The POV-Ray authors recommend

#max_intersections 200

if you start to have problems. Of course, you may need to go even higher if this doesn't fix your problem.


#max_trace_level

The #max_trace_level directive controls how patient POV-Ray will be when rendering reflective or transmissive surfaces. The first ray sent out for each pixel is at trace level 0. If that intersects a reflective surface, another ray needs to be traced to determine what's being reflected. This new ray is at trace level 1. If that ray intersects another reflective surface, a third ray (now at trace level 2) needs to traced, and so on. The same holds with transmissive surfaces. Whenever a ray strikes a surface with a nonzero filter value, another ray needs to be traced to determine what color is being transmitted. The trace level goes up from there. The default #max_trace_level is 5. This means that if any ray running at trace level 5 intersects a reflective or transmissive surface, POV-Ray will give up and just return the color black. Thus, if you get reflective or transmissive surfaces which appear black when they shouldn't be, you probably need to up the max trace level. This is done by specifying, for example

#max_trace_level 10

Note that there is no upper limit on the max trace level, but POV-Ray might crash if it runs out of memory while tracing reflective surfaces.


Rotate

Rotate is a transformation which can be used to both change the orientation of a thing in space. This thing can be an object, a light, a camera, or a texture (or any component of a texture). The basic format for a rotation is

rotate <x angle, y angle, z angle>

The argument to rotate is a vector of rotation angles. Each of the components are floats which specify the angle (in degrees) to rotate around the corresponding axis. Any float value is valid for each of these, including zero.

Note that when you rotate an object, you always rotate it around the axis. So anything which is not centered on the axis around which you are rotating will appear to orbit that axis. Note also that the coordinate system in POV-Ray is left-handed. To determine which way is the positive direction around an axis, hold your left hand with the thumb sticking out in the positive direction of that axis. The direction your fingers curl when you close your hand is the direction of positive rotation.

Also, the order of the rotations for a rotate statement is around x-axis, then around y-axis, then around z-axis. This makes a difference. For proof if this, see the three scenes below. The first shows a cone pointing in the +y direction. The second has the cone transformed by rotating first -90 degrees around the x-axis, then 90 degrees around the y-axis. The third has these two transformations reversed.

For more information about general transformations, see the transformations section.


Scale

The scale transformation is used to change the size of objects. You can scale objects uniformly, or nonuniformly if you wish. You can also mirror-reverse objects. As with any other transformation, this can be used with any object, light, camera, or texture. The two general forms for a scale is

scale scl
scale <x-scl, y-scl, z-scl>

The first form is for uniform scaling. It takes a float which specifies the factor by which to scale the object. The object is then scaled by that factor in all dimensions. The second form is for nonuniform scaling of objects. The parameter here is a three-coordinate vector specifying the scale factor in the x, y, and z directions respectively. Values greater than one for any of these values (uniform or nonuniform) will stretch the object, values less than one will squish the object, and negative values will reverse the object. Scaling on object by zero in any dimension is not legal. If you try, POV-Ray wil generate a warning and reset the offending component to 1.

All scaling is with respect to the corresponding axis (nonuniform) or the origin (uniform). Thus the following object delcarations are the same.

sphere {
   <0, 2, 0>, 1
   scale 2
}

sphere {
   <0, 4, 0>, 2
}

When you scale the first sphere, you not only double its radius, you also double the center's distance from the origin. This can generate problems when working with objects that are not at origin. If you have an object somewhere and you scale it and it disappears, it's most likely because it wasn't at the origin when it was scaled. That's just something to keep in mind.

Another thing to keep in mind is the use of the x, y, and z vectors in a scale statement. This will often generate scale-by-zero warnings. Take, for example, the following object

sphere {
   <0, 0, 0>, 4
   scale 5*x
}

This will generate a warning, because the value of "x" is <1, 0, 0>. Hence, the value of 5*x is <5, 0, 0>. The zeros in that will annoy POV-Ray.

For more information about transformations in general, see the transformations section. Conveniently, this is the next section.


Transformations

The term "transformation" refers to rotatations, translations, and scales. Transformations can be applied to just about anything, including objects, lights, cameras, pigments, and normals. It doesn't make sense to transform finishes as the finish of an object doesn't depend on its absolute location in space (it does, however, depend on its location relative to other objects).

Any number of transformations may be applied to an object (from here on I'll use the term "object" to refer to any of those things I listed above). The transformations will be applied to the object in the order they are listed. Note that any position and orientation of an object can be achieved with a scale, a rotation, and a translation (in that order). However, it's often easier to use somewhat more complex transformations to acheive certain effects. For example, the following two scenes look the same. However, the first was generated by specifying object locations explicitly, and the second by rotating them into those positions.

Both show cylinders at the corners of an equilateral triangle. However, the first one required some thought to position the cylinders, while the second one didn't (at least not as much). Also, in the second scene it's more obvious from the source exactly what's going on in the scene with those cylinders.

The order of transformations does matter, particularly with translations. As an example, here's a simple scene. The first shows the object untransformed, the second shows it after a scale and a rotation, and the third after a rotation and a scale.

Note the rather striking differences in the second two scenes.

Objects, Textures, and Transformations

When transforming an textured object, the behavior of the texture is fairly intuitive. Just remember that an object is modifed in the order that things appear in its declaration. The following two objects will not look the same. White_Marble is declared in "textures.inc".

sphere {
   <0, 4, 0>, 1
   rotate 90*z
   pigment { White_Marble }
}

sphere {
   <0, 4, 0> 1
   pigment { White_Marble }
   rotate 90*z
}

This is because, in the first sphere, the object is rotated, and then the pigment is applied to the object's surface. In the second, first the object is covered with the pigment, and then the object (and pigment) are rotated. To make the first sphere look like the second, you could add a "rotate 90*z" transformation to the pigment of the first sphere. This would transform the sphere, then transform the pigment the same way, and then apply the pigment to the sphere's surface. The same rules hold for all the other transformations.

For a perhaps more basic description of transformations, see the Tutorial.


Translate

Translate is a transformation which modifies the position of an object. You can use it to put any object anywhere in space. The basic form for translate is

translate <x-dist, y-dist, z-dist>

The argument is a three component vector specifying the distance to move the object in the x direction, y direction, and z direction, respectively. The components in the vectors are floats, and any value (positive, negative, or zero) is legal. The order in which the translations from one vector are applied doesn't matter, so you don't have to worry about explicitly specifying it.


Version and #version

The #version directive is used for backwards compatibility with POV-Ray 1.0. Currently, the valid arguments for this directive are "1.0" and "2.0" (without the quotes). The default value is 2.0. This default can be changed with the +MV command-line parameter. Most of time you won't be using this directive, however, it can come in handy if you get some old POV-Ray code from somewhere. Along with the #version directive is the version variable. The value of this variable is either "1.0" or "2.0" and it corresponds to the version expected at this point in the file. The #version directive must appear outside of any and all other things (like object declarations, for example).


X, Y, and Z

x, y, and z are built in vectors for convenience. Their values are <1, 0, 0>, <0, 1, 0>, and <0, 0, 1>, respectively. They're useful for specifying transformations, for example, the following pairs of statements are equivalent.

translate <5, 0, 0>
translate 5*x

rotate <0, 80, 0>
rotate 80*y

translate <4, 6, 0>
translate 4*x + 6*y


Reference Index Top of Document Main Page

The Online POV-Ray Tutorial © 1996 The Online POV-Ray Tutorial ThinkQuest Team