If you've made it this far, you're in good shape! This section covers the features of POV-Ray that are most most complex, but also the most powerful. Once you complete this section, you'll be ready a certified ray-tracing master.
Quick Index:
#declare my_sphere =
sphere {
<0, 0, 0>, 5
finish {
pigment rgbf <.5, .2, .4, .667>
}
}
What this does, essentially, is declare a new type of object called "my_sphere"
which you can now use later on in your source code, like this:
object {
my_sphere
translate <-2, 0, 0>
}
The object statement tells POV-Ray to create an object of type "my_sphere." Theoretically, you can put object statements
around every object you use (including primitives, like spheres) but
POV-Ray only requires it for #declared objects.Note that any attributes you place inside the object statement override those in the #declare statement -- in this example, our sphere is moved from its original location at <0,0,0> to <-2,0,0>. This hold true for pigments, finishes, etc.
VRML programmers should take note that this #declare differs somewhat from VRML's DFN node. #declare does not create an instance of the object (which DFN does), only the definition. In other words, the above #declare statement would not add any objects to your scene on its own. You need to instantiate the objects (with the object keyword) to do that.
Now, why would you want to use #declare? Say, for example, you're making a Greek temple. You
would want
many pillars in your object, so you would create a pillar object with #declare, like this:
Then, you would create however many of these you needed, translating to your heart's content. Say,
however, that you decide the columns in your temple should be made out of red marble, not
white. All you have to do is change the one #declare statement, and all the pillars
change! If you had created those pillars without #declare, you'd have to change each
one by hande -- a major hassle, especially if you had 40 pillars in your temple.
#declare pillar =
cylinder {
<0, -5, 0>, <0, 5, 0>
texture { White_Marble }
}
So you can see one immediate benefit to #declare -- updating your scene becomes a lot easier.
But wait, there's more! You can also use #declare to create your own colors and textures. In fact, the colors.inc and
textures.inc files are basically long lists of
#declared colors and textures, respectively.
The syntax is intuitive:
As you can most likely guess, these define a new color, called "blue_green_filter" and a new texture,
called "red_glass". You would use these like this:
#declare blue_green_filter = rgbf <0, .5, .5, .5>
#declare red_glass =
texture {
finish {
refraction 1.0
reflection 0.1
ior 1.5
}
pigment {
color rgbf <1, .7, .7, .7>
}
}
Not too difficult! You can use #declare to create custom finish, normal,
and pigment statements... you can even use it with vectors and single numbers, like this:
sphere {
<0, 0, 0>, 1
pigment { blue_green_filter }
}
cone {
<-2, -4, 16>, 5
<0, -3, 1>, 1
texture { red_glass }
}
This will save you a bit of typing if you reference PI frequently in your scene file! (Please remember that you don't need to put an object statement
around anything you #declare other than objects).
#declare PI = 3.1415926545338327950288
C and C++ programmers should not be mislead by #delare's superficial similarity to the C/C++ pre-processor macro #define. Their behaviour is quite different. #define actually changes the source code before it gets compiled (why is why it's called a pre-processor macro). POV-Ray does not have a pre-processor, and so #declare, although misleadingly labeled, will not do source-code substitution.
At any rate, you can get the complete syntax for object and #declare in the Language Reference. They are both powerful tools, and if you create anything other than very simple scenes, you will find them invaluable.
There are five operators in CSG: union, intersection,
merge, difference, and inverse. The
syntax of all the operators (except inverse) is very simple: it's the operator, followed by a
list of two or more objects enclosed by braces, like this:
CSG_operator {
object_1
object_2
etc.
}
We'll go over these operators one by one, because they're all important. A complete reference can be found in the CSG Section of the Language Reference.
union {
sphere { <0, 1, 2>, 3 }
box { <-77, 6, 5>, <2, 3, 55> }
sphere { <-2, -3, -4>, 5 }
}
union {
sphere { <0, 1, 2>, 3 }
box { <-77, 6, 5>, <2, 3, 55> }
sphere { <-2, -3, -4>, 5 }
pigment { color Blue } // applies to the entire union
}
The second, and perhaps even more useful reason for using unions, is when you combine CSG and the
#declare keyword, like this:
#define two_spheres =
union {
sphere { <0, 0, 0>, 3 }
sphere { <-1, -5, -1>, 3 }
}
object {
two_spheres
pigment { color Pink }
rotate <0, 180, 0>
}
#declare wheels_n_axle =
union {
object { // left wheel
wheel // assuming we have already created a wheel object
translate <-3, 0, 0>
}
object { // axle
axle // assuming we have already created an axle object
}
object { // right wheel
wheel // assuming we have already created a wheel object
translate <3, 0, 0>
}
}
#declare car =
union {
object { // front wheels and axle
wheel_n_axle
translate <0, 0, 5>
}
object { // rear wheels and axle
wheels_n_axle
translate <0, 0, -5>
}
// other car parts go here
}
A complete description of the union operator can be found in the
CSG Section of the Language Reference.
#declare wall =
difference {
box { <0, 0, 0>, <10, 10, 1> } // 10x10x1 wall
box { <2, 0, -1>, <6, 8, 2> } // minus a doorway
texture { Wall_Texture } // assuming we have already created a Wall_Texture
}

When we add the difference statement, we get:

Note that we made the doorway cube thicker than the wall. Why? This is because, occasionally, POV-Ray will get confused when you have two objects that overlay exactly the same space. So, we made the doorway cube a little thicker, avoiding a potentially weird image, and at no loss to anything else.
One important thing to remember about differences is that all objects are subtracted from the first one. If, for example, we wanted to add a few window holes to the wall above, we could just add a few more cubes at the very end, and voila! Once again, any attributes placed at the end of the difference statement will apply to the entire object.
A complete reference for the difference keyword is located in the
CSG Section of the Language Reference.
#include "colors.inc"
camera {
location <0, 0, -5>
look_at <0, 0, 0>
}
light_source { <10, 10, -10> color White }
intersection {
sphere { <0, -1, 0>, 2 }
sphere { <0, 1, 0>, 2 }
pigment { color Yellow }
}
This code takes two spheres that overlap, like this:

Then, it uses the intersection operator to remove everything that isn't overlapping, leaving an a remarkably sweet-looking goody, like this:

Although intersections are a little more difficult to imagine than some of the other CSG operators, they can be a
very powerful tool. You can find a complete reference in the
intersection section of the
Language Reference.
A complete reference for the merge operator can be found in the
CSG Section of the Language Reference.
intersection {
box { <0,0,0>,<1,1,1> }
sphere {
<1,1,1>, 1
inverse
}
}
is the same as this:
difference {
box { <0,0,0>,<1,1,1> }
sphere {
<1,1,1>, 1
}
}
In fact, POV-Ray calculates differences using this same method. A complete reference to the
inverse keyword can be found in the CSG Section of
the Language Reference.The first is to specify your object in mathematical terms. Obviously, this will only work if
The second option you have is to use a modelling program. What a modelling program can do is generate extremely complex objects in POV-Ray by specifying them as a whole bunch of really simple objects, normally blobs, triangles, smooth triangles. or bicubic patches. These objects, much like the the mathematical ones above, are not generally meant for human consumption -- in other words, don't bother trying to create objects with these by hand, because unless you really know what you're doing, you'll probably just waste a lot of time.
Instead, find a good modelling program (there are many free and shareware ones out there; try the Resource Library), create the complex object in there (usually the modelling programs will have a very nice, graphical interface) and run POV-Ray on the file it creates. You will save a lot of time and effort.
The Online POV-Ray Tutorial © 1996 The Online POV-Ray Tutorial ThinkQuest Team