The Online POV-Ray Tutorial

Creating Simple Scenes

(Show Jump Points) (Hide Jump Points)

The POV-Ray language is fairly easy to use, once you understand it. In fact, if you have any experience with programming, you will find POV-Ray very easy -- there are no variables, conditionals, loops, or anything else that can make programming tricky. Basically, a POV-Ray source file (the file you make and give to POV-Ray) is just a list of objects and their descriptions. Of course, describing the scene you have in your mind to POV-Ray is the tricky part, because you have to speak POV-Ray's language.

Quick index:

  1. Creating simple objects
  2. The Camera
  3. Let there be light! (Light sources)
  4. The first example scene
  5. Transformations
  6. Texture
  7. Pigment
  8. Finish
  9. Normal
  10. Including Textures

Creating simple objects

The building blocks of all POV-Ray objects and scenes are called primitives. Primitives are objects that POV-Ray already knows about, and all you have to do is describe a few attributes. POV-Ray primitives are usually simple geometric shapes such as spheres, cubes, and cones.

Describing primitives, in general, take this form in POV-Ray:

Object_Name {
  Object_Parameters
  Some_Simple_Attribute
  Some_Other_Simple_Attribute
  Some_Complex_Attribute {
    Some_Attribute
    Some_Other_Attribute
  }
}
This isn't very enlightening. Let's take a look at a short example:

sphere {
  <0, 0, 0>, 5
  pigment {
    color rgb <1, 0, 0>
  }
}
Deciphering what this does isn't too tricky. The code defines a sphere with its center at the origin (that's <0,0,0>, remember?) and with a radius of 5 (in other words, the distance from the center of the sphere to any point on the edge of the sphere is exactly 5 units). The phrase pigment { color rgb <1,0,0> } simply means that the sphere's pigment (or color) attribute is described by the rgb vector <1,0,0>, which is the color red. You could have just as well used color Red, if you had #included the correct file. The pigment attribute, by the way, is a complex attribute, of which color is just one of the many attributes that can go inside it.

There are two types of primitives in POV-Ray: finite primitives and infinite primitives. Finite primitives have well-defined limits. Examples of finite primitives include spheres, cones, torii, and blobs. Infinite primitives have components that can potentially stretch to infinity -- for example, a plane is both infinitely thin and infinitely wide. Examples of infinite objects include planes, quadrics and cubics. At any rate, describing primitives in POV-Ray is only a matter of knowing the syntax for the particular primitive you want to describe. You can find a complete syntax reference in the finite object and infinite object language references.

By now, you're probably itching to make your first scene. Before you can do that, however, you need to learn about two things: the camera and light sources.


The Camera

Before POV-Ray can generate the scene, it needs to know from where you are looking. If you imagine your computer screen as the camera taking a snapshot of the scene you're describing, you'll see POV-Ray needs to know a) where the camera is in the scene, and b) which direction it's pointing. Such data is given to POV-Ray through the camera object. As you might imagine, the camera object is a rather important one: in fact, POV-Ray requires that there be one and only one in each scene.

There are many attributes that the camera object can have; of these, we will only concentrate on the two most useful: the location and the look_at attributes. A complete reference of all the camera attributes can be found in the Camera Reference.

A simple camera in POV-Ray looks like this:

camera {
  location <2,5,-10>
  look_at <0,0,0>
}
This example defines a camera located at <2,5,-10> and pointing at the origin. This means that anything with a z coordinate less than -10 will definately be invisible -- it will be behind the camera!

You can put the camera anywhere you want in the scene, including inside of objects (although you may not see very much), with one exception: you may not place the camera directly over the origin and have it looking straight down. For complex mathematical reasons, this will cause POV-Ray to generate an error. If you need that type of setup, position the camera a little to the left or the right -- your problem will be solved, and your scene will look (almost) exactly the same.

Anyways, now that we have a way of receiving light, we need to have a way of providing light.


Let there be light! (Light sources)

If you gave POV-Ray a file containing the camera definition above and the sphere definition before that, the output image would be a lovely blank picture. This would happen because you'd have no light in your scene. To add light (thereby enabling you to actually see something), you need to add a light source.

There are a few different types of light sources in POV-Ray. We will concentrate here on the most simple (and useful): the point light source. A point light source can be thought of as an infinitely small object that emits light. Because they are infinitely small, point light sources cannot be directly seen (so you don't have to worry about them appearing in your scene). However, their effects can certainly be seen: your scene lights up!

Point light sources as known as non-attenuating light sources: the emitted light does not get weaker with distance. This means that you can illuminate your entire scene with one point light source placed far away from the scene. You can have as many light sources as you want, but they are computationally expensive -- the more you have, the longer POV-Ray will take to trace your scene.

An example of a simple point light source definition in POV-Ray looks like this:


light_source {
  <0,10,-10>
  color rgb <1,1,1>
}
The first vector is a position vector specifying the location of the light source. The second vector specifies the color (and brightness) of the light. It is generally a good idea to use white or gray light, as using colored light can have side effects that are not immediately obvious (for example, green objects will not show up when exposed to pure red light). Complete information for light sources can be found in the lights section of the Language Reference.

Anyways, now that we can add light, we're ready to construct our first full scene.


The first example scene

Putting together all we have learned to far, we get a complete POV-Ray source code file that looks like this:


// This is a simple red sphere

// first, the camera position
camera {
  location <2,5,-10>
  look_at <0,0,0>
}

// now, some light
light_source {
  <0,-10,0>
  color rgb <1,1,1>
}

// the sphere
sphere {
  <0,0,0>, 5
  pigment { color rgb <1,0,0> }
}
After running POV-Ray, the output image looks like this:

Finally! Your first image! Of course, this one is a little boring -- but don't worry, we'll get to some fun stuff soon. For now, experiment! It's the best way to learn. Try replacing the sphere with other objects and seeing what happens. The objects that you should easily be able to use are boxes, cones, cylinders, spheres, torii and planes.


Transformations

So now we can create some simple objecs. But wait! Some of these objects can only be created around the origin (like the torus). What if we want to put them somewhere else? What if we want to move them around? POV-Ray provides answers to all these questions in the form of transformations. Transformations, in ray-tracing terms, are attributes that change the position, size or orientation of objects (and of the various attributes of the objects). The most common types of transformations, and the ones that POV-Ray supports, are translations, rotations and scalings.

A translation is a transformation that moves an object relative to its current position. It is specified in POV-Ray by the phrase translate <x,y,z>. Translations are easy to visualize. Consider a cube sitting on the origin, like this:

Our camera is positioned so that the x axis increases to the right, the y axis increases upwards and the z axis increases towards us. A translation of <-1,4,2> results in the cube being moved left one unit, up four, and back two, like this:

A rotation is a transformation that changes the orientation of an object (the way that it's facing). Rotations are the most complex of the transformations. They are specified to POV-Ray by the string rotation <x,y,z>, where x, y, and z are the number of degrees (not radians) around the respective axis. Consider the original cube up above. A rotation of <0,0,45> rotates the cube 45 degrees around the z axis, leaving us with a cube looking like this:

A quick way to remember which way the objects are going to rotate is by usings the so-called "left hand rule." Hold out your left hand, fingers clenched and thumb out. Point your thumb in the positive direction of the axis you are rotating about (if you're rotating about more than one axis at a time, this won't help you -- unless you have more than one thumb!) The direction that your fingers curl is the direction an object will rotate when the number of degrees is positive. (Negative degrees rotate the opposite direction).

Another important thing to remember about rotations is that they are always with respect to the coordinate axes -- in other words, unless your object is located at the origin, it will orbit around the axis (or axes) you are rotating it about. For example, this is what would happen if we translated the cube first, and then rotated it:

To get around this, make sure you rotate your object when its centered at the origin, and then translate it. Your picture will end up like this:

Transformations are one of the few aspects of POV-Ray in which the order matters, simply because transformations are always made with respect to the object's current orientation.

The last translation you need to know about is scaling. Simply enough, scaling changes the size of the object with respect to its current size. Scaling is specified in POV-Ray via the string scale <x,y,z>. The elements of the vector specify the how much to scale the shape with respect to the coordinate axis: a scale of 1.0 leaves the object the same, and a scale of 0.0 or less is invalid. Going back to our original cube, if we scaled the object with the string scale <1,4,1>, we would get a result like this:

Because of vector promotion (if you don't remember what that is, you can re-read about it), scaling can also take a single number rather than a vector. This causes the object to be scaled in every direction by that number. For example, the phrase scale 2 is the same as the phrase scale <2,2,2>.

Transformations are placed like any other attribute. For example:

torus {
  3, 11
  pigment { color Yellow }
  scale <1.5,1,1>
  rotate <-45,0,0>
  translate <0,2,0>
}
This code makes a yellow torus, slightly widened around the x axis, rotated -45 degrees around the x axis and with its center at <0,2,0>, like this:

Note that torus objects are created around the origin, so you are in fact forced to use transformations to get them where you want... luckily for you, you now know how. And to quote G. I. Joe, knowing is half the battle.


Texture

We admit it -- we lied to you. The pigment attribute is actually a part of a bigger attribute called the texture attribute. Every time you used pigment, it should have really looked like this:
texture {
  pigment { color Red }
}
The reason that POV-Ray is a little loose about the pigment attribute and lets you use it outside of texture is because pigment is so frequently used by itself that it becomes a pain to type out the whole texture statement. In fact, most parts of the texture { } block you can do the same thing with. Either way, they have the same effect.

The texture attribute contains attributes describing the outward appearance of the object: pigment, finish and normal. The pigment attribute, as you know, describes the color of the object (although it's a lot more complicated than what we've shown you so far). The finish attribute describes how the object "interacts with light" -- highlighting, metallic luster, shinyness, reflectivity, etc. The normal attribute describes some three-dimensional features of objects, such as bumps, waves, and ripples. We'll cover these one by one.


Pigment

You've seen the use of the color attribute within the pigment attribute (for example, pigment { color Blue }). A more complete description that what we've given you so far can be found in the Color section of the Language Reference. A more flexibe attribute, however, is color_map. color_maps are used to do a wide variety of things. Basically, a color_map defines bands of color on a "map" ranging from 0.0 to 1.0 Let's look at a simple example:
color_map {
  [0.0  color Red]
  [0.25 color Blue]
  [0.9  color Green]
}
This defines three bands of color: red from 0.0 to 0.25, blue from 0.25 to 0.9, and green from 0.9 to 1.0. The other commonly used format looks like this:
color_map {
  [0.0 0.25 color Red]
  [0.25 0.9 color Blue]
  [0.9 1.0  color Green]
}
They both do the same thing; the second one just contains information about where you want the bands to stop as well as start.

The next step is tell POV-Ray what to do with this. This is done by using of the many pigment types. A simple pigment type is called gradient. Gradient creates bands of color based on the color map. Using the source code from the first scene we created, and replacing the color Red with our color map and pigment type, we get this:

sphere {
  <0,0,0>, 5
  pigment {
    gradient <0, 1, 0>
    color_map {
      [0.0 color Red]
      [0.25 color Blue]
      [1.0 color Green]
    }
  scale 3
  }
}
This source code requires a bit of explaining. The vector following the gradient keyword is the normal vector to the orientation of the bands of color (you remember normal vectors, don't you? Or did you think we were wasting our time telling you stuff you didn't need to know? Admit it! You skipped over that section! Well, we're forgiving; you can go back and read about it again). The scale statement applies to the pigment, not to the object (look carefully at where it's placed -- inside the pigment { } block).

Our sphere now looks like this:

A careful examination of this image yields some interesting facts. Starting from the top down, you can see a slight bit of green (the rest of it was cut off), which fades into the the large blue band, which in turn fades into the small red band. The red band is abruptly cut off and the cycle repeats itself again. However, the next time, the pattern has reversed! The red band is on the top. This is because gradient patterns reverse themselves at the origin. To get around this, you can translate the texture away from the origin (you can apply all transformations to textures, remember?). More information on gradients can be found in the gradient section of the Language Reference.

Ok, now let's try something else. Add the phrase turbulence 0.5 after the gradient statement. The resulting picture looks like this:

Whoah! The turbulence keyword, as you may have guessed, "mixes stuff up." With this color map, we get a freakish plasma-like sphere. Values for turbulence range from 0.0 to 1.0. A complete description can be found in the turbulence section of the Language Reference.

There are many other pigment types than gradient. For example, there is a pigment type called marble. By itself, rather boring and un-marble-like. However, with a high turbulence, it can create some very realistic marble pigments. Here's some sample source code:

sphere {
  <0,0,0>,5
  pigment {
    marble
    turbulence 1  // full turbulence
    color_map {
      [0.0 color Gray90] // 90% gray
      [0.8 color Gray60] // 60% gray
      [1.0 color Gray20] // 20% gray
    }
  }
}
This high-turbulence marble pigment generates some very nice-looking marble:

Not too shabby, huh? Other pigment types include wood, agate, bozo, and a host of others that can be found in the pigment section of the Language Reference. And although technically not pigment types per se, you may want to check out the checker and hexagon pigment patterns, as well as the image map pattern (which lets you map an external image to an object), all found in the same section as above. And remember, the best way to learn is to experiment!


Finish

Finish describes how the objects interact with light: how much they reflect, how they shine, how metallic they are, etc. All finish attributes are enclosed in a finish { } block.

Perhaps the most used of the finish attributes is the phong attribute. A phong is a highlight, or glare. It is specified, strangely enough, by the phong attribute, followed by a number between 0.0 and 1.0 that specifies how bright the phong is. There is also a phong_size that controlls how "tight" the phong is -- in other words, the higher this number, the smaller in size the phong is (this is a little misleading, yes). Here we have a green sphere with a phong highlight of 1.0:

sphere {
  <0,0,0>, 5
  pigment { color rgb <1,1,0> }
  finish { phong 0.8 }
}
When lit by two light sources, the sphere looks like this:

As you can see, the phong adds a nice bit of realistic "shine" whenever a light source directly hits part of the object. A more complete description of phong can be found in the phong section of the Language Reference.

Another finish attribute that can produce stunning effects is the reflection keyword. This causes objects to reflect their surroundings to a certain degree. Reflection takes one number, ranging from 0.0 to 1.0, that specifies how reflective the object is. Let's take a look at a more complex scene with a reflective object.

#include "colors.inc"

camera {
  location <-2, 3, -10>
  look_at <0, 5, 0>
}

plane { // the floor
  y, 0  // along the x-z plane (y is the normal vector)
  pigment { checker color Black color White } // checkered pattern
}

sphere {
  <0, 5, 0>, 2
  pigment { color White }
  finish {
    reflection 0.9
    phong 1
  }
}

light_source { <10, 10, -10> color White }

light_source { <-10, 5, -15> color White }
The image this produces is:

As you can see, this generates a yellowish mirrored sphere floating above an infinite checkerboard -- a variant of one of the standard ray-tracing scenes. A more in-depth description of reflectivity can be found in the reflection section of the Reference manual.

The final attribute of the finish keyword we will describe here is the refraction keyword. Refraction is what happens when light rays passing through a translucent object get bent, causing a distortion of everything seen through the object. For example, if you look through a crystal ball, you will see a distorted view of whatever is behind it.

The refraction keyword takes one value. This value should either be 0.0 or 1.0, for refraction off and on, respectively. Although you can specify values in between, it is not recommended as it does not correspond to any known physical property. How noticeably it refracts is controlled by the ior keyword (for index of refraction), which takes a number greater than 0. The default ior of "empty space" is defined as 1.0. So, if we wanted to create the crystal ball described above, we would use something like this:

sphere {
  <0,5,0>,2
  pigment { color rgbf <1,1,1,.8> }
  finish {
    reflection 0.1
    refraction 1.0
    ior 1.5
    phong 1.0
  }
}
Remember your RGBF vectors? A filter value of 1.0 would mean this was an invisible sphere, certainly not what we want. Our filter value of 0.8 gives the sphere enough definition to be visible. The image generated looks like this:

Now we start seeing some of the true power of ray-tracing. The warped look of the checkboard pattern is due to the refraction, the bright hightlighting is due to a phong, and a bit of reflection makes this all the more realistic. Tinting the glass would be easy: just change the color of the sphere from <1,1,1> (or white) to whatever color you want it tinted. Modify the filter value to make the ball more and less translucent. It's fun!

There are many other finish attributes that you can play with, including metallic, ambient, and crand. We've touched on a few; for a complete reference, read the finish section of the Language Reference. To get a good feel for most of the finish attributes, you can experiment with the Finish Tool.


Normal

The normal attribute creates some simple 3D features on your objects: bumps, ripples, waves, and the like. It does not actually change the object; instead, it changes slightly the way light bounces off the object and essentailly fools the eye into believing the object is a little different than it really is. As such, the effects are not 100% true to real life, but they are much, much faster than actually describing the changes individually would be.

Let's try a bumps example. Bumps are created with (oddly enough) the bumps keyword, followed by a single number, generally between 0.0 and 1.0, that specifies the relative size of the bumps. Here's some source code:

cone {
  <0,-3,0>,1
  <0,3,0>,0.1
  texture {
    normal {
      bumps 1/2
      scale 1/6
    }
    pigment { color rgb <.5,.7,.2> }
  }
}
This creates a green cone with a slightly bumpy appearance, like this:

Not to difficult, eh? Imagine how difficult it would be to model all those bumps yourself. Now, here's a fun one to try -- ripples:

plane {
  y, -2
  texture {
    pigment { color rgb <.1,.9,.9> }
    normal {
      ripples 0.5
    }
  }
}
The number following the ripples keyword specifies, again, the relative size of the ripples. The image this produces is:

Pretty nifty! The ripples keyword and its close relative, the waves keyword, can take a few modifiers that give a little more control than we've shown you. A complete reference can be found in the ripples section of the Language Reference. More normal attributes, such a dents and wrinkles, can be found in the normal section of the same document. You can also experiment with the Normal Tool to get a feeling for the various attributes.


Including Textures

Much like you learned how to include colors beforehand, you can also include textures. POV-Ray comes with a file full of some very good textures, called textures.inc. Including this is the same as before:
#include "colors.inc"
#include "textures.inc"
Note that you must include colors.inc before you include textures.inc, because textures.inc uses colors from colors.inc.

Using an included texture is easy. To make a sphere that uses the Jade textures, for example, you would say:

sphere {
  <-2, 4, 6>, 5.6
  texture { Jade }
}
Look through the file textures.inc for a list of the textures included. You can also look through colors.inc for a list of the colors in there.

Well, if you've managed this far, you're in good shape. Keep it up! The next section gets in to the really fun stuff.


Top of Document Main Page Step 2: POV-Ray Basics Step 4: Advanced POV-Ray Features

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