5.2 OBJECTS
-------------
Objects are the building blocks of your scene. There are 20 different
types of objects supported by POV-Ray. Seven of them are finite solid
primitives, 4 are finite patch primitives, 5 are infinite solid polynomial
primitives, 3 are types of Constructive Solid Geometry types and one is a
specialized object that is a light source.
The basic syntax of an object is a keyword describing its type, some
floats, vectors or other parameters which further define its location
and/or shape and some optional object modifiers such as texture, pigment,
normal, finish, bounding, clipping or transformations.
The texture describes what the object looks like, ie. its material.
Textures are combinations of pigments, normals and finishes. Pigment is
the color or pattern of colors inherent in the material. Normal is a
method of simulating various patterns of bumps, dents, ripples or waves by
modifying the surface normal vector. Finish describes the reflective and
refractive properties of a material.
Bounding shapes are finite, invisible shapes which wrap around complex,
slow rendering shapes in order to speed up rendering time. Clipping shapes
are used to cut away parts of shapes to expose a hollow interior.
Transformations tell the ray tracer how to move, size or rotate the shape
and/or the texture in the scene.
5.2.1 SOLID FINITE PRIMITIVES
There are 7 different solid finite primitive shapes: blob, box, cone,
cylinder, height_field, sphere, and torus. These have a well-defined
"inside" and can be used in Constructive Solid Geometry. Because these
types are finite, POV-Ray can use automatic bounding on them to speed up
rendering time.
5.2.1.1 Spheres
Since spheres are so common in ray traced graphics, POV-Ray has a highly
optimized sphere primitive which renders much more quickly than the
corresponding polynomial quadric shape. The syntax is:
sphere { <CENTER>, RADIUS }
Where <CENTER> is a vector specifying the x,y,z coordinates of the center
of the sphere and RADIUS is a float value specifying the radius. You can
also add translations, rotations, and scaling to the sphere. For example,
the following two objects are identical:
sphere { <0, 25, 0>, 10
pigment {Blue}
}
sphere { <0, 0, 0>, 1.0
pigment {Blue}
scale 10
translate y*25
}
Note that Spheres may be scaled unevenly giving an ellipsoid shape.
Because spheres are highly optimized they make good bounding shapes.
Because they are finite they respond to automatic bounding. As with all
shapes, they can be translated, rotated and scaled.
5.2.1.2 Boxes
A simple box can be defined by listing two corners of the box like this:
box { <CORNER1>, <CORNER2> }
Where <CORNER1> and <CORNER2> are vectors defining the x,y,z coordinates of
opposite corners of the box. For example:
box { <0, 0, 0>, <1, 1, 1> }
Note that all boxes are defined with their faces parallel to the coordinate
axes. They may later be rotated to any orientation using a rotate
parameter.
Each element of CORNER1 should always be less than the corresponding
element in CORNER2. If any elements of CORNER1 are larger than CORNER2, the
box will not appear in the scene.
Boxes are calculated efficiently and make good bounding shapes. Because
they are finite they respond to automatic bounding. As with all
shapes, they can be translated, rotated and scaled.
5.2.1.3 Cylinders
A finite length cylinder with parallel end caps may be defined by.
cylinder { <END1>, <END2>, RADIUS }
Where <END1> and <END2> are vectors defining the x,y,z coordinates of the
center of each end of the cylinder and RADIUS is a float value for the
radius. For example:
cylinder { <0,0,0>, <3,0,0>, 2}
is a cylinder 3 units long lying along the x axis from the origin to x=3
with a radius of 2.
Normally the ends of a cylinder are closed by flat planes which are
parallel to each other and perpendicular to the length of the cylinder.
Adding the optional keyword "open" after the radius will remove the end
caps and results in a hollow tube.
Because they are finite they respond to automatic bounding. As with all
shapes, they can be translated, rotated and scaled.
5.2.1.4 Cones
A finite length cone or a frustum (a cone with the point cut off) may be
defined by.
cone { <END1>, RADIUS1, <END2>, RADIUS2 }
Where <END1> and <END2> are vectors defining the x,y,z coordinates of the
center of each end of the cone and RADIUS1 and RADIUS2 are float values for
the radius of those ends. For example:
cone { <0,0,0>,2 <0,3,0>, 0}
is a cone 3 units tall pointing up the y axis from the origin to y=3. The
base has a radius of 2. The other end has a radius of 0 which means it
comes to a sharp point. If neither radius is zero then the results look
like a tapered cylinder or a cone with the point cut off.
Like a cylinder, normally the ends of a cone are closed by flat planes
which are parallel to each other and perpendicular to the length of the
cone. Adding the optional keyword "open" after RADIUS2 will remove the end
caps and results in a tapered hollow tube like a megaphone or funnel.
Because they are finite they respond to automatic bounding. As with all
shapes, they can be translated, rotated and scaled.
5.2.1.5 Torus
A torus is a 4th order quartic polynomial shape that looks like a donut or
inner tube. Because this shape is so useful and quartics are difficult to
define, POV-Ray lets you take a short-cut and define a torus by:
torus { MAJOR, MINOR }
where MAJOR is a float value giving the major radius and MINOR is a float
specifying the minor radius. The major radius extends from the center of
the hole to the mid-line of the rim while the minor radius is the radius of
the cross-section of the rim. The torus is centered at the origin and lies
in the X-Z plane with the Y-axis sticking through the hole.
----------- - - - - - - - ---------- +Y
/ \ / \ |
/ \ / \ |
| | | |<-B-->| -X---|---+X
\ / \ / |
\__________/_ _ _ _ _ _ _ \__________/ |
|<-----A----->| -Y
A = Major Radius
B = Minor Radius
Internally the torus is computed the same as any other quartic or 4th order
polynomial however a torus defined this way will respond to automatic
bounding while a quartic must be manually bound if at all. As with all
shapes, a torus can be translated, rotated and scaled. Calculations for
all higher order polynomials must be very accurate. If this shape renders
improperly you may add the keyword "sturm" after the MINOR value to use
POV-Ray's slower-yet-more-accurate Sturmian root solver.
5.2.1.6 Blob
Blobs are an interesting shape type. Their components are "flexible"
spheres that attract or repel each other creating a "blobby" organic
looking shape. The spheres' surfaces actually stretch out smoothly and
connect, as if coated in silly putty (honey? glop?) and pulled apart.
Picture each blob component as a point floating in space. Each point has a
field around it that starts very strong at the center point and drops off
to zero at some radius. POV-Ray adds together the field strength of each
component and looks for the places that the strength of the field is
exactly the same as the "threshold" value that was specified. Points with
a total field strength greater than the threshold are considered inside the
blob. Those less than the threshold are outside. Points equal to the
threshold are on the surface of the blob.
A blob is defined as follows:
blob {
threshold THRESHOLD_VALUE
component STRENGTH, RADIUS, <CENTER>
component STRENGTH, RADIUS, <CENTER> // Repeat for any number
component STRENGTH, RADIUS, <CENTER> // of components
}
The keyword "threshold" is followed by a float THRESHOLD_VALUE. Each
component begins with the keyword "component". STRENGTH is a float value
specifying the field strength at its center. The strength may be positive
or negative. A positive value will make that component attract other
components. Negative strength will make that component repel other
components. Components in different, separate blob shapes do not affect
each other. The strength tapers off to zero at the value specified by the
float RADIUS. The vector <CENTER> specifies the x,y,z coordinates of the
component. For example:
blob {
threshold 0.6
component 1.0, 1.0, <.75, 0, 0>
component 1.0, 1.0, <-.375, .64952, 0>
component 1.0, 1.0, <-.375, -.64952, 0>
scale 2
}
If you have a single blob component then the surface you see will look just
like a sphere, with the radius of the surface being somewhere inside the
"radius" value you specified for the component. The exact radius of this
sphere-like surface can be determined from the blob equation listed below
(you will probably never need to know this, blobs are more for visual
appeal than for exact modeling).
If you have a number of blob components, then their fields add together at
every point in space - this means that if the blob components are close
together the resulting surface will smoothly flow around the components.
The various numbers that you specify in the blob declaration interact in
several ways. The meaning of each can be roughly stated as:
THRESHOLD:
This is the total density value that POV-Ray is looking for. By
following the ray out into space and looking at how each blob component
affects the ray, POV-Ray will find the points in space where the density is
equal to the "threshold" value.
1) "threshold" must be greater than 0. POV-Ray only looks for positive
densities.
2) If "threshold" is greater than the strength of a component, then
the component will disappear.
3) As "threshold" gets larger the surface you see gets closer to the
centers of the components.
4) As "threshold" gets smaller, the surface you see gets closer to the
spheres at a distance of "radius" from the centers of the components.
STRENGTH:
Each component has a strength value - this defines the density of the
component at the center of the component. Changing this value will usually
have only a subtle effect.
1) "strength" may be positive or negative. Zero is a bad value, as the
net result is that no density was added - you might just as well have not
used this component.
2) If "strength" is positive, then POV-Ray will add its density to the
space around the center of the component. If this adds enough density to be
greater than "threshold you will see a surface.
3) If "strength" is negative, then POV-Ray will subtract its density
from the space around the center of the component. This will only do
something if there happen to be positive components nearby. What happens is
that the surface around any nearby positive components will be dented away
from the center of the negative component.
RADIUS:
Each component has a radius of influence. The component can only
affect space within "radius" of its center. This means that if all of the
components are farther than "radius" from each other, you will only see a
bunch of spheres. If a component is within the radius of another
component, then the two components start to affect each other. At first
there is only a small bulge outwards on each of the two components, as they
get closer they bulge more and more until they attach along a smooth neck.
If the components are very close (i.e. their centers are on top of each
other), then you will only see a sphere (this is just like having a
component of more strength. bigger than the size of each of the component
radii)
1) "radius" must be bigger than 0.
2) As "radius" increases the apparent size of the component will
increase.
CENTER:
This is simply a point in space. It defines the center of a blob
component. By changing the x/y/z values of the center you move the
component around.
THE FORMULA
For the more mathematically minded, here's the formula used internally
by POV-Ray to create blobs. You don't need to understand this to use blobs.
The formula used for a single blob component is:
density = strength * (1 - radius^2)^2
This formula has the nice property that it is exactly equal to strength" at
the center of the component and drops off to exactly 0 at a distance of
"radius" from the center of the component. The density formula for more
than one blob component is just the sum of the individual component
densities:
density = density1 + density2 + ...
Blobs can be used in CSG shapes and they can be scaled, rotated and
translated. Because they are finite they respond to automatic bounding.
The calculations for blobs must be very accurate. If this shape renders
improperly you may add the keyword "sturm" after the last component to use
POV-Ray's slower-yet-more-accurate Sturmian root solver.
5.2.1.7 Height Fields
Height fields are fast, efficient objects that are generally used to create
mountains or other raised surfaces out of hundreds of triangles in a mesh.
A height field is essentially a 1 unit wide by 1 unit long box with a
mountainous surface on top. The height of the mountain at each point is
taken from the color number (palette index) of the pixels in a graphic
image file.
________ <---- image index 255
/ /|
+1y ---------- |
| | |
| | |+1z <- Image upper-right
| | /
0,0,0---------- +1x
^
|____ Image lower-left
NOTE: Image resolution is irrelevant to the scale of the heightfield.
The mesh of triangles corresponds directly to the pixels in the image file.
In fact, there are two small triangles for every pixel in the image file.
The Y (height) component of the triangles is determined by the palette
index number stored at each location in the image file. The higher the
number, the higher the triangle. The maximum height of an un-scaled height
field is 1 unit.
The higher the resolution of the image file used to create the height
field, the smoother the height field will look. A 640 X 480 GIF will create
a smoother height field than a 320 x 200 GIF. The size/resolution of the
image does not affect the size of the height field. The un-scaled height
field size will always be 1x1. Higher resolution image files will create
smaller triangles, not larger height fields.
There are three types files which can define a height field as follows:
height_field { gif "filename.gif" }
height_field { tga "filename.tga" }
height_field { pot "filename.pot" }
The image file used to create a height field can be a GIF, TGA or POT
format file. The GIF format is the only one that can be created using a
standard paint program.
In a GIF file, the color number is the palette index at a given point. Use
a paint program to look at the palette of a GIF image. The first color is
palette index zero, the second is index 1, the third is index 2, and so on.
The last palette entry is index 255. Portions of the image that use low
palette entries will be lower on the height field. Portions of the image
that use higher palette entries will be higher on the height field. For
example, an image that was completely made up of entry 0 would be a flat
1x1 square. An image that was completely made up of entry 255 would be a
1x1x1 cube.
The maximum number of colors in a GIF are 256, so a GIF height field can
have any number of triangles, but they will only 256 different height
values.
The color of the palette entry does not affect the height of the pixel.
Color entry 0 could be red, blue, black, or orange, but the height of any
pixel that uses color entry 0 will always be 0. Color entry 255 could be
indigo, hot pink, white, or sky blue, but the height of any pixel that uses
color entry 255 will always be 1.
You can create height field GIF images with a paint program or a fractal
program like "Fractint". If you have access to an IBM-PC, you can get
Fractint from most of the same sources as POV-Ray.
A POT file is essentially a GIF file with a 16 bit palette. The maximum
number of colors in a POT file is greater than 32,000. This means a POT
height field can have over 32,000 possible height values. This makes it
possible to have much smoother height fields. Note that the maximum height
of the field is still 1 even though more intermediate values are possible.
At the time of this writing, the only program that created POT files was a
freeware IBM-PC program called Fractint. POT files generated with this
fractal program create fantastic landscapes. If you have access to an IBM-
PC, you can get Fractint from most of the same sources as POV-Ray.
The TGA file format may be used as a storage device for 16 bit numbers
rather than an image file. The TGA format uses the red and green bytes of
each pixel to store the high and low bytes of a height value. TGA files are
as smooth as POT files, but they must be generated with special custom-made
programs. Currently, this format is of most use to programmers, though you
may see TGA height field generator programs arriving soon. There is
example C source code included with the POV-Ray source archive to create a
TGA file for use with a height field.
It is nearly impossible to take advantage of the 16 bits of resolution
offered by the use of tga files in height fields when the tga file is
created in a paint program. A gif file is a better choice for paint
created height fields in 8 bits. Also see Appendix B.5 for a tip on
creating tga files for height fields.
An optional "water_level" parameter may be added after the file name. It
consists of the keyword "water_level" followed by a float value tells the
program not to look for the height field below that value. Default value is
0, and legal values are between 0 and 1. For example, "water_level .5"
tells POV-Ray to only render the top half of the height field. The other
half is "below the water" and couldn't be seen anyway. This term comes from
the popular use of height fields to render landscapes. A height field would
be used to create islands and another shape would be used to simulate water
around the islands. A large portion of the height field would be obscured
by the "water" so the "water_level" parameter was introduced to allow the
ray-tracer to ignore the unseen parts of the height field. Water_level is
also used to "cut away" unwanted lower values in a height field. For
example, if you have an image of a fractal on a solid colored background,
where the background color is palette entry 0, you can remove the
background in the height field by specifying, "water_level .001"
Normally height fields have a rough, jagged look because they are made of
lots of flat triangles. Adding the keyword "smooth" causes POV-Ray to
modify the surface normal vectors of the triangles in such a way that the
lighting and shading of the triangles will give a smooth look. This may
allow you to use a lower resolution file for your height field than would
otherwise be needed.
Height fields can be used in CSG shapes and they can be scaled, rotated and
translated. Because they are finite they respond to automatic bounding.
Here are a notes and helpful hints on height fields from their creator,
Doug Muir:
The height field is mapped to the x-z plane, with its lower left corner
sitting at the origin. It extends to 1 in the positive x direction and to 1
in the positive z direction. It is maximum 1 unit high in the y direction.
You can translate it, scale it, and rotate it to your heart's content.
When deciding on what water_level to use, remember, this applies to the un-
transformed height field. If you are a Fractint user, the water_level
should be used just like the water_level parameter for 3d projections in
Fractint.
Here's a detailed explanation of how the ray-tracer creates the height
field. You can skip this if you aren't interested in the technical side of
ray-tracing. This information is not needed to create or use height fields.
To find an intersection with the height field, the ray tracer first checks
to see if the ray intersects the box which surrounds the height field.
Before any transformations, this box's two opposite vertexes are at (0,
water_level, 0) and (1, 1, 1). If the box is intersected, the ray tracer
figures out where, and then follows the line from where the ray enters the
box to where it leaves the box, checking each pixel it crosses for an
intersection.
It checks the pixel by dividing it up into two triangles. The height vertex
of the triangle is determined by the color index at the corresponding
position in the GIF, POT, or TGA file.
If your file has a uses the color map randomly, your height field is going
to look pretty chaotic, with tall, thin spikes shooting up all over the
place. Not every GIF will make a good height field.
If you want to get an idea of what your height field will look like, I
recommend using the IBM-PC program Fractint's 3d projection features to do
a sort of preview. If it doesn't look good there, the ray tracer isn't
going to fix it. For those of you who can't use Fractint, convert the image
palette to a gray scale from black at entry 0 to white at entry 255 with
smooth steps of gray in-between. The dark parts will lower than the
brighter parts, so you can get a feel for how the image will look as a
height field.
5.2.2 FINITE PATCH PRIMITIVES
There are 4 totally thin, finite objects which have NO well-defined inside.
They may be combined in CSG union but cannot be use in other types of CSG.
They are bicubic_patch, disc, smooth_triangle and triangle. Because these
types are finite, POV-Ray can use automatic bounding on them to speed up
rendering time.
5.2.2.1 Triangle and Smooth_triangle
The triangle primitive is available in order to make more complex objects
than the built-in shapes will permit. Triangles are usually not created by
hand, but are converted from other files or generated by utilities.
A triangle is defined by:
triangle { <CORNER1>, <CORNER2>, <CORNER3> }
where <CORNER> is a vector defining the x,y,z coordinates of each corner
of the triangle.
Because triangles are perfectly flat surfaces it would require extremely
large numbers of very small triangles to approximate a smooth, curved
surface. However much of our perception of smooth surfaces is dependent
upon the way light and shading is done. By artificially modifying the
surface normals we can simulate as smooth surface and hide the sharp-edged
seams between individual triangles.
The smooth_triangle primitive is used for just such purposes. The
smooth_triangles use a formula called Phong normal interpolation to
calculate the surface normal for any point on the triangle based on normal
vectors which you define for the three corners. This makes the triangle
appear to be a smooth curved surface. A smooth_triangle is defined by:
smooth_triangle {
<CORNER1>, <NORMAL1>,
<CORNER2>, <NORMAL2>,
<CORNER3>, <NORMAL>3
}
where the corners are defined as in regular triangles and <NORMAL> is a
vector describing the direction of the surface normal at each corner.
These normal vectors are prohibitively difficult to compute by hand.
Therefore smooth_triangles are almost always generated by utility programs.
To achieve smooth results, any triangles which share a common vertex should
have the same normal vector at that vertex. Generally the smoothed normal
should be the average of all the actual normals of the triangles which
share that point.
5.2.2.2 Bicubic_patch
A bicubic patch is a 3D curved surface created from a mesh of triangles.
POV-Ray supports a type of bicubic patch called a Bezier patch. A bicubic
patch is defined as follows:
bicubic_patch {
type PATCH_TYPE
flatness FLATNESS_VALUE
u_steps NUM_U_STEPS
v_steps NUM_V_STEPS
<CP1>, <CP2>, <CP3>, <CP4>,
<CP5>, <CP6>, <CP7>, <CP8>,
<CP9>, <CP10>, <CP11>, <CP12>,
<CP13>, <CP14>, <CP15>, <CP16>
}
The keyword "type" is followed by a float PATCH_TYPE which currently must
be either 0 or 1. For type 0 only the control points are retained within
POV-Ray. This means that a minimal amount of memory is needed, but POV-Ray
will need to perform many extra calculations when trying to render the
patch. Type 1 preprocesses the patch into many subpatches. This results
in a significant speedup in rendering, at the cost of memory.
These 4 parameters: type, flatness, u_steps & v_steps, may appear in any
order. They are followed by 16 vectors that define the x,y,z coordinates
of the 16 control points which define the patch. The patch touches the 4
corner points , , and while the other 12 points
pull and stretch the patch into shape.
The keywords "u_steps" and "v_steps" are each followed by float values
which tell how many rows and columns of triangles are the minimum to use to
create the surface. The maximum number of individual pieces of the patch
that are tested by POV-Ray can be calculated from the following:
sub-pieces = 2^u_steps * 2^v_steps
This means that you really should keep "u_steps" and "v_steps" under 4 or
5. Most patches look just fine with "u_steps 3" and "v_steps 3", which
translates to 64 subpatches (128 smooth triangles).
As POV-Ray processes the Bezier patch, it makes a test of the current piece
of the patch to see if it is flat enough to just pretend it is a rectangle.
The statement that controls this test is: "flatness xxx". Typical flatness
values range from 0 to 1 (the lower the slower).
If the value for flatness is 0, then POV-Ray will always subdivide the
patch to the extend specified by u_steps and v_steps. If flatness is
greater than 0, then every time the patch is split, POV-Ray will check to
see if there is any need to split further.
There are both advantages and disadvantages to using a non-zero flatness.
The advantages include:
If the patch isn't very curved, then this will be detected and POV-Ray
won't waste a lot of time looking at the wrong pieces.
If the patch is only highly curved in a couple of places, POV-Ray will
keep subdividing there and concentrate it's efforts on the hard part.
The biggest disadvantage is that if POV-Ray stops subdividing at a
particular level on one part of the patch and at a different level on an
adjacent part of the patch, there is the potential for "cracking". This is
typically visible as spots within the patch where you can see through. How
bad this appears depends very highly on the angle at which you are viewing
the patch.
Like triangles, the bicubic patch is not meant to be generated by hand.
These shapes should be created by a special utility. You may be able to
acquire utilities to generate these shapes from the same source from which
you obtained POV-Ray.
Example:
bicubic_patch {
type 1
flatness 0.01
u_steps 4
v_steps 4
<0, 0, 2>, <1, 0, 0>, <2, 0, 0>, <3, 0,-2>,
<0, 1 0>, <1, 1, 0>, <2, 1, 0>, <3, 1, 0>,
<0, 2, 0>, <1, 2, 0>, <2, 2, 0>, <3, 2, 0>,
<0, 3, 2>, <1, 3, 0>, <2, 3, 0>, <3, 3, -2>
}
The triangles in a POV-Ray bicubic_patch are automatically smoothed using
normal interpolation but it is up to the user (or the user's utility
program) to create control points which smoothly stitch together groups of
patches.
As with the other shapes, bicubic_patch objects can be translated, rotated,
and scaled. Because they are finite they respond to automatic bounding.
Since it's made from triangles, a bicubic_patch cannot be used in CSG
intersection or difference types or inside a clipped_by modifier because
triangles have no clear "inside". The CSG union type works acceptably.
5.2.2.3 Disc
One other flat, finite object type is available with POV-Ray. Note that a
disc is infinitely thin. It has no thickness. If you want a disc with
true thickness you should use a very short cylinder. A disc shape may be
defined by:
disc { <CENTER>, <NORMAL>, RADIUS }
or
disc { <CENTER>, <NORMAL>, RADIUS, HOLE_RADIUS }
The vector <CENTER> defines the x,y,z coordinates of the center of the
disc. The <NORMAL> vector describes its orientation by describing its
surface normal vector. This is followed by a float specifying the RADIUS.
This may be optionally followed by another float specifying the radius of a
hole to be cut from the center of the disc.
Example:
disc {
<-2,-0.5, 0>, //center location
<0, 1, 0>, //normal vector
2 //radius
pigment { color Cyan }
}
disc {
<0, 1, 0>, //center location
<-1, 3, -2>, //normal vector
1.5, //radius
0.5 //hole radius (optional)
pigment { color Yellow }
}
As with the other shapes, discs can be translated, rotated, and scaled.
Because they are finite they respond to automatic bounding. Disc cannot be
used in CSG intersection or difference types or inside a clipped_by
modifier because it has no clear "inside". The CSG union type works
acceptably.
5.2.3 INFINITE SOLID PRIMITIVES
There are 5 polynomial primitive shapes that are possibly infinite and do
not respond to automatic bounding. They do have a well defined inside and
may be used in CSG. They are plane, cubic, poly, quadric, and quartic.
5.2.3.1 Plane
The plane primitive is a fast, efficient way to define an infinite flat
surface. The plane is specified as follows:
plane { <NORMAL>, DISTANCE }
The <NORMAL> vector defines the surface normal of the plane. A surface
normal is a vector which points up from the surface at a 90 degree angle.
This is followed by a float value that gives the distance along the normal
that the plane is from the origin. For example:
plane { <0,1,0>,4 }
This is a plane where "straight up" is defined in the positive y direction.
The plane is 4 units in that direction away from the origin. Because most
planes are defined with surface normals in the direction of an axis, you
will often see planes defined using the "x", "y", or "z" built-in vector
identifiers. The example above could be specified as:
plane { y,4 }
The plane extends infinitely in the x and z directions. It effectively
divides the world into two pieces. By definition the normal vector points
to the outside of the plane while any points away from the vector are
defined as inside. This inside/outside distinction is only important when
using planes in CSG.
As with the other shapes, planes can be translated, rotated, and scaled.
Because they are infinite they do not respond to automatic bounding. Plane
can be used freely in CSG because it has a clear defined "inside".
A plane is called a "polynomial" shape because it is defined by a first
order polynomial equation. Given a plane:
plane { , D }
it can be represented by the formula:
A*x + B*y + C*z = D
Therefore our example "plane {y,4}" is actually the polynomial equation
"y=4". You can think of this as a set of all x,y,z points where all have y
values equal to 4, regardless of the x or z values.
This equation is a "first order" polynomial because each term contains only
single powers of x, y or z. A second order equation has terms like x^2,
y^2, z^2, xy, xz and yz. Another name for a 2nd order equation is a
quadric equation. Third order polys are called cubics. A 4th order
equation is a quartic. Such shapes are described in the sections below.
5.2.3.2 Quadric
Quadric surfaces can produce shapes like ellipsoids, spheres, cones,
cylinders, paraboloids (dish shapes), and hyperboloids (saddle or hourglass
shapes). NOTE: Do not confuse "quaDRic" with "quaRTic". A quadric is a
2nd order polynomial while a quartic is 4th order.
A quadric is defined in POV-Ray by:
quadric { <A,B,C>, <D,E,F>, <G,H,I>, J }
where A through J are float expressions.
This defines a surface of x,y,z points which satisfy the equation:
A x^2 + B y^2 + C z^2
+ D xy + E xz + F yz
+ G x + H y + I z + J = 0
Different values of A,B,C,...J will give different shapes. So, if you take
any three dimensional point and use its x, y, and z coordinates in the
above equation, the answer will be 0 if the point is on the surface of the
object. The answer will be negative if the point is inside the object and
positive if the point is outside the object. Here are some examples:
X^2 + Y^2 + Z^2 - 1 = 0 Sphere
X^2 + Y^2 - 1 = 0 Infinitely long cylinder along the Z axis
X^2 + Y^2 - Z^2 = 0 Infinitely long cone along the Z axis
The easiest way to use these shapes is to include the standard file
"SHAPES.INC" into your program. It contains several pre-defined quadrics
and you can transform these pre-defined shapes (using translate, rotate,
and scale) into the ones you want.
You can invoke them by using the syntax,
object { Quadric_Name }
The pre-defined quadrics are centered about the origin <0, 0, 0> and have a
radius of 1. Don't confuse radius with width. The radius is half the
diameter or width making the standard quadrics 2 units wide.
Some of the pre-defined quadrics are,
Ellipsoid
Cylinder_X, Cylinder_Y, Cylinder_Z
QCone_X, QCone_Y, QCone_Z
Paraboloid_X, Paraboloid_Y, Paraboloid_Z
For a complete list, see the file SHAPES.INC.
5.2.3.3 Poly, Cubic and Quartic.
Higher order polynomial surfaces may be defined by the use of a poly shape.
The syntax is:
poly { ORDER, <T1, T2, T3, .... Tm> }
Where ORDER is a whole number from 2 to 7 inclusively that specifies the
order of the equation. T1, T2... Tm are float values for the coefficients
of the equation. There are "m" such terms where
m=((ORDER+1)*(ORDER+2)*(ORDER+3))/6
An alternate way to specify 3rd order polys is:
cubic { <T1, T2,... T20> }
Also 4th order equations may be specified with:
quartic { <T1, T2,... T35> }
Here's a more mathematical description of quartics for those who are
interested. Quartic surfaces are 4th order surfaces, and can be used to
describe a large class of shapes including the torus, the lemniscate, etc.
The general equation for a quartic equation in three variables is (hold
onto your hat):
a00 x^4 + a01 x^3 y + a02 x^3 z+ a03 x^3 + a04 x^2 y^2+
a05 x^2 y z+ a06 x^2 y + a07 x^2 z^2+a08 x^2 z+a09 x^2+
a10 x y^3+a11 x y^2 z+ a12 x y^2+a13 x y z^2+a14 x y z+
a15 x y + a16 x z^3 + a17 x z^2 + a18 x z + a19 x+
a20 y^4 + a21 y^3 z + a22 y^3+ a23 y^2 z^2 +a24 y^2 z+
a25 y^2 + a26 y z^3 + a27 y z^2 + a28 y z + a29 y+
a30 z^4 + a31 z^3 + a32 z^2 + a33 z + a34
To declare a quartic surface requires that each of the coefficients (a0 ->
a34) be placed in order into a single long vector of 35 terms.
As an example let's define a torus the hard way. A Torus can be
represented by the equation:
x^4 + y^4 + z^4 + 2 x^2 y^2 + 2 x^2 z^2 + 2 y^2 z^2
-2 (r0^2 + r1^2) x^2 + 2 (r0^2 - r1^2) y^2
-2 (r0^2 + r1^2) z^2 + (r0^2 - r1^2)^2 = 0
Where r0 is the "major" radius of the torus - the distance from the hole of
the donut to the middle of the ring of the donut, and r1 is the "minor"
radius of the torus - the distance from the middle of the ring of the donut
to the outer surface. The following object declaration is for a torus
having major radius 6.3 minor radius 3.5 (Making the maximum width just
under 10).
//Torus having major radius sqrt(40), minor radius sqrt(12)
quartic {
< 1, 0, 0, 0, 2, 0, 0, 2, 0,
-104, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 2, 0, 56, 0,
0, 0, 0, 1, 0, -104, 0, 784 >
sturm
bounded_by { // bounded_by speeds up the render,
// see bounded_by
// explanation later
// in docs for more info.
sphere { <0, 0, 0>, 10 }
}
}
Poly, cubic and quartics are just like quadrics in that you don't have to
understand what one is to use one. The file SHAPESQ.INC has plenty of pre-
defined quartics for you to play with. The most common one is the torus or
donut. The syntax for using a pre-defined quartic is:
object { Quartic_Name }
As with the other shapes, these shapes can be translated, rotated, and
scaled. Because they are infinite they do not respond to automatic
bounding. They can be used freely in CSG because they have a clear defined
"inside".
Polys use highly complex computations and will not always render perfectly.
If the surface is not smooth, has dropouts, or extra random pixels, try
using the optional keyword "sturm" in the definition. This will cause a
slower, but more accurate calculation method to be used. Usually, but not
always, this will solve the problem. If sturm doesn't work, try rotating,
or translating the shape by some small amount. See the sub-directory MATH
for examples of polys in scenes.
There are really so many different quartic shapes, we can't even begin to
list or describe them all. If you are interested and mathematically
inclined, an excellent reference book for curves and surfaces where you'll
find more quartic shape formulas is:
"The CRC Handbook of Mathematical Curves and Surfaces"
David von Seggern
CRC Press
1990
5.2.4 CONSTRUCTIVE SOLID GEOMETRY (CSG)
POV-Ray supports Constructive Solid Geometry (also called Boolean
operations) in order to make the shape definition abilities more powerful.
5.2.4.1 About CSG
The simple shapes used so far are nice, but not terribly useful on their
own for making realistic scenes. It's hard to make interesting objects when
you're limited to spheres, boxes, cylinders, planes, and so forth.
Constructive Solid Geometry (CSG) is a technique for taking these simple
building blocks and combining them together. You can use a cylinder to bore
a hole through a sphere. You can start with solid blocks and carve away
pieces. Objects may be combined in groups and treated as though they were
single objects.
Constructive Solid Geometry allows you to define shapes which are the
union, intersection, or difference of other shapes. Additionally you may
clip sections of objects revealing their hollow interiors.
Unions superimpose two or more shapes. This has the same effect as defining
two or more separate objects, but is simpler to create and/or manipulate.
In POV-Ray 2.0 the union keyword may be used anyplace composite was used in
previous versions of POV-Ray. Also a new type of union called "merge" can
eliminate internal surfaces on transparent or clipped objects.
Intersections define the space where the two or more surfaces overlap.
Differences allow you to cut one object out of another.
CSG intersections, unions, and differences can consist of two or more
shapes. For example:
union {
object{O1}
object{O2}
object{O3} // any number of objects
texture{T1}
}
CSG shapes may be used in CSG shapes. In fact, CSG shapes may be used
anyplace that a standard shape is used.
The order of the component shapes with the CSG doesn't matter except in a
difference shape. For CSG differences, the first shape is visible and the
remaining shapes are cut out of the first.
Constructive solid geometry shapes may be translated, rotated, or scaled in
the same way as any shape. The shapes making up the CSG shape may be
individually translated, rotated, and scaled as well.
When using CSG, it is often useful to invert a shape so that it's inside-
out. The appearance of the shape is not changed, just the way that POV-Ray
perceives it. The inverse keyword can be used to do this for any shape.
When inverse is used, the "inside" of the shape is flipped to become the
"outside". For planes, "inside" is defined to be "in the opposite direction
to the "normal" or "up" direction.
Note that performing an intersection between a shape and some other inverse
shapes is the same as performing a difference. In fact, the difference is
actually implemented in this way in the code.
5.2.4.2 Inside and outside
Most shape primitives, like spheres, boxes, and blobs, divide the world
into two regions. One region is inside the surface and one is outside.
(The exceptions to this rule are triangles, disc and bezier patches - we'll
talk about this later.)
Given any point in space, you can say it's either inside or outside any
particular primitive object (well, it could be exactly on the surface, but
numerical inaccuracies will put it to one side or the other).
Even planes have an inside and an outside. By definition, the surface
normal of the plane points towards the outside of the plane. (For a simple
floor, for example, the space above the floor is "outside" and the space
below the floor is "inside". For simple floors this in un-important, but
for planes as parts of CSG's it becomes much more important). CSG uses the
concepts of inside and outside to combine shapes together. Take the
following situation:
Note: The diagrams shown here demonstrate the concepts in 2D and are
intended only as an analogy to the 3D case.
Note that the triangles and triangle-based shapes cannot be used as solid
objects in CSG since they have no clear inside and outside.
In this diagram, point 1 is inside object A only. Point 2 is inside B
only. Point 3 is inside both A and B while point 0 is outside everything.
* = Object A
% = Object B
* 0
* * %
* * % %
* *% %
* 1 %* %
* % * 2 %
* % 3 * %
*******%******* %
% %
%%%%%%%%%%%%%%%%%
Complex shapes may be created by combining other shapes using a technique
called "Constructive Solid Geometry" (or CSG for short). The CSG shapes
are difference, intersection, and union. The following gives a simple 2D
overview of how these functions work.
5.2.4.3 Union
Unions are simply "glue", used bind two or more shapes into a single entity
that can be manipulated as a single object. The diagram above shows the
union of A and B. The new object created by the union operation can then
be scaled, translated, and rotated as a single shape. The entire union can
share a single texture, but each object contained in the union may also
have its own texture, which will override any matching texture statements
in the parent object:
union {
sphere { <0, 0.5, 0> 1 pigment { Red } }
sphere { <0, 0.0, 0> 1 }
sphere { <0,-0.5, 0> 1 }
pigment { Blue }
finish { Shiny }
}
This union will contain three spheres. The first sphere is explicitly
colored Red while the other two will be shiny blue. Note that the shiny
finish does NOT apply to the first sphere. This is because the
"pigment{Red}" is actually shorthand for "texture{pigment{Red}}". It
attaches an entire texture with default normals and finish. The textures
or pieces of textures attached to the union apply ONLY to components with
no textures. These texturing rules also apply to intersection, difference
and merge as well.
Earlier versions of POV-Ray placed restrictions on unions so you often had
to combine objects with composite statements. Those earlier restrictions
have been lifted so composite is no longer needed. Composite is still
supported for backwards compatibility but it is recommended that union now
be used in it's place since future support for the composite keyword is not
guarantied.
5.2.4.4 Intersection
A point is inside the intersection if it's inside both A AND B. This
"logical AND's" the shapes and gets the common part, most useful for
"cutting" infinite shapes off. The diagram below consists of only those
parts common to A and B.
%*
% *
% 3 *
%*******
For example:
intersection {
sphere {<-0.75,0,0>,1}
sphere {< 0.75,0,0>,1}
pigment {Yellow}
}
5.2.4.5 Difference
A point is inside the difference if it's inside A but not inside B. The
results is a "subtraction" of the 2nd shape from the first shape:
*
* *
* *
* *
* 1 %
* %
* %
*******%
For example:
difference {
sphere {<-0.75,0,0>,1}
sphere {< 0.75,0,-0.25>,1}
pigment {Yellow}
}
5.2.4.6 Merge
As can be seen in the diagram for union, the inner surfaces where the
objects overlap is still present. On transparent or clipped objects these
inner surfaces cause problems. A merge object works just like union but it
eliminates the inner surfaces like this:
*
* * %
* * % %
* *% %
* %
* %
* %
*******% %
% %
%%%%%%%%%%%%%%%%%
5.2.5 LIGHT SOURCES
The last object we'll cover is the light source. Light sources have no
visible shape of their own. They are just points or areas which emit
light.
5.2.5.1 Point Lights
Most light sources are infinitely small points which emit light. Point
light sources are treated like shapes, but they are invisible points from
which light rays stream out. They light objects and create shadows and
highlights. Because of the way ray tracing works, lights do not reflect
from a surface. You can use many light sources in a scene, but each light
source used will increase rendering time. The brightness of a light is
determined by its color. A bright color is a bright light, a dark color, a
dark one. White is the brightest possible light, Black is completely dark
and Gray is somewhere in the middle.
The syntax for a light source is:
light_source { <X, Y, Z> color red #, green #, blue #}
Where X, Y and Z are the coordinates of the location and "color" is any
color or color identifier. For example,
light_source { <3, 5, -6> color Gray50}
is a 50% Gray light at X=3, Y=5, Z=-6.
Point light sources in POV-Ray do not attenuate, or get dimmer, with
distance.
5.2.5.2 Spotlights
A spotlight is a point light source where the rays of light are constrained
by a cone. The light is bright in the center of the spotlight and falls
off/darkens to soft shadows at the edges of the circle.
The syntax is:
Syntax: light_source { <CENTER>
color red #, green #, blue #
spotlight
point_at <POINT>
radius #
falloff #
tightness #
}
A spotlight is positioned using two vectors. The first vector is the usual
<CENTER> vector that you would use to position a point light source.
The second vector is the point_at <POINT>, the vector position of
the point the light is pointing at, similar to the look_at in a camera
description.
The following illustrations will be helpful in understanding how these
values relate to each other:
(+) Spotlight <center>
/ \
/ \
/ \
/ \
/ \
/ \
+-----*-----+
^ point_at <point>
The center is specified the same way as a normal point light_source.
Point_at <POINT> is the location that the cone of light is
aiming at.
Spotlights also have three other parameters: radius, falloff, and
tightness.
If you think of a spotlight as two nested cones, the inner cone would be
specified by the radius parameter, and would be fully lit. The outer cone
would be the falloff cone and beyond it would be totally unlit. The values
for these two parameters are specified in degrees of the half angle at the
peak of each cone:
(+) Spotlight <center>
|\ <----- angle measured here
| \
|| \
|| \ shaded area = radius cone
||| \ outer line = falloff cone
|||| \
||||| \
+-------+
The radius# is the radius, in degrees, of the bright circular hotspot at
the center of the spotlight's area of affect.
The falloff# is the falloff angle of the radius of the total spotlight
area, in degrees. This is the value where the light "falls off" to zero
brightness. Falloff should be larger than the radius. Both values should
be between 1 and 180.
The tightness value specifies how quickly the light dims, or falls off, in
the region between the radius (full brightness) cone and the falloff (full
darkness) cone. The default value for tightness is 10. Lower tightness
values will make the spot have very soft edges. High values will make the
edges sharper, the spot "tighter". Values from 1 to 100 are acceptable.
Spotlights may used anyplace that a normal light source is used. Like
normal light sources, they are invisible points. They are treated as shapes
and may be included in CSG shapes. They may also be used in conjunction
with area_lights.
Example:
// This is the spotlight.
light_source {
<10, 10, 0>
color red 1, green 1, blue 0.5
spotlight
point_at <0, 1, 0>
tightness 50
radius 11
falloff 25
}
5.2.5.3 Area Lights
Regular light sources in POV-Ray are modeled as point light sources, that
is they emit light from a single point in space. Because of this the
shadows created by these lights have the characteristic sharp edges that
most of us are use to seeing in ray traced images. The reason for the
distinct edges is that a point light source is either fully in view or it
is fully blocked by an object. A point source can never be partially
blocked.
Area lights on the other hand occupy a finite area of space. Since it is
possible for an area light to be partially blocked by an object the shadows
created will have soft or "fuzzy" edges. The softness of the edge is
dependent on the dimensions of the light source and it's distance from the
object casting the shadow.
The area lights used in POV-Ray are rectangular in shape, sort of like a
flat panel light. Rather than performing the complex calculations that
would be required to model a true area light, POV-Ray approximates an area
light as an array of "point" light sources spread out over the area
occupied by the light. The intensity of each individual point light in the
array is dimmed so that the total amount of light emitted by the light is
equal to the light color specified in the declaration.
Syntax:
light_source {
<X, Y, Z> color red # green # blue #
area_light <X1, Y1, Z1>, <X2, Y2, Z2>, N1, N2
adaptive #
jitter
[optional spotlight parameters]
}
The light's location and color are specified in the same way as a
regular light source.
The area_light command defines the size and orientation of the area light
as well as the number of lights in the light source array. The vectors
<X1,Y1,Z1> and <X2,Y2,Z2> specify the lengths and directions of the edges
of the light. Since the area lights are rectangular in shape these vectors
should be perpendicular to each other. The larger the size of the light the
thicker that the soft part of the shadow will be. The numbers N1 and N2
specify the dimensions of the array of point lights. The larger the number
of lights you use the smoother your shadows will be but the longer they
will take to render.
The adaptive command is used to enable adaptive sampling of the light
source. By default POV-Ray calculates the amount of light that reaches a
surface from an area light by shooting a test ray at every point light
within the array. As you can imagine this is VERY slow. Adaptive sampling
on the other hand attempts to approximate the same calculation by using a
minimum number of test rays. The number specified after the keyword
controls how much adaptive sampling is used. The higher the number the more
accurate your shadows will be but the longer they will take to render. If
you're not sure what value to use a good starting point is 'adaptive 1'.
The adaptive command only accepts integer values and cannot be set lower
than 0. Adaptive sampling is explained in more detail later.
The jitter command is optional. When used it causes the positions of the
point lights in the array to be randomly jittered to eliminate any shadow
banding that may occur. The jittering is completely random from render to
render and should not be used when generating animations.
Note: It's possible to specify spotlight parameters along with area_light
parameters to create "area spotlights." Using area spotlights is a good way
to speed up scenes that use area lights since you can confine the lengthy
soft shadow calculations to only the parts of your scene that need them.
Example:
light_source {
<0, 50, 0> color White
area_light <5, 0, 0>, <0, 0, 10>, 5, 5
adaptive 1
jitter
}
This defines an area light that extends 5 units along the x axis and 10
units along the z axis and is centered at the location <0,50,0>. The light
consists of a 5 by 5 jittered array of point sources for a total of 25
point lights. A minimum of 9 shadow rays will be used each time this light
is tested.
/ * * * * *
/ * * * * * Y
<0,0,10> / * * * * * | Z
/ * * * * * | /
/ * * * * * | /
+-----------> +------X
<5,0,0>
An interesting effect that can be created using area lights is a linear
light. Rather than having a rectangular shape, a linear light stretches
along a line sort of like a thin fluorescent tube. To create a linear light
just create an area light with one of the array dimensions set to 1.
Example:
light_source {
<0, 50, 0> color White
area_light <40, 0, 0>, <0, 0, 1>, 100, 1
adaptive 4
jitter
}
This defines a linear light that extends from <-40/2,50,0> to <+40/2,50,0>
and consists of 100 point sources along it's length. The vector <0,0,1> is
ignored in this case since a linear light has no width. Note: If the linear
light is fairly long you'll usually need to set the adaptive parameter
fairly high as in the above example.
When performing adaptive sampling POV-Ray starts by shooting a test ray at
each of the four corners of the area light. If the amount of light received
from all four corners is approximately the same then the area light is
assumed to be either fully in view or fully blocked. The light intensity is
then calculated as the average intensity of the light received from the
four corners. However, if the light intensity from the four corners
differs significantly then the area light is partially blocked. The light
is the split into four quarters and each section is sampled as described
above. This allows POV-Ray to rapidly approximate how much of the area
light is in view without having to shoot a test ray at every light in the
array.
While the adaptive sampling method is fast (relatively speaking) it can
sometimes produces inaccurate shadows. The solution is to reduce the amount
of adaptive sampling without completely turning it off. The number after
the adaptive keyword adjusts the number of times that the area light will
be split before the adaptive phase begins. For example if you use "adaptive
0" a minimum of 4 rays will be shot at the light. If you use "adaptive 1" a
minimum of 9 rays will be shot (adaptive 2 = 25 rays, adaptive 3 = 81 rays,
etc). Obviously the more shadow rays you shoot the slower the rendering
will be so you should use the lowest value that gives acceptable results.
The number of rays never exceeds the values you specify for rows and
columns of points. For example: area_light x,y,4,4 specifies a 4 by 4
array of lights. If you specify adaptive 3 it would mean that you should
start with a 5 by 5 array. In this case no adaptive sampling is done. The
4 by 4 array is used.
5.2.5.4 Looks_like
Normally the light source itself has no visible shape. The light simply
radiates from an invisible point or area. You may give a light source a
any shape by adding a "looks_like{OBJECT}" statement. For example:
light_source {
<100,200,-300> color White
looks_like {sphere{<0,0,0>,1 texture{T1}}
}
This creates a visible sphere which is automatically translated to the
light's location <100,200,-300> even though the sphere has <0,0,0> as its
center. There is an implied "no_shadow" also attached to the sphere so
that light is not blocked by the sphere. Without the automatic no_shadow,
the light inside the sphere would not escape. The sphere would, in effect,
cast a shadow over everything.
If you want the attached object to block light then you should attach it
with a union and not a looks_like as follows:
union {
light_source {<100,200,-300> color White}
object {My_Lamp_Shade}
}
Presumably parts of the lamp shade are open to let SOME light out.