Part 2 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 { 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 {
color red #, green #, blue # spotlight point_at radius # falloff # tightness # } A spotlight is positioned using two vectors. The first vector is the usual
vector that you would use to position a point light source. The second vector is the point_at , 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
/ \ / \ / \ / \ / \ / \ +-----*-----+ ^ point_at The center is specified the same way as a normal point light_source. Point_at 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
|\ <----- 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.3.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 { color red # green # blue # area_light , , 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 and 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.3.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. 5.3 OBJECT MODIFIERS ---------------------- A variety of modifiers may be attached to objects. Transformations such as translate, rotate and scale have already been discussed. Textures are in a section of their own below. Here are three other important modifiers: clipped_by, bounded_by and no_shadow. Although the examples below use object statements and object identifiers, these modifiers may be used on any type of object such as sphere, box etc. 5.3.1 CLIPPED_BY The "clipped_by" statement is technically an object modifier but it provides a type of CSG similar to CSG intersection. You attach a clipping object like this: object { My_Thing clipped_by{plane{y,0}} } Every part of the object "My_Thing" that is inside the plane is retained while the remaining part is clipped off and discarded. In an intersection object, the hole is closed off. With clipped_by it leaves an opening. For example this diagram shows our object "A" being clipped_by a plane{y,0}. * * * * * * *************** Clipped_by may be used to slice off portions of any shape. In many cases it will also result in faster rendering times than other methods of altering a shape. Often you will want to use the clipped_by and bounded_by options with the same object. The following shortcut saves typing and uses less memory. object { My_Thing bounded_by{box{<0,0,0>,<1,1,1>}} clipped_by{bounded_by} } This tells POV-Ray to use the same box as a clip that was used as a bounds. 5.3.1 BOUNDED_BY The calculations necessary to test if a ray hits an object can be quite time consuming. Each ray has to be tested against every object in the scene. POV-Ray attempts so speed up the process by building a set of invisible boxes, called bounding slabs, which cluster the objects together. This way a ray that travels in one part of the scene doesn't have to be tested against objects in another far away part of the scene. When large number objects are present the slabs are nested inside each other. POV-Ray can use slabs on any finite object. However infinite objects such as plane, quadric, quartic, cubic & poly cannot be automatically bound. Also CSG objects cannot be efficiently bound by automatic methods. By attaching a bounded_by statement to such shapes you can speed up the testing of the shape and make it capable of using bounding slabs. If you use bounding shapes around any complex objects you can speed up the rendering. Bounding shapes tell the ray tracer that the object is totally enclosed by a simple shape. When tracing rays, the ray is first tested against the simple bounding shape. If it strikes the bounding shape, then the ray is further tested against the more complicated object inside. Otherwise the entire complex shape is skipped, which greatly speeds rendering. To use bounding shapes, simply include the following lines in the declaration of your object: bounded_by { object { ... } } An example of a Bounding Shape: intersection { sphere {<0,0,0>, 2} plane {<0,1,0>, 0} plane {<1,0,0>, 0} bounded_by {sphere {<0,0,0>, 2}} } The best bounding shape is a sphere or a box since these shapes are highly optimized, although, any shape may be used. If the bounding shape is itself a finite shape which responds to bounding slabs then the object which it encloses will also be used in the slab system. CSG shapes can benefit from bounding slabs without a bounded_by statement however they may do so inefficiently in intersection, difference and merge. In these three CSG types the automatic bound used covers all of the component objects in their entirety. However the result of these intersections may result in a smaller object. Compare the sizes of the illustrations for union and intersection in the CSG section above. It is possible to draw a much smaller box around the intersection of A and B than the union of A and B yet the automatic bounds are the size of union{A B} regardless of the kind of CSG specified. While it is almost always a good idea to manually add a bounded_by to intersection, difference and merge, it is often best to NOT bound a union. If a union has no bounded_by and no clipped_by then POV-Ray can internally split apart the components of a union and apply automatic bounding slabs to any of its finite parts. Note that some utilities such as RAW2POV may be able to generate bounds more efficiently than POV-Ray's current system. However most unions you create yourself can be easily bounded by the automatic system. For technical reasons POV-Ray cannot split a merge object. It is probably best to hand bound a merge, especially if it is very complex. Note that if bounding shape is too small or positioned incorrectly, it may clip the object in undefined ways or the object may not appear at all. To do true clipping, use clipped_by as explained above. Often you will want to use the clipped_by and bounded_by options with the same object. The following shortcut saves typing and uses less memory. object { My_Thing clipped_by{box{<0,0,0>,<1,1,1>}} bounded_by{clipped_by} } This tells POV-Ray to use the same box as a bounds that was used as a clip. 5.3.2 NO_SHADOW You may specify the no_shadow keyword in object and that object will not cast a shadow. This is useful for special effects and for creating the illusion that a light source actually is visible. This keyword was necessary in earlier versions of POV-Ray which did not have the "looks_like" statement. Now it is useful for creating things like laser beams or other unreal effects. Simply attach the keyword as follows: object { My_Thing no_shadow } 5.4 TEXTURES -------------- Textures are the materials from which the objects in POV-Ray are made. They specifically describe the surface coloring, shading, and properties like transparency and reflection. You can create your own textures using the parameters described below, or you can use the many pre-defined high quality textures that have been provided in the files TEXTURES.INC and STONES.INC. The tutorial in section 4 above introduces the basics of defining textures and attaching them to objects. It explains how textures are made up of three portions, a color pattern called "pigment", a bump pattern called "normal", and surface properties called "finish". The most complete form for defining a texture is as follows: texture { TEXTURE_IDENTIFIER pigment {...} normal {...} finish {...} TRANSFORMATIONS... } Each of the items in a texture are optional but if they are present, the identifier must be first and the transformations bust be last. The pigment, normal and finish parameters modify any pigment, normal and finish already specified in the TEXTURE_IDENTIFIER. If no texture identifier is specified then the pigment, normal and finish statements modify the current default values. TRANSFORMATIONs are translate, rotate and scale statements. They should be specified last. The sections below describe all of the options available in pigments, normals and finishes. 5.4.1 PIGMENT The color or pattern of colors for an object is defined by a pigment statement. A pigment statement is part of a texture specification. However it can be tedious to type "texture{pigment{...}}" just to add a color to an object. Therefore you may attach a pigment directly to an object without explicitly specifying that it as part of a texture. For example... this... can be shortened to this... object { object { My_Object My_Object texture { pigment {color Purple} pigment {color Purple} } } } The color you define is the way you want it to look if fully illuminated. You pick the basic color inherent in the object and POV-Ray brightens or darkens it depending on the lighting in the scene. The parameter is called "pigment" because we are defining the basic color the object actually IS rather than how it LOOKS. The most complete form for defining a pigment is as follows: pigment { PIGMENT_IDENTIFIER PATTERN_TYPE PIGMENT_MODIFIERS TRANSFORMATIONS... } Each of the items in a pigment are optional but if they are present, they should be in the order shown above to insure that the results are as expected. Any items after the PIGMENT_IDENTIFIER modify or override settings given in the IDENTIFIER. If no identifier is specified then the items modify the pigment values in the current default texture. TRANSFORMATIONs are translate, rotate and scale statements. They apply only to the pigment and not to other parts of the texture. They should be specified last. The various PATTERN_TYPEs fall into roughly 4 categories. Each category is discussed below. They are solid color, color list patterns, color mapped patterns and image maps. 5.4.1.1 Color The simplest type of pigment is a solid color. To specify a solid color you simply put a color specification inside a pigment. For example... pigment {color Orange} A color specification consists of the keyword "color" followed a color identifier or by a specification of the amount or red, green, blue and transparency in the surface. For example: color red 0.5 green 0.2 blue 1.0 The float values between 0.0 and 1.0 are used to specify the intensity of each primary color of light. Note that we use additive color primaries like the color phosphors on a color computer monitor or TV. Thus... color red 1.0 green 1.0 blue 1.0 ...specifies full intensity of all primary colors which is white light. The primaries may be given in any order and if any primary is unspecified its value defaults to zero. In addition to the primary colors a 4th value called "filter" specifies the amount of transparency. For example a piece of red tinted cellophane might have... color red 1.0 filter 1.0 Lowering the filter value would let less light through. The default value if no filter is specified is 0.0 or no transparency. Note that the example has an implied "green 0.0 blue 0.0" which means that no green or blue light can pass through. Often users mistakenly specify a clear object by... color filter 1.0 but this has implied red, green and blue values of zero. You've just specified a totally black filter so no light passes through. The correct way is... color red 1.0 green 1.0 blue 1.0 filter 1.0 Note in earlier versions of POV-Ray the keyword "alpha" was used for transparency. However common usage of "alpha" in this context usually means that light passes through unaffected. In POV-Ray however, light is filtered when it passes through a colored surface. The program works the same as it always did but the keyword has been changed to make its meaning clearer. A short-cut way to specify a color is... color rgb<0.2, 0.5, 0.9> or color rgbf<0.2, 0.8, 1.0, 0.7> Color specifications are used elsewhere in POV-Ray. Unless stated otherwise, all of the above information on color specs given above applies to any color spec. Color identifiers may be declared. For examples see COLORS.INC. A color identifier contains red, blue, green and filter values even if they are not explicitly specified. For example: color filter 1.0 My_Color // here My_Color overwrites the filter color My_Color filter 1.0 // this changes My_Color's filter value to 1.0 When using a color specification to give an object a solid color pigment, the keyword "color" may be omitted. For example... pigment {red 1 blue 0.5} or pigment {My_Color} are legal. 5.4.1.2 Color List Patterns -- checker and hexagon Two of the simplest color patterns available are the checker and hexagon patterns. These patterns take a simple list of colors one after the other. For example a checker pattern is specified by... pigment {checker color C1 color C2} This produces a checkered pattern consisting of alternating squares of color C1 and C2. If no colors are specified then default blue and green colors are used. All color patterns in POV-Ray are 3 dimensional. For every x,y,z point in space, the pattern has a unique color. In the case of a checker pattern it is actually a series of cubes that are one unit in size. Imagine a bunch of 1 inch cubes made from two different colors of modeling clay. Now imagine arranging the cubes in an alternating check pattern and stacking them in layer after layer so that the colors still alternated in every direction. Eventually you would have a larger cube. The pattern of checks on each side is what the POV-Ray checker pattern produces when applied to a box object. Finally imagine cutting away at the cube until it is carved into a smooth sphere or any other shape. This is what the checker pattern would look like on an object of any kind. Color patterns do not wrap around the surfaces like putting wallpaper on an object. The patterns exist in 3-d and the objects are carved from them like carving stacked colored cubes. In a later section we describe wood and marble patterns for example. The wood grain or stone swirls exist through the whole object but they appear only at the surface. Another pattern that uses a list of colors is the hexagon pattern. A hexagon pattern is specified by... pigment {hexagon color C1 color C2 color C3} Hex pattern generates a repeating pattern of hexagons in the XZ plane. In this instance imagine tall rods that are hexagonal in shape and are parallel to the Y axis and grouped in bundles like this... _____ / \ / C2 \_____ |\ / \ | \_____/ C3 \ | / \ /| / C1 \_____/ | |\ /| | | | \_____/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The three colors will repeat the pattern shown above with hexagon C1 centered at the origin. Each side of the hexagon is one unit long. The hexagonal "rods" of color extend infinitely in the +Y and -Y directions. If no colors are specified then default blue, green, and red colors are used. 5.4.1.3 Color Mapped Patterns Most of the color patterns do not use abrupt color changes of just two or three colors like those in the checker or hexagon patterns. They instead use smooth transitions of many colors that gradually change from one point to the next. The colors are defined in a color map that describes how the pattern blends from one color to the next. 5.4.1.3.1 Gradient This simplest such pattern is the "gradient" pattern. It is specified as follows... pigment {gradient VECTOR} where VECTOR is a vector pointing in the direction that the colors blend. For example: sphere { <0, 1, 2>, 2 pigment { gradient x } // bands of color vary as you move // along the "x" direction. } This produces a series of smooth bands of color that look like layers of color next to each other. Points at x=0 are black. As the X location increases it smoothly turns to white at x=1. Then it starts over with black and gradually turns white at x=2. The pattern reverses for negative values of X. Using "gradient y" or "gradient z" makes the colors blend along the y or z axis. Any vector may be used but x, y and z are most common. 5.4.1.3.2 Color Maps The gray scale default colors of the gradient pattern isn't a very interesting sight. The real power comes from specifying a color map to define how the colors should blend. Each of the various pattern types available is in fact a mathematical function that takes any x,y,z location and turns it into a number between 0.0 and 1.0. That number is used to specify what mix of colors to use from the color map. A color map is specified by... color_map { [ NUM_1 color C1] [ NUM_2 color C2] [ NUM_3 color C3] ... } Where NUM_1, NUM_2... are float values between 0.0 and 1.0 inclusive. C1, C2 ... are color specifications. NOTE: the [] brackets are part of the actual statement. They are not notational symbols denoting optional parts. The brackets surround each entry in the color map. There may be from 2 to 20 entries in the map. For example, sphere { <0,1,2>, 2 pigment { gradient x color_map { [0.1 color Red] [0.3 color Yellow] [0.6 color Blue] [0.6 color Green] [0.8 color Cyan] } } } The pattern function is evaluated and the result is a value from 0.0 to 1.0. If the value is less than the first entry (in this case 0.1) then the first color (Red) is used. Values from 0.1 to 0.3 use a blend of red and yellow using linear interpolation of the two colors. Similarly values from 0.3 to 0.6 blend from yellow to blue. Note that the 3rd and 4th entries both have values of 0.6. This causes an immediate abrupt shift of color from blue to green. Specifically a value that is less than 0.6 will be blue but exactly equal to 0.6 will be green. Moving along, values from 0.6 to 0.8 will be a blend of green and cyan. Finally any value greater than or equal to 0.8 will be cyan. If you want areas of unchanging color you simply specify the same color for two adjacent entries. For example: color_map { [0.1 color Red] [0.3 color Yellow] [0.6 color Yellow] [0.8 color Green] } In this case any value from 0.3 to 0.6 will be pure yellow. 5.4.1.3.3 Marble A "gradient x" pattern uses colors from the color map from 0.0 up to 1.0 at location x=1 but then jumps back to the first color for x=1.00000001 (or some tiny fraction above 1.0) and repeats the pattern again and again. The marble pattern is similar except that it uses the color map from 0 to 1 but then it reverses the map and blends from 1 back to zero. For example: pigment { gradient x color_map { [0.0 color Yellow] [1.0 color Cyan] } } This blends from yellow to cyan and then it abruptly changes back to yellow and repeats. However replacing "gradient x" with "marble" smoothly blends from yellow to cyan as the x coordinate goes from 0.0 to 0.5 and then smoothly blends back from cyan to yellow by x=1.0. When used with a "turbulence" modifier and an appropriate color map, this pattern looks like veins of color of real marble, jade or other types of stone. By default, marble has no turbulence. 5.4.1.3.4 Wood Wood uses the color map to create concentric cylindrical bands of color centered on the Z axis. These bands look like the growth rings and veins in real wood. Small amounts of turbulence should be added to make it look more realistic. By default, wood has no turbulence. Like marble, wood uses color map values 0 to 1 then repeats the colors in reverse order from 1 to 0. 5.4.1.3.5 Onion Onion is a pattern of concentric spheres like the layers of an onion. It uses colors from a color map from 0 to 1, 0 to 1 etc without reversing. 5.4.1.3.6 Leopard Leopard creates regular geometric pattern of circular spots. It uses colors from a color map from 0 to 1, 0 to 1 etc without reversing. 5.4.1.3.7 Granite This pattern uses a simple 1/f fractal noise function to give a pretty darn good granite pattern. Typically used with small scaling values (2.0 to 5.0). This pattern is used with creative color maps in STONES.INC to create some gorgeous layered stone textures. By default, granite has no turbulence. It uses colors from a color map from 0 to 1, 0 to 1 etc without reversing. 5.4.1.3.8 Bozo The bozo color pattern takes a noise function and maps it onto the surface of an object. It uses colors from a color map from 0 to 1, 0 to 1 etc without reversing. Noise in ray tracing is sort of like a random number generator, but it has the following properties: 1) It's defined over 3D space i.e., it takes x, y, and z and returns the noise value there. 2) If two points are far apart, the noise values at those points are relatively random. 3) If two points are close together, the noise values at those points are close to each other. You can visualize this as having a large room and a thermometer that ranges from 0.0 to 1.0. Each point in the room has a temperature. Points that are far apart have relatively random temperatures. Points that are close together have close temperatures. The temperature changes smoothly, but randomly as we move through the room. Now, let's place an object into this room along with an artist. The artist measures the temperature at each point on the object and paints that point a different color depending on the temperature. What do we get? A POV-Ray bozo texture! 5.4.1.3.9 Spotted This uses the same noise pattern as bozo but it is unaffected by turbulence. It uses colors from a color map from 0 to 1, 0 to 1 etc without reversing. 5.4.1.3.10 Agate This pattern is very beautiful and similar to marble, but uses a different turbulence function. The turbulence keyword has no effect, and as such it is always very turbulent. You may control the amount of the built-in turbulence by adding the "agate_turb" keyword followed by a float value. For example: pigment { agate agate_turb 0.5 color_map { ... } } 5.4.1.3.11 Mandel The mandel pattern computes the standard Mandelbrot fractal pattern and projects it onto the X-Y plane. It uses the X and Y coordinates to compute the Mandelbrot set. The pattern is specified with the keyword mandel followed by an integer number. This number is the maximum number of iterations to be used to compute the set. Typical values range from 10 up to 256 but any positive integer may be used. For example: sphere { <0, 0, 0>, 1 pigment { mandel 25 color_map { [0.0 color Cyan] [0.3 color Yellow] [0.6 color Magenta] [1.0 color Cyan] } scale .5 } } The value passed to the color map is computed by the formula: value = number_of_iterations / max_iterations The color extends infinitely in the Z direction similar to a planar image map. 5.4.1.3.12 Radial The radial pattern is a radial blend that wraps around the +Y axis. The color for value 0.0 starts at the +X direction and wraps the color map around from east to west with 0.25 in the -Z direction, 0.5 in -X, 0.75 at +Z and back to 1.0 at +X. See the "frequency" and "phase" pigment modifiers below for examples. 5.4.1.4 Image Maps When all else fails and none of the above pigment pattern types meets your needs, you can use an image map to wrap a 2-D bit-mapped image around your 3-D objects. 5.4.1.4.1 Specifying an image map. The syntax for image_map is... pigment { image_map { FILE_TYPE "filename" MODIFIERS... } } Where FILE_TYPE is one of the following keywords "gif", "tga", "iff" or "dump". This is followed by the name of the file in quotes. Several optional modifiers may follow the file specification. The modifiers are described below. Note: Earlier versions of POV-Ray allowed some modifiers before the FILE_TYPE but that syntax is being phased out in favor of the syntax described here. Filenames specified in the image_map statements will be searched for in the home (current) directory first, and if not found, will then be searched for in directories specified by any "-L" (library path) options active. This would facilitate keeping all your image maps files in a separate subdirectory, and giving an "-L" option on the command line to where your library of image maps are. By default, the image is mapped onto the X-Y plane. The image is "projected" onto the object as though there were a slide projector somewhere in the -Z direction. The image exactly fills the square area from x,y coordinates (0,0) to (1,1) regardless of the image's original size in pixels. If you would like to change this default, you may translate, rotate or scale the pigment or texture to map it onto the object's surface as desired. In the section 5.4.1.2 above when we explained checker pigment patterns, we described the checks as solid cubes of colored clay from which objects are carved. With image maps you should imagine that each pixel is a long, thin, square, colored rod that extends parallel to the Z axis. The image is made from rows and columns of these rods bundled together and the object is then carved from the bundle. If you would like to change this default orientation, you may translate, rotate or scale the pigment or texture to map it onto the object's surface as desired. 5.4.1.4.2 The "once" option. Normally there are an infinite number of repeating images created over every unit square of the X-Y plane like tiles. By adding the keyword "once" after a file name, you can eliminate all other copies of the image except the one at (0,0) to (1,1). Areas outside this unit square are treated as fully transparent. Note: The "once" keyword may also be used with bump_map and material_map statements. 5.4.1.4.3 The "map_type" option. The default projection of the image onto the X-Y plane is called a "planar map type". This option may be changed by adding the "map_type" keyword followed by a number specifying the way to wrap the image around the object. A "map_type 0" gives the default planar mapping already described. A "map_type 1" is a spherical mapping. It assumes that the object is a sphere of any size sitting at the origin. The Y axis is the north/south pole of the spherical mapping. The top and bottom edges of the image just touch the pole regardless of any scaling. The left edge of the image begins at the positive X axis and wraps the image around the sphere from "west" to "east" in a -Y rotation. The image covers the sphere exactly once. The "once" keyword has no meaning for this type. With "map_type 2" you get a cylindrical mapping. It assumes that a cylinder of any diameter lies along the Y axis. The image wraps around the cylinder just like the spherical map but the image remains 1 unit tall from y=0 to y=1. This band of color is repeated at all heights unless the "once" keyword is applied. Finally "map_type 5" is a torus or donut shaped mapping. It assumes that a torus of major radius 1 sits at the origin in the X-Z plane. The image is wrapped around similar to spherical or cylindrical maps. However the top and bottom edges of the map wrap over and under the torus where they meet each other on the inner rim. Types 3 and 4 are still under development. Note: The "map_type" option may also be applied to bump_map and material_map statements. 5.4.1.4.4 The "filter" options. To make all or part of an image map transparent, you can specify filter values for the color palette/registers of GIF or IFF pictures (at least for the modes that use palettes/color maps). You can do this by adding the keyword "filter" following the filename. The keyword is followed by two numbers. The first number is the palette/register number value and 2nd is the amount of transparency. The values should be separated by a comma. For example: image_map { gif "mypic.gif" map_type 0 filter 0, 0.5 // Make color 0 50% transparent filter 5, 1.0 // Make color 5 100% transparent filter 8, 0.3 // Make color 8 30% transparent } You can give the entire image a filter value using "filter all VALUE". For example: image_map { gif "stnglass.gif" map_type 0 filter all 0.9 } NOTE: Transparency works by filtering light by its original color. Adding "filter" to the color black still leaves you with black no matter how high the filter value is. If you want a color to be clear, add filter 1 to the color white. 5.4.1.4.5 The "interpolate" option. Adding the "interpolate" keyword can smooths the jagged look of an image or bump map. When POV-Ray asks a color or bump amount for an image or bump map, it often asks for a point that is not directly on top of one pixel, but sort of between several different colored pixels. Interpolations returns an "in-between" value so that the steps between the pixels in the image or bump map will look smoother. There are currently two types of interpolation: Normalized Distance -- interpolate 4 Bilinear -- interpolate 2 Default is no interpolation. Normalized distance is the slightly faster of the two, bilinear does a better job of picking the between color. Normally, bilinear is used. If your bump or image map looks jaggy, try using interpolation instead of going to a higher resolution image. The results can be very good. For example: image_map { gif "mypic.gif" map_type 0 interpolate 2 } 5.4.1.5 Pigment Modifiers After specifying the pigment type such as marble, wood etc and adding an optional color map, you may add any of several modifiers. 5.4.1.5.1 Turbulence The keyword "turbulence" followed by a float or vector may be used to stir up the color pattern. Typical values range from the default 0.0 which is no turbulence to 1.0 which is very turbulent. If a vector is specified then different amounts of turbulence are applied in the x, y and z directions. For example "turbulence <1.0, 0.6, 0.1>" has much turbulence in the x direction, a moderate amount in the y direction and a small amount in the z direction. Turbulence uses a noise function called DNoise. This is sort of like noise used in the bozo pattern except that instead of giving a single value it gives a direction. You can think of it as the direction that the wind is blowing at that spot. Turbulence which uses DNoise to push a point around a few times. We locate the point we want to color (P), then push it around a bit using turbulence to get to a final point (Q) then look up the color of point Q in our ordinary boring textures. That's the color that's used for the point P. It in effect says "Don't give me the color at this spot... take a few random steps in a different direction and give me that color. Each step is typically half as long as the one before. For example: P -------------------------> First Move / / / /Second / Move / ______/ \ \ Q - Final point. The magnitude of these steps is controlled by the turbulence value. 5.4.1.5.2 Octaves The number of steps used by turbulence is controlled by the "octaves" value. The values may range from 1 up to 10. The default value of "octaves 6" is fairly close to the upper limit; you won't see much change by setting it to a higher value because the extra steps are too small. You can achieve some very interesting wavy effects by specifying lower values. Setting octaves higher can slow down rendering because more steps are computed. 5.4.1.5.3 Omega The keyword "omega" followed by a float value may be added to change the turbulence calculations. Each successive octave of turbulence is multiplied by the omega value. The default "omega 0.5" means that each octave is 1/2 the size of the previous one. Higher omega values mean that 2nd, 3rd, 4th and up octaves contribute more turbulence giving a sharper, "krinkly" look while smaller omegas give a fuzzy kind of turbulence that gets blury in places. 5.4.1.5.4 Lambda The lambda parameter controls how statistically different the random move of an octave is compared to its previous octave. The default value for this is "lambda 2". Values close to lambda 1.0 will straighten out the randomness of the path in the diagram above. Higher values can look more "swirly" under some circumstances. More tinkering by POV-Ray users may lead us to discover ways to make good use of this parameter. For now just tinker and enjoy. 5.4.1.5.5 Quick_color When developing POV-Ray scenes its often useful to do low quality test runs that render faster. The +Q command line switch can be used to turn off some time consuming color pattern and lighting calculations to speed things up. However all settings of +Q5 or lower turns off pigment calculations and creates gray objects. By adding a "quick_color" to a pigment you tell POV-Ray what solid color to use for quick renders instead of a patterned pigment. For example: pigment { gradient x color_map{ [0 color Yellow][0.3 color Cyan][0.6 color Magenta][1 color Cyan] } turbulence 0.5 lambda 1.5 omega 0.75 octaves 8 quick_color Neon_Pink } This tells POV-Ray to use solid Neon_Pink for test runs at quality +Q5 or lower but to use the turbulent gradient pattern for rendering at +Q6 and higher. Note that solid color pigments such as: pigment {color Magenta} automatically set the quick_color to that value. You may override this if you want. Suppose you have 10 spheres on the screen and all are Yellow. If you want to identify them individually you could give each a different quick_color like this: sphere {<1,2,3>,4 pigment {color Yellow quick_color Red}} sphere {<-1,-2,-3>,4 pigment {color Yellow quick_color Blue}} ...and so on. At +Q6 or higher they will all be Yellow but at +Q5 or lower each would be different colors so you could identify them. 5.4.1.5.6 Frequency and Phase The frequency and phase keywords were originally intended for the normal patterns ripples and waves discussed in the next section. With version 2.0 they were extended to pigments to make the radial and mandel pigment pattern easier to use. As it turned out it was simple to make them apply to any color map pattern. The frequency keyword adjusts the number of times that a color map repeats over one cycle of a pattern. For example gradient x covers color map values 0 to 1 over the range x=0 to x=1. By adding "frequency 2" the color map repeats twice over that same range. The same effect can be achieved using "scale x*0.5" so the frequency keyword isn't that useful for patterns like gradient. However the radial pattern wraps the color map around the +Y axis once. If you wanted two copies of the map (or 3 or 10 or 100) you'd have to build a bigger map. Adding "frequency 2" causes the color map to be used twice per revolution. Try this: sphere {<0,0,0>,3 pigment { radial color_map{[0.5 color Red][0.5 color White]} frequency 6 } rotate -x*90 } The result is 6 sets of red and white radial stripes evenly spaced around the sphere. Note "frequency -1" reverses the entries in a color_map. The phase keyword takes values from 0.0 to 1.0 and rotates the color map entries. In the example above if you render successive frames at phase 0 then phase 0.1, phase 0.2 etc you could create an animation that rotates the stripes. The same effect can be easily achieved by rotating the radial pigment using "rotate y*Angle" but there are other uses where phase can be handy. Sometimes you create a great looking gradient or wood color map but you want the grain slightly adjusted in or out. You could re-order the color map entries but that's a pain. A phase adjustment will shift everything but keep the same scale. Try animating a mandel pigment for a color palette rotation effect. 5.4.1.5.7 Transforming pigments You may modify pigment patterns with "translate", "rotate" and "scale" commands. Note that placing these transforms inside the texture but outside the pigment will transform the entire texture. However placing them inside the pigment transforms just the pigment. For example: sphere {<0,0,0>,3 texture { pigment { checker color Red color White scale <2,1,3> // affects pigment only... not normal } normal { bumps 0.3 scale 0.4 // affects bump normal only... not pigment } finish {Shiny} translate 5*x // affects entire texture } translate y*2 // affects object and texture } Note that transforms affect the entire pigment regardless of the ordering of other parameters. For example: This... ...is the same as this... pigment { pigment { bozo bozo turbulence 0.3 scale 2 scale 2 turbulence 0.3 } } The scaling before or after turbulence makes no difference. In general it is best to put all transformations last for the sake of clarity. 5.4.2 NORMAL Ray tracing is known for the dramatic way it depicts reflection, refraction and lighting effects. Much of our perception depends on the reflective properties of an object. Ray tracing can exploit this by playing tricks on our perception to make us see complex details that aren't really there. Suppose you wanted a very bumpy surface on the object. It would be very difficult to mathematically model lots of bumps. We can however simulate the way bumps look by altering the way light reflects off of the surface. Reflection calculations depend on a vector called a "surface normal" vector. This is a vector which points away from the surface and is perpendicular to it. By artificially modifying (or perturbing) this normal vector you can simulate bumps. The "normal {...}" statement is the part of a texture which defines the pattern of normal perturbations to be applied to an object. Like the pigment statement, you can omit the surrounding texture block to save typing. Do not forget however that there is a texture implied. For example... this... can be shortened to this... object { object { My_Object My_Object texture { pigment {color Purple} pigment {color Purple} normal {bumps 0.3} normal {bumps 0.3} } } } Note that attaching a normal pattern does not really modify the surface. It only affects the way light reflects or refracts at the surface so that it looks bumpy. The most complete form for defining a normal is as follows: normal { NORMAL_IDENTIFIER NORMAL_PATTERN_TYPE NORMAL_MODIFIERS TRANSFORMATIONS... } Each of the items in a normal are optional but if they are present, they should be in the order shown above to insure that the results are as expected. Any items after the NORMAL_IDENTIFIER modify or override settings given in the IDENTIFIER. If no identifier is specified then the items modify the normal values in the current default texture. TRANSFORMATIONs are translate, rotate and scale statements. They apply only to the normal and not to other parts of the texture. They should be specified last. There are 6 different NORMAL_PATTERN_TYPEs discussed below. They are bumps, dents, ripples, waves, wrinkles and bump_map. 5.4.2.1 Bumps A smoothly rolling random pattern of bumps can be created with the "bumps" normal pattern. Bumps uses the same random noise function as the bozo and spotted pigment patterns, but uses the derived value to perturb the surface normal or, in other words, make the surface look bumpy. This gives the impression of a "bumpy" surface, random and irregular, sort of like an orange. After the bumps keyword, you supply a single floating point value for the amount of surface perturbation. Values typically range from 0.0 (No Bumps) to 1.0 or greater (Extremely Bumpy). For example: sphere { <0, 1, 2>, 2 texture { pigment {color Yellow} normal {bumps 0.4 scale 0.2} finish {phong 1} } } This tells POV-Ray to use a bump pattern to modify the surface normal. The value 0.4 controls the apparent depth of the bumps. Usually the bumps are about 1 unit wide which doesn't work very well with a sphere of radius 2. The scale makes the bumps 1/5th as wide but does not affect their depth. 5.4.2.2 Dents The "dents" pattern is especially interesting when used with metallic textures, it gives impressions into the metal surface that look like dents have been beaten into the surface with a hammer. A single value is supplied after the dents keyword to indicate the amount of denting required. Values range from 0.0 (Showroom New) to 1.0 (Insurance Wreck). Scale the pattern to make the pitting more or less frequent. 5.4.2.3 Ripples The ripples bump pattern make a surface look like ripples of water. The ripples option requires a value to determine how deep the ripples are. Values range from 0.0 to 1.0 or more. The ripples radiate from 10 random locations inside the unit cube area <0,0,0> to <1,1,1>. Scale the pattern to make the centers closer or farther apart. The frequency keyword changes the spacing between ripples. The phase keyword can be used to move the ripples outwards for realistic animation. 5.4.2.4 Waves This works in a similar way to ripples except that it makes waves with different frequencies. The effect is to make waves that look more like deep ocean waves. The waves option requires a value to determine how deep the waves are. Values range from 0.0 to 1.0 or more. The waves radiate from 10 random locations inside the unit cube area <0,0,0> to <1,1,1>. Scale the pattern to make the centers closer or farther apart. The frequency keyword changes the spacing between waves. The phase keyword can be used to move the waves outwards for realistic animation. 5.4.2.5 Wrinkles This is sort of a 3-D bumpy granite. It uses a similar 1/f fractal noise function to perturb the surface normal in 3-D space. With a transparent color pattern, could look like wrinkled cellophane. Requires a single value after the wrinkles keyword to indicate the amount of wrinkling desired. Values from 0.0 (No Wrinkles) to 1.0 (Very Wrinkled) are typical. 5.4.2.6 Bump_map When all else fails and none of the above normal pattern types meets your needs, you can use a bump map to wrap a 2-D bit-mapped bump pattern around your 3-D objects. Instead of placing the color of the image on the shape like an image_map, bump_map perturbs the surface normal based on the color of the image at that point. The result looks like the image has been embossed into the surface. By default, bump_map uses the brightness of the actual color of the pixel. Colors are converted to gray scale internally before calculating height. Black is a low spot, white is a high spot. The image's index values may be used instead (see use_index) below. 5.4.2.6.1 Specifying a bump map. The syntax for bump_map is... normal { bump_map { FILE_TYPE "filename" MODIFIERS... } } Where FILE_TYPE is one of the following keywords "gif", "tga", "iff" or "dump". This is followed by the name of the file in quotes. Several optional modifiers may follow the file specification. The modifiers are described below. Note: Earlier versions of POV-Ray allowed some modifiers before the FILE_TYPE but that syntax is being phased out in favor of the syntax described here. Filenames specified in the bump_map statements will be searched for in the home (current) directory first, and if not found, will then be searched for in directories specified by any "-L" (library path) options active. This would facilitate keeping all your bump maps files in a separate subdirectory, and giving an "-L" option on the command line to where your library of bump maps are. By default, the bump is mapped onto the X-Y plane. The bump is "projected" onto the object as though there were a slide projector somewhere in the -Z direction. The bump exactly fills the square area from x,y coordinates (0,0) to (1,1) regardless of the bump's original size in pixels. If you would like to change this default, you may translate, rotate or scale the normal or texture to map it onto the object's surface as desired. If you would like to change this default orientation, you may translate, rotate or scale the normal or texture to map it onto the object's surface as desired. 5.4.2.6.2 Bump_size The relative bump_size can be scaled using bump_size modifier. The bump_size number can be any number other than 0. Valid numbers are 2, .5, -33, 1000, etc. For example: normal { bump_map { gif "stuff.gif" bump_size 5 } } 5.4.2.6.3 Use_index & use_color Usually the bump_map converts the color of the pixel in the map to a grayscale intensity value in the range 0.0 to 1.0 and calculates the bumps based on that value. If you specify use_index, bump_map uses the color's palette number to compute as the height of the bump at that point. So, color #0 would be low and color #255 would be high. The actual color of the pixels doesn't matter when using the index. The "use_color" keyword may be specified to explicitly note that the color methods should be used instead. 5.4.2.6.4 The "once" option. Normally there are an infinite number of repeating bump_maps created over every unit square of the X-Y plane like tiles. By adding the keyword "once" after a file name, you can eliminate all other copies of the bump_map except the one at (0,0) to (1,1). Areas outside this unit square are treated as fully transparent. Note: The "once" keyword may also be used with image_map and material_map statements. 5.4.2.6.5 The "map_type" option. The default projection of the bump onto the X-Y plane is called a "planar map type". This option may be changed by adding the "map_type" keyword followed by a number specifying the way to wrap the bump around the object. A "map_type 0" gives the default planar mapping already described. A "map_type 1" is a spherical mapping. It assumes that the object is a sphere of any size sitting at the origin. The Y axis is the north/south pole of the spherical mapping. The top and bottom edges of the bump_map just touch the pole regardless of any scaling. The left edge of the bump_map begins at the positive X axis and wraps the pattern around the sphere from "west" to "east" in a -Y rotation. The pattern covers the sphere exactly once. The "once" keyword has no meaning for this type. With "map_type 2" you get a cylindrical mapping. It assumes that a cylinder of any diameter lies along the Y axis. The bump pattern wraps around the cylinder just like the spherical map but remains 1 unit tall from y=0 to y=1. This band of bumps is repeated at all heights unless the "once" keyword is applied. Finally "map_type 5" is a torus or donut shaped mapping. It assumes that a torus of major radius 1 sits at the origin in the X-Z plane. The bump pattern is wrapped around similar to spherical or cylindrical maps. However the top and bottom edges of the map wrap over and under the torus where they meet each other on the inner rim. Types 3 and 4 are still under development. Note: The "map_type" option may also be applied to image_map and material_map statements. 5.4.2.6.6 The "interpolate" option. Adding the "interpolate" keyword can smooths the jagged look of a bump map. When POV-Ray asks bump amount for a bump map, it often asks for a point that is not directly on top of one pixel, but sort of between several different colored pixels. Interpolations returns an "in-between" value so that the steps between the pixels in the bump map will look smoother. There are currently two types of interpolation: Normalized Distance -- interpolate 4 Bilinear -- interpolate 2 Default is no interpolation. Normalized distance is the slightly faster of the two, bilinear does a better job of picking the between color. Normally, bilinear is used. If your bump map looks jaggy, try using interpolation instead of going to a higher resolution image. The results can be very good. 5.4.2.7 Normal Modifiers After specifying the normal type such as bumps, dents etc you may add any of several modifiers. 5.4.2.7.1 Turbulence The keyword "turbulence" followed by a float or vector may be used to stir up the color pattern. Typical values range from the default 0.0 which is no turbulence to 1.0 which is very turbulent. If a vector is specified then different amounts of turbulence is applied in the x, y and z directions. For example "turbulence <1.0, 0.6, 0.1>" has much turbulence in the x direction, a moderate amount in the y direction and a small amount in the z direction. A complete discussion of turbulence is given under Pigment Modifiers in section 5.4.1.5 above. The "octaves", "omega", and "lambda" options are also available as normal modifiers. They discussed under that section as well. 5.4.2.7.2 Frequency and Phase Both waves and ripples respond to a parameter called phase. The phase option allows you to create animations in which the water seems to move. This is done by making the phase increment slowly between frames. The range from 0.0 to 1.0 gives one complete cycle of a wave. The waves and ripples textures also respond to a parameter called frequency. If you increase the frequency of the waves, they get closer together. If you decrease it, they get farther apart. Bumps, dents, wrinkles and bump_map do not respond to frequency or phase. 5.4.2.7.3 Transforming normals You may modify normal patterns with "translate", "rotate" and "scale" commands. Note that placing these transforms inside the texture but outside the normal will transform the entire texture. However placing them inside the normal transforms just the normal. See section 5.4.1.5.7 Transforming Pigments for examples: 5.4.3 FINISH The finish properties of a surface can greatly affect its appearance. How does light reflect? What happens when light passes through? What kind of highlights are visible. To answer these questions you need a finish statement. The "finish {...}" statement is the part of a texture which defines the various finish properties to be applied to an object. Like the pigment or normal statement, you can omit the surrounding texture block to save typing. Do not forget however that there is a texture implied. For example... this... can be shortened to this... object { object { My_Object My_Object texture { pigment {color Purple} pigment {color Purple} finish {phong 0.3} finish {phong 0.3} } } } The most complete form for defining a finish is as follows: finish { FINISH_IDENTIFIER FINISH_ITEMS... } The FINISH_IDENTIFIER is optional but should proceed all other items. Any items after the FINISH_IDENTIFIER modify or override settings given in the IDENTIFIER. If no identifier is specified then the items modify the finish values in the current default texture. Note that transformations are not allowed inside a finish because finish items cover the entire surface uniformly. 5.4.3.1 Diffuse Reflection Items When light reflects off of a surface, the laws of physics say that it should leave the surface at the exact same angle it came in. This is similar to the way a billiard ball bounces off a bumper of a pool table. This perfect reflection is called "specular" reflection. However only very smooth polished surfaces reflect light in this way. Most of the time, light reflects and is scattered in all directions by the roughness of the surface. This scattering is called "diffuse reflection" because the light diffuses or spreads in a variety of directions. It accounts for the majority of the reflected light we see. In the real world, light may come from any of three possible sources. 1)It can come directly from actual light sources which are illuminating an object. 2)It can bounce from other objects such as mirrors via specular reflection. For example shine a flashlight onto a mirror. 3)It can bounce from other objects via diffuse reflections. Look at some dark area under a desk or in a corner. Even though a lamp may not directly illuminate that spot you can still see a little bit because light comes from diffuse reflection off of nearby objects. 5.4.3.1.1 Diffuse POV-Ray and most other ray tracers can only simulate directly, one of these three types of illumination. That is the light which comes directly from the light source which diffuses in all directions. The keyword "diffuse" is used in a finish statement to control how much light of this direct light is reflected via diffuse reflection. For example: finish {diffuse 0.7} means that 70% of the light seen comes from direct illumination from light sources. The default value is diffuse 0.6. 5.4.3.1.2 Brilliance The amount of direct light that diffuses from an object depends upon the angle at which it hits the surface. When light hits at a shallow angle it illuminates less. When it is directly above a surface it illuminates more. The "brilliance" keyword can be used in a finish statement to vary the way light falls off depending upon the angle of incidence. This controls the tightness of the basic diffuse illumination on objects and slightly adjusts the appearance of surface shininess. Objects may appear more metallic by increasing their brilliance. The default value is 1.0. Higher values from 3.0 to about 10.0 cause the light to fall off less at medium to low angles. There are no limits to the brilliance value. Experiment to see what works best for a particular situation. This is best used in concert with highlighting. 5.4.3.1.3 Crand Graininess Very rough surfaces, such as concrete or sand, exhibit a dark graininess in their apparent color. This is caused by the shadows of the pits or holes in the surface. The "crand" keyword can be added to cause a minor random darkening the diffuse reflection of direct illumination. Typical values range from "crand 0.01" to "crand 0.5" or higher. The default value is 0. For example: finish {crand 0.05} The grain or noise introduced by this feature is applied on a pixel-by- pixel basis. This means that it will look the same on far away objects as on close objects. The effect also looks different depending upon the resolution you are using for the rendering. For these reasons it is not a very accurate way to model the rough surface effect, but some objects still look better with a little crand thrown in. In previous versions of POV-Ray there was no "crand" keyword. Any lone float value found inside a texture{...} which was not preceded by a keyword was interpreted as a randomness value. NOTE: This should not be used when rendering animations. This is the one of a few truly random features in POV-Ray, and will produce an annoying flicker of flying pixels on any textures animated with a "crand" value. 5.4.3.1.4 Ambient The light you see in dark shadowed areas comes from diffuse reflection off of other objects. This light cannot be directly modeled using ray tracing. However we can use a trick called "ambient lighting" to simulate the light inside a shadowed area. Ambient light is light that is scattered everywhere in the room. It bounces all over the place and manages to light objects up a bit even where no light is directly shining. Computing real ambient light would take far too much time, so we simulate ambient light by adding a small amount of white light to each texture whether or not a light is actually shining on that texture. This means that the portions of a shape that are completely in shadow will still have a little bit of their surface color. It's almost as if the texture glows, though the ambient light in a texture only affects the shape it is used on. The default value is very little ambient light (0.1). The value can range from 0.0 to 1.0. Ambient light affects both shadowed and non-shadowed areas so if you turn up the ambient value you may want to turn down the diffuse value. Note that this method doesn't account for the color of surrounding objects. If you walk into a room that has red walls, floor and ceiling then your white clothing will look pink from the reflected light. POV-Ray's ambient shortcut doesn't account for this. There is also no way to model specular reflected indirect illumination such as the flashlight shining in a mirror. 5.4.3.2 Specular Reflection Items When light does not diffuse and it DOES reflect at the same angle as it hits an object, it is called "specular reflection". Such mirror-like reflection is controlled by the "reflection" keyword in a finish statement. For example: finish {reflection 1.0 ambient 0 diffuse 0} This gives the object a mirrored finish. It will reflect all other elements in the scene. The value can range from 0.0 to 1.0. By default there is no reflection. Adding reflection to a texture makes it take longer to render because an additional ray must be traced. NOTE: Although such reflection is called "specular" it is not controlled by the POV-Ray "specular" keyword. That keyword controls a "specular" highlight. 5.4.3.3 Highlights A highlights are the bright spots that appear when a light source reflects off of a smooth object. They are a blend of specular reflection and diffuse reflection. They are specular-like because they depend upon viewing angle and illumination angle. However they are diffuse-like because some scattering occurs. In order to exactly model a highlight you would have to calculate specular reflection off of thousands of microscopic bumps called micro facets. The more that micro facets are facing the viewer, the shinier the object appears, and the tighter the highlights become. POV-Ray uses two different models to simulate highlights without calculating micro facets. They are the specular and phong models. Note that specular and phong highlights are NOT mutually exclusive. It is possible to specify both and they will both take effect. Normally, however, you will only specify one or the other. 5.4.3.3.1 Phong Highlights The "phong" keyword controls the amount of Phong highlighting on the object. It causes bright shiny spots on the object that are the color of the light source being reflected. The Phong method measures the average of the facets facing in the mirror direction from the light sources to the viewer. Phong's value is typically from 0.0 to 1.0, where 1.0 causes complete saturation to the light source's color at the brightest area (center) of the highlight. The default phong 0.0 gives no highlight. The size of the highlight spot is defined by the phong_size value. The larger the phong_size, the tighter, or smaller, the highlight and the shinier the appearance. The smaller the phong_size, the looser, or larger, the highlight and the less glossy the appearance. Typical values range from 1.0 (Very Dull) to 250 (Highly Polished) though any values may be used. Default phong_size is 40 (plastic) if phong_size is not specified. For example: finish {phong 0.9 phong_size 60} If "phong" is not specified then "phong_size" has no effect. 5.4.3.3.2 Specular Highlight A specular highlight is very similar to Phong highlighting, but uses slightly different model. The specular model more closely resembles real specular reflection and provides a more credible spreading of the highlights occur near the object horizons. Specular's value is typically from 0.0 to 1.0, where 1.0 causes complete saturation to the light source's color at the brightest area (center) of the highlight. The default specular 0.0 gives no highlight. The size of the spot is defined by the value given for roughness. Typical values range from 1.0 (Very Rough -- large highlight) to 0.0005 (Very Smooth -- small highlight). The default value, if roughness is not specified, is 0.05 (Plastic). It is possible to specify "wrong" values for roughness that will generate an error when you try to render the file. Don't use 0 and if you get errors, check to see if you are using a very, very small roughness value that may be causing the error. For example: finish {specular 0.9 roughness 0.02} If "specular" is not specified then "roughness" has no effect. 5.4.3.3.3 Metallic Highlight Modifier The keyword "metallic" may be used with phong or specular highlights. This keyword indicates that the color of the highlights will be filtered by the surface color instead of directly using the light_source color. Note that the keyword has no numeric value after it. You either have it or you don't. For example: finish {phong 0.9 phong_size 60 metallic} If "phong" or "specular" is not specified then "metallic" has no effect. 5.4.3.4 Refraction When light passes through a surface either into or out of a dense medium, the path of the ray of light is bent. Such bending is called refraction. Normally transparent or semi-transparent surfaces in POV-Ray do not refract light. Adding "refraction 1.0" to the finish statement turns on refraction. Note: It is recommended that you only use "refraction 0" or "refraction 1". Values in between will darken the refracted light in ways that do not correspond to any physical property. Many POV-Ray scenes were created with intermediate refraction values before this "bug" was discovered so the "feature" has been maintained. A more appropriate way to reduce the brightness of refracted light is to change the "filter" value in the colors specified in the pigment statement. Note also that "refraction" does not cause the object to be transparent. Transparency is only occurs if there is a non-zero "filter" value in the color. The amount of bending or refracting of light depends upon the density of the material. Air, water, crystal, diamonds all have different density and thus refract differently. The "index of refraction" or "ior" value is used by scientists to describe the relative density of substances. The "ior" keyword is used in POV-Ray to specify the value. For example: texture { pigment { White filter 0.9 } finish { refraction 1 ior 1.5 } } The default ior value of 1.0 will give no refraction. The index of refraction for air is 1.0, water is 1.33, glass is 1.5, and diamond is 2.4. The file IOR.INC pre-defines several useful values for ior. NOTE: If a texture has a filter component and no value for refraction and ior are supplied, the renderer will simply transmit the ray through the surface with no bending. In layered textures, the refraction and ior keywords MUST be in the last texture, otherwise they will not take effect. 5.4.4 SPECIAL TEXTURES Most textures consist of a single pigment, normal and finish specification which applies to the entire surface. However two special textures have been implemented that extend the "checker" and "image_map" concepts to cover not just pigment but the entire texture. 5.4.4.1 Tiles This first special texture is the "tiles" texture. It works just like the "checker" pigment pattern except it colors the blocks with entire textures rather than solid colors. The syntax is: texture{ tiles { texture {... put in a texture here ... } tile2 texture {... this is the second tile texture } } // Optionally put translate, rotate or scale here } For example: texture{ tiles { texture { Jade } tile2 texture { Red_Marble } } } The textures used in each tile may be any type of texture including more tiles or regular textures made from pigment, normal and finish statements. Note that no other pigment, normal or finish statements may be added to the texture. This is illegal: texture { tiles { texture {T1} tile2 texture {T2} } finish {phong 1.0} } The finish must be individually added to each texture. Note that earlier versions of POV-Ray used only the pigment parts of the textures in the tiles. Normals and finish were ignored. Also layered textures were not supported. In order to correct these problems the above restrictions on syntax were necessary. This means some POV-Ray 1.0 scenes using tiles many need minor modifications that cannot be done automatically with the version compatibility mode. The textures within a tiles texture may be layered but tiles textures do don't work as part of a layered texture. 5.4.4.2 Material_Map The "material_map" special texture extends the concept of "image_map" to apply to entire textures rather than solid colors. A material_map allows you to wrap a 2-D bit-mapped texture pattern around your 3-D objects. Instead of placing a solid color of the image on the shape like an image_map, an entire texture is specified based on the index or color of the image at that point. You must specify a list of textures to be used like a "texture palette" rather than the usual color palette. When used with mapped file types such as GIF, the index of the pixel is used as an index into the list of textures you supply. For unmapped file types such as TGA, the 8 bit value of the red component in the range 0-255 is used as an index. If the index of a pixel is greater than the number of textures in your list then the index is taken modulo N where N is the length of your list of textures. 5.4.4.2.1 Specifying a material map. The syntax for material_map is... texture { material_map { FILE_TYPE "filename" MODIFIERS... texture {...} // First used for index 0 texture {...} // Second texture used for index 1 texture {...} // Third texture used for index 2 texture {...} // Fourth texture used for index 3 // and so on for however many used. } TRANSFORMATION... } If particular index values are not used in an image then it may be necessary to supply dummy textures. It may be necessary to use a paint program or other utility to examine the map file's palette to determine how to arrange the texture list. In the syntax above, FILE_TYPE is one of the following keywords "gif", "tga", "iff" or "dump". This is followed by the name of the file in quotes. Several optional modifiers may follow the file specification. The modifiers are described below. Note: Earlier versions of POV-Ray allowed some modifiers before the FILE_TYPE but that syntax is being phased out in favor of the syntax described here. Filenames specified in the material_map statements will be searched for in the home (current) directory first, and if not found, will then be searched for in directories specified by any "-L" (library path) options active. This would facilitate keeping all your material maps files in a separate subdirectory, and giving an "-L" option on the command line to where your library of material maps are. By default, the material is mapped onto the X-Y plane. The material is "projected" onto the object as though there were a slide projector somewhere in the -Z direction. The material exactly fills the square area from x,y coordinates (0,0) to (1,1) regardless of the material's original size in pixels. If you would like to change this default, you may translate, rotate or scale the normal or texture to map it onto the object's surface as desired. If you would like to change this default orientation, you may translate, rotate or scale the texture to map it onto the object's surface as desired. Note that no other pigment, normal or finish statements may be added to the texture outside the material_map. This is illegal: texture { material_map { gif "matmap.gif" texture {T1} texture {T2} texture {T3} } finish {phong 1.0} } The finish must be individually added to each texture. Note that earlier versions of POV-Ray allowed such specifications but they were ignored. The above restrictions on syntax were necessary for various bug fixes. This means some POV-Ray 1.0 scenes using material_maps many need minor modifications that cannot be done automatically with the version compatibility mode. The textures within a material_map texture may be layered but material_map textures do don't work as part of a layered texture. To use a layered texture inside a material_map you must declare it as a texture identifier and invoke it in the texture list. 5.4.4.2.2 Material_map options. The "once" and "map_type" options may be used with material_maps exactly like image_map or bump_map. The "interpolate" keyword also is allowed but it interpolates the map indices rather than the colors. In most cases this results in a worse image instead of a better image. Future versions will fix this problem. 5.4.5 LAYERED TEXTURES It is possible to create a variety of special effects using layered textures. A layered texture is one where several textures that are partially transparent are laid one on top of the other to create a more complex texture. The different texture layers show through the transparent portions to create the appearance of one texture that is a combination of several textures. You create layered textures by listing two or more textures one right after the other. The last texture listed will be the top layer, the first one listed will be the bottom layer. All textures in a layered texture other than the bottom layer should have some transparency. For example: object { My_Object texture {T1} // the bottom layer texture {T2} // a semi-transparent layer texture {T3} // the top semi-transparent layer } In this example T2 shows only where T3 is transparent and T1 shows only where T2 and T3 are transparent. The color of underlying layers is filtered by upper layers but the results do not look exactly like a series of transparent surfaces. If you had a stack of surfaces with the textures applied to each, the light would be filtered twice: once on the way in as the lower layers are illuminated by filtered light and once on the way out. Layered textures do not filter the illumination on the way in. Other parts of the lighting calculations work differently as well. The result look great and allow for fantastic looking textures but they are simply different from multiple surfaces. See STONES.INC in the standard include files for some magnificent layered textures. Note layered textures must use the "texture{...}" wrapped around any pigment, normal or finish statements. Do not use multiple pigment, normal or finish statements without putting them inside the texture statement. Layered textures may be declared. For example: #declare Layered_Examp= texture {T1} texture {T2} texture {T3} Then invoke it as follows: object { My_Object texture { Layer_Examp // Any pigment, normal or finish here // modifies the bottom layer only. } } 5.4.6 DEFAULT TEXTURE POV-Ray creates a default texture when it begins processing. You may change those defaults as described below. Every time you specify a "texture{...}" statement, POV-Ray creates a copy of the default texture. Anything items you put in the texture statement override the default settings. If you attach a pigment, normal or finish to an object without any texture statement then POV-Ray checks to see if a texture has already been attached. If it has a texture then the pigment, normal or finish will modify that existing texture. If no texture has yet been attached to the object then the default texture is copied and the pigment, normal or finish will modify that texture. You may change the default texture, pigment, normal or finish using the language directive "#default {...}" as follows: #default { texture { pigment {...} normal {...} finish {...} } } Or you may change just part of it like this: #default { pigment {...} } This still changes the pigment of the default texture. At any time there is only one default texture made from the default pigment, normal and finish. The example above does not make a separate default for pigments alone. Note: Special textures tiles and material_map may not be used as defaults. You may change the defaults several times throughout a scene as you wish. Subsequent #default statements begin with the defaults that were in effect at the time. If you wish to reset to the original POV-Ray defaults then you should first save them as follows: //At top of file #declare Original_Default = texture {} later after changing defaults you may restore it with... #default {texture {Original_Default}} If you do not specify a texture for an object then the default texture is attached when the object appears in the scene. It is not attached when an object is declared. For example: #declare My_Object= sphere{<0,0,0>,1} // Default texture not applied object{My_Object} // Default texture added here You may force a default texture to be added by using an empty texture statement as follows: #declare My_Thing= sphere{<0,0,0>,1 texture{}} // Default texture applied The original POV-Ray defaults for all items are given throughout the documentation under each appropriate section. 5.5 CAMERA ------------ Every scene in POV-Ray has a camera defined. If you do not specify a camera then a default camera is used. The camera definition describes the position, angle and properties of the camera viewing the scene. POV-Ray uses this definition to do a simulation of the camera in the ray tracing universe and "take a picture" of your scene. The camera simulated in POV-Ray is a pinhole camera. Pinhole cameras have a fixed focus so all elements of the scene will always be perfectly in focus. The pinhole camera is not able to do soft focus or depth of field effects. A total of 6 vectors may be specified to define the camera but only a few of those are needed to in most cases. Here is an introduction to simple camera placement. 5.5.1 LOCATION AND LOOK_AT Under many circumstances just two vectors in the camera statement are all you need: location and look_at. For example: camera { location <3,5,-10> look_at <0,2,1> } The location is simply the X, Y, Z coordinates of the camera. The camera can be located anywhere in the ray tracing universe. The default location is <0,0,0>. The look_at vector tells POV-Ray to pan and tilt the camera until it is looking at the specified X, Y, Z coordinate. By default the camera looks at a point one unit in the +Z direction from the location. The look_at specification should almost always be the LAST item in the camera statement. If other camera items are placed after the look_at vector then the camera may not continue to look at the specified point. 5.5.2 THE SKY VECTOR Normally POV-Ray pans left or right by rotating about the Y axis until it lines up with the look_at point and then tilts straight up or down until the point is met exactly. However you may want to slant the camera sideways like an airplane making a banked turn. You may change the tilt of the camera using the "sky" vector. For example: camera { location <3,5,-10> sky <1,1,0> look_at <0,2,1> } This tells POV-Ray to roll the camera until the top of the camera is in line with the sky vector. Imagine that the sky vector is an antenna pointing out of the top of the camera. Then it uses the "sky" vector as the axis of rotation left or right and then to tilt up or down in line with the "sky" vector. In effect you're telling POV-Ray to assume that the sky isn't straight up. Note that the sky vector must appear before the look_at vector. The sky vector does nothing on its own. It only modifies the way the look_at vector turns the camera. The default value for sky is <0,1,0>. 5.5.3 THE DIRECTION VECTOR The "direction" vector serves two purposes. It tells POV-Ray the initial direction to point the camera before moving it with look_at or rotate vectors. It also controls the field of view. Note that this is only the initial direction. Normally, you will use the look_at keyword, not the direction vector to point the camera in its actual direction. The length of the direction vector tells POV-Ray to use a telephoto or wide-angle view. It is the distance from the camera location to the imaginary "view window" that you are looking through. A short direction vector gives a wide angle view while a long direction gives a narrow, telephoto view. This figure illustrates the effect: |\ |\ | \ | \ | \ | \ | \ | \ Location | | Location | | *------------> | *-------------------------->| Direction| | | | | | | | | | | | \ | \ | \ | \ | \| \| Short direction gives wide view... long direction narrows view. The default value is "direction <0,0,1>". Be careful with short direction vector lengths like 1.0 and less. You may experience distortion on the edges of your images. Objects will appear to be shaped strangely. If this happens, move the location back and make the direction vector longer. Wide angle example: camera { location <3,5,-10> direction <0,0,1> look_at <0,2,1> } Zoomed in telephoto example: camera { location <3,5,-10> direction <0,0,8> look_at <0,2,1> } 5.5.4 UP AND RIGHT VECTORS The "up" vector defines the height of the view window. The "right" vector defines the width of the view window. This figure illustrates the relationship of these vectors: -------------------------- | ^ | | up <0,1,0>| | | | | | | | | | | | | | | | | |------------------------->| | right<1.33,0,0> | | | | | | | | | | | | | | | | | | | -------------------------- 5.5.4.1 Aspect Ratio Together these vectors define the "aspect ratio" (height to width ratio) of the resulting image. The default values "up <0,1,0>" and "right <1.33,0,0>" results in an aspect ratio of about 4 to 3. This is the aspect ratio of a typical computer monitor. If you wanted a tall skinny image or a short wide panoramic image or a perfectly square image then you should adjust the up and right vectors to the appropriate proportions. Most computer video modes and graphics printers use perfectly square pixels. For example Macintosh displays and IBM S-VGA modes 640x480, 800x600 and 1024x768 all use square pixels. When your intended viewing method uses square pixels then the width and height you set with the +W and +H switches should also have the same ratio as the right and up vectors. Note that 640/480=4/3 so the ratio is proper for this square pixel mode. Not all display modes use square pixels however. For example IBM VGA mode 320x200 and Amiga 320x400 modes do not use square pixels. These two modes still produce a 4/3 aspect ratio image. Therefore images intended to be viewed on such hardware should still use 4/3 ratio on their up & right vectors but the +W and +H settings will not be 4/3. For example: camera { location <3,5,-10> up <0,1,0> right <1,0,0> look_at <0,2,1> } This specifies a perfectly square image. On a square pixel display like SVGA you would use +W and +H settings such as +W480 +H480 or +W600 +H600. However on the non-square pixel Amiga 320x400 mode you would want to use values of +W240 +H400 to render a square image. 5.5.4.2 Handedness The "right" vector also describes the direction to the right of the camera. It tells POV-Ray where the right side of your screen is. The sign of the right vector also determines the "handedness" of the coordinate system in use. The default right statement is: right <1.33, 0, 0> This means that the +X direction is to the right. It is called a "left- handed" system because you can use your left hand to keep track of the axes. Hold out your left hand with your palm facing to your right. Stick your thumb up. Point straight ahead with your index finger. Point your other fingers to the right. Your bent fingers are pointing to the +X direction. Your thumb now points +Y. Your index finger points +Z. To use a right-handed coordinate system, as is popular in some CAD programs and other ray tracers, make the same shape using your right hand. Your thumb still points up in the +Y direction and your index finger still points forward in the +Z direction but your other fingers now say the +X is to the left. That means that the "right" side of your screen is now in the -X direction. To tell POV-Ray to compensate for this you should use a negative X value in the "right" vector like this: right <-1.33, 0, 0> Some CAD systems, like AutoCAD, also have the assumption that the Z axis is the "elevation" and is the "up" direction instead of the Y axis. If this is the case you will want to change your "up" and "direction" as well. Note that the up, right, and direction vectors must always remain perpendicular to each other or the image will be distorted. 5.5.5 TRANSFORMING THE CAMERA The "translate" and "rotate" commands can re-position the camera once you've defined it. For example: camera { location < 0, 0, 0> direction < 0, 0, 1> up < 0, 1, 0> right < 1, 0, 0> rotate <30, 60, 30> translate < 5, 3, 4> } In this example, the camera is created, then rotated by 30 degrees about the X axis, 60 degrees about the Y axis, and 30 degrees about the Z axis, then translated to another point in space. 5.5.6 CAMERA IDENTIFIERS You may declare several camera identifiers if you wish. This makes it easy to quickly change cameras. For example: #declare Long_Lens= camera { location -z*100 direction z*50 } #declare Short_Lens= camera { location -z*50 direction z*10 } camera { Long_Lens //edit this line to change lenses look_at Here } 5.6 MISC FEATURES ------------------- Here are a variety of other topics about POV-Ray features. 5.6.1 FOG POV-Ray includes the ability to render fog. To add fog to a scene, place the following declaration outside of any object definitions: fog { color Gray70 // the fog color distance 200.0 // distance for 100% fog color } The fog color is then blended into the current pixel color at a rate calculated as: 1-exp(-depth/distance) = 1-exp(-200/200) = 1-exp(-1) = 1-.37... = 0.63... So at depth 0, the color is pure (1.0) with no fog (0.0). At the fog distance, you'll get 63% of the color from the object's color and 37% from the fog color. Subtle use of fog can add considerable realism and depth cuing to a scene without adding appreciably to the overall rendering times. Using a black or very dark gray fog can be used to simulate attenuated lighting by darkening distant objects. 5.6.2 MAX_TRACE_LEVEL The "#max_trace_level" directive sets a variable that defines how many levels that POV-Ray will trace a ray. This is used when a ray is reflected or is passing through a transparent object. When a ray hits a reflective surface, it spawns another ray to see what that point reflects, that's trace level 1. If it hits another reflective surface, then another ray is spawned and it goes to trace level 2. The maximum level by default is 5. If max trace level is reached before a non-reflecting surface is found, then the color is returned as black. Raise max_trace_level if you see black in a reflective surface where there should be a color. The other symptom you could see is with transparent objects. For instance, try making a union of concentric spheres with the Cloud_Sky texture on them. Make ten of them in the union with radius's from 1-10 then render the Scene. The image will show the first few spheres correctly, then black. This is because a new level is used every time you pass through a transparent surface. Raise max_trace_level to fix this problem. For example: #max_trace_level 20 Note: Raising max_trace_level will use more memory and time and it could cause the program to crash with a stack overflow error. Values for max_trace_level are not restricted, so it can be set to any number as long as you have the time and memory. 5.6.3 MAX_INTERSECTIONS POV-Ray uses a set of internal stacks to collect ray/object intersection points. The usual maximum number of entries in these "I-Stacks" is 64. Complex scenes may cause these stacks to overflow. POV-Ray doesn't stop but it may incorrectly render your scene. When POV-Ray finishes rendering, a number of statistics are displayed. If you see "I-Stack Overflows" reported in the statistics, you should increase the stack size. Add a directive to your scene as follows: #max_intersections 200 If the "I-Stack Overflows" remain, increase this value until they stop. 5.6.4 BACKGROUND A background color can be specified if desired. Any ray that doesn't hit an object will be colored with this color. The default background is black. The syntax for background is: background { color SkyBlue } Using a colored background takes up no extra time for the ray tracer, making it a very economical, although limited, feature. Only solid colors can be specified for a background. Textures cannot be used. No shadows will be cast on it, which makes it very useful, but at the same time, it has no "roundness", or shading, and can sometimes cause a scene to look "flat". Use background with restraint. It's often better, although a bit slower, to use a "sky sphere", but there are times when a solid background is just what you need. 5.6.5 THE #VERSION DIRECTIVE Although POV-Ray 2.0 has had significant changes to the language over POV- Ray 1.0, almost all 1.0 scenes will still work if the compatibility mode is set to 1.0. The +MV switch described earlier, sets the initial mode. The default is +MV2.0. Inside a scene file you may turn compatibility off or on using the "#version" directive. For example: #version 1.0 // Put some version 1.0 statements here #version 2.0 // Put some version 2.0 statements here Note you may not change versions inside an object or declaration. The primary purpose of the switch is to turn off float and expression parsing so that commas are not needed. It also turns off some warning messages. Note some changes in tiles and material_maps cannot be fixed by turning the version compatibility on. It may require hand editing of those statements. See the special texture section for details. Future versions of POV-Ray may not continue to maintain full backward compatibility. We strongly encourage you to phase in 2.0 syntax as much as possible. APPENDIX A COMMON QUESTIONS AND ANSWERS ======================================== Q: I get a floating point error on certain pictures. What's wrong? A: The ray tracer performs many thousands of floating point operations when tracing a scene. If checks were added to each one for overflow or underflow, the program would be much slower. If you get this problem, first look through your scene file to make sure you're not doing something like: - Scaling something by 0 in any dimension. Ex: scale <34, 2, 0> will generate a warning. - Making the look_at point the same as the location in the camera - Looking straight down at the look_at point - Defining triangles with two points the same (or nearly the same) - Using a roughness value of zero (0). If it doesn't seem to be one of these problems, please let us know. If you do have such troubles, you can try to isolate the problem in the input scene file by commenting out objects or groups of objects until you narrow it down to a particular section that fails. Then try commenting out the individual characteristics of the offending object. Q: Are planes 2D objects or are they 3D but infinitely thin? A: Neither. Planes are 3D objects that divide the world into two half- spaces. The space in the direction of the surface normal is considered outside and the other space is inside. In other words, planes are 3D objects that are infinitely thick. For the plane, plane { y, 0 }, every point with a positive Y value is outside and every point with a negative Y value is inside. ^ | | | Outside _______|_______ Inside Q: I'd like to go through the program and hand-optimize the assembly code in places to make it faster. What should I optimize? A: Don't bother. With hand optimization, you'd spend a lot of time to get perhaps a 5-10% speed improvement at the cost of total loss of portability. If you use a better ray-surface intersection algorithm, you should be able to get an order of magnitude or more improvement. Check out some books and papers on ray tracing for useful techniques. Specifically, check out "Spatial Subdivision" and "Ray Coherence" techniques. Q: Objects on the edges of the screen seem to be distorted. Why? A: If the direction vector of the camera is not very long, you may get distortion at the edges of the screen. Try moving the location back and raising the value of the direction vector. Q: How do you position planar image maps without a lot of trial and error? A: By default, images will be mapped onto the range 0,0 to 1,1 in the appropriate plane. You should be able to translate, rotate, and scale the image from there. Q: How do you calculate the surface normals for smooth triangles? A: There are two ways of getting another program to calculate them for you. There are now several utilities to help with this. 1) Depending on the type of input to the program, you may be able to calculate the surface normals directly. For example, if you have a program that converts B-Spline or Bezier Spline surfaces into POV-Ray format files, you can calculate the surface normals from the surface equations. 2) If your original data was a polygon or triangle mesh, then it's not quite so simple. You have to first calculate the surface normals of all the triangles. This is easy to do - you just use the vector cross-product of two sides (make sure you get the vectors in the right order). Then, for every vertex, you average the surface normals of the triangles that meet at that vertex. These are the normals you use for smooth triangles. Look for the utilities such as RAW2POV. RAW2POV has an excellent bounding scheme and the ability to specify a smoothing threshold. Q: When I render parts of a picture on different systems, the textures don't match when I put them together. Why? A: The appearance of a texture depends on the particular random number generator used on your system. POV-Ray seeds the random number generator with a fixed value when it starts, so the textures will be consistent from one run to another or from one frame to another so long as you use the same executables. Once you change executables, you will likely change the random number generator and, hence, the appearance of the texture. There is an example of a standard ANSI random number generator provided in IBM.C, include it in your machine-specific code if you are having consistency problems. Q: I created an object that passes through its bounding volume. At times, I can see the parts of the object that are outside the bounding volume. Why does this happen? A: Bounding volumes are not designed to change the shape of the object. They are strictly a realtime improvement feature. The ray tracer trusts you when you say that the object is enclosed by a bounding volume. The way it uses bounding volumes is very simple: If the ray hits the bounding volume (or the ray's origin is inside the bounding volume),when the object is tested against that ray. Otherwise, we ignore the object. If the object extends beyond the bounding volume, anything goes. The results are undefined. It's quite possible that you could see the object outside the bounding volume and it's also possible that it could be invisible. It all depends on the geometry of the scene. If you want this effect use a clipped_by volume instead of bounded_by or use clipped_by { bounded_by } if you wish to clip and bound with the same object. APPENDIX B TIPS AND HINTS ========================== B.1 SCENE DESIGN ------------------ There are a number of excellent shareware CAD style modelers available on the DOS platform now that will create POV-Ray scene files. The online systems mentioned elsewhere in this document are the best places to find these. Hundreds of special-purpose utilities have been written for POV-Ray; data conversion programs, object generators, shell-style "launchers", and more. It would not be possible to list them all here, but again, the online systems listed will carry most of them. Most, following the POV-Ray spirit, are freeware or inexpensive shareware. Some extremely elaborate scenes have been designed by drafting on graph paper. Raytracer Mike Miller recommends graph paper with a grid divided in tenths, allowing natural decimal conversions. Start out with a "boilerplate" scene file, such as a copy of BASICVUE.POV, and edit that. In general, place your objects near and around the "origin" (0, 0, 0) with the camera in the negative z direction, looking at the origin. Naturally, you will break from this rule many times, but when starting out, keep things simple. For basic, boring, but dependable lighting, place a light source at or near the position of the camera. Objects will look flat, but at least you will see them. From there, you can move it slowly into a better position. B.2 SCENE DEBUGGING TIPS -------------------------- To see a quick version of your picture, render it very small. With fewer pixels to calculate the ray tracer can finish more quickly. -w160 -h100 is a good size. Use the +Q "quality" switch when appropriate. If there is a particular area of your picture that you need to see in high resolution, perhaps with anti-aliasing on (perhaps a fine-grained wood texture), use the +SC, +EC. +SR, and +ER switches to isolate a "window". If your image contains a lot of inter-reflections, set max_trace_level to a low value such as 1 or 2. Don't forget to put it back up when you're finished! "Turn off" any unnecessary lights. Comment out extended light and spotlight keywords when not needed for debugging. Again, don't forget to put them back in before you retire for the night with a final render running! If you've run into an error that is eluding you by visual examination, it's time to start bracketing your file. Use the block comment characters ( /* ... */ ) to disable most of your scene and try to render again. If you no longer get an error, the problem naturally lies somewhere within the disabled area. Slow and methodical testing like this will eventually get you to a point where you will either be able to spot the bug, or go quietly insane. Maybe both. If you seem to have "lost" yourself or an object (a common experience for beginners) there are a few tricks that can sometimes help: 1) Move your camera way back to provide a long range view. This may not help with very small objects which tend to be less visible at a distance, but it's a nice trick to keep up your sleeve. 2) Try setting the ambient value to 1.0 if you suspect that the object may simply be hidden from the lights. This will make it self-illuminated and you'll be able to see it even with no lights in the scene. 3) Replace the object with a larger, more obvious "stand-in" object like a large sphere or box. Be sure that all the same transformations are applied to this new shape so that it ends up in the same spot. B.3 ANIMATION --------------- When animating objects with solid textures, the textures must move with the object, i.e. apply the same rotate or translate functions to the texture as to the object itself. This is now done automatically if the transformations are placed _after_ the texture block. Example: shape { ... pigment { ... } scale < ... > } Will scale the shape and pigment texture by the same amount. While: shape { ... scale < ... > pigment { ... } } Will scale the shape, but not the pigment. Constants can be declared for most of the data types in the program including floats and vectors. By writing these to #include files, you can easily separate the parameters for an animation into a separate file. Some examples of declared constants would be: #declare Y_Rotation = 5.0 * clock #declare ObjectRotation = <0, Y_Rotation, 0> #declare MySphere = sphere { <0, 0, 0>, 1.1234 } Other examples can be found scattered throughout the sample scene files. DOS users: Get ahold of DTA.EXE (Dave's Targa Animator) for creating .FLI/.FLC animations. AAPLAY.EXE and PLAY.EXE are common viewers for this type of file. When moving the camera in an animation (or placing one in a still image, for that matter) avoid placing the camera directly over the origin. This will cause very strange errors. Instead, move off center slightly and avoid hovering directly over the scene. B.4 TEXTURES -------------- Wood is designed like a "log", with growth rings aligned along the z axis. Generally these will look best when scaled down by about a tenth (to a unit-sized object). Start out with rather small value for the turbulence, too (around 0.05 is good for starters). The marble texture is designed around a pigment primitive that is much like an x-gradient. When turbulated, the effect is different when viewed from the "side" or from the "end". Try rotating it by 90 degrees on the y axis to see the difference. You cannot get specular highlights on a totally black object. Try using a very dark gray, say Gray10 or Gray15, instead. B.5 HEIGHT FIELDS ------------------- Try using POV-Ray itself to create images for height_fields: camera { location <0, 0, -2> } plane { z, 0 finish { ambient 1 } // needs no light sources pigment { bozo } // or whatever. Experiment. } That's all you'll need to create a .tga file that can then be used as a height field in another image! B.6 FIELD-OF-VIEW ------------------- By making the direction vector in the camera longer, you can achieve the effect of a tele-photo lens. Shorter direction vectors will give a kind of wide-angle affect, but you may see distortion at the edges of the image. See the file "fov.inc" in the \POVRAY\INCLUDE directory for some predefined field-of-view values. If your spheres and circles aren't round, try increasing the direction vector slightly. Often a value of 1.5 works better than the 1.0 default when spheres appear near the edge of the screen. B.7 CONVERTING "HANDEDNESS" ----------------------------- If you are importing images from other systems, you may find that the shapes are backwards (left-to-right inverted) and no rotation can make them correct. Often, all you have to do is negate the terms in the right vector of the camera to flip the camera left-to-right (use the "right-hand" coordinate system). Some programs seem to interpret the coordinate systems differently, however, so you may need to experiment with other camera transformations if you want the y and z vectors to work as POV-Ray does. APPENDIX C SUGGESTED READING ============================= First, a shameless plug for two books that are specifically about POV-Ray: The Waite Group's Ray Tracing Creations By Drew Wells & Chris Young ISBN 1-878739-27-1 Waite Group Press 1993 and The Waite Group's Image Lab By Tim Wegner ISBN 1-878739-11-5 Waite Group Press 1992 Image Lab by Tim Wegner contains a chapter about POV-Ray. Tim is the co- author of the best selling book, Fractal Creations, also from the Waite Group. Ray Tracing Creations by Drew Wells and Chris Young is an entire book about ray tracing with POV-Ray. This section lists several good books or periodicals that you should be able to locate in your local computer book store or your local university library. "An Introduction to Ray tracing" Andrew S. Glassner (editor) ISBN 0-12-286160-4 Academic Press 1989 "3D Artist" Newsletter ("The Only Newsletter about Affordable PC 3D Tools and Techniques") Publisher: Bill Allen P.O. Box 4787 Santa Fe, NM 87502-4787 (505) 982-3532 "Image Synthesis: Theory and Practice" Nadia Magnenat-Thalman and Daniel Thalmann Springer-Verlag 1987 "The RenderMan Companion" Steve Upstill Addison Wesley 1989 "Graphics Gems" Andrew S. Glassner (editor) Academic Press 1990 "Fundamentals of Interactive Computer Graphics" J. D. Foley and A. Van Dam ISBN 0-201-14468-9 Addison-Wesley 1983 "Computer Graphics: Principles and Practice (2nd Ed.)" J. D. Foley, A. van Dam, J. F. Hughes ISBN 0-201-12110-7 Addison-Wesley, 1990 "Computers, Pattern, Chaos, and Beauty" Clifford Pickover St. Martin's Press "SIGGRAPH Conference Proceedings" Association for Computing Machinery Special Interest Group on Computer Graphics "IEEE Computer Graphics and Applications" The Computer Society 10662, Los Vaqueros Circle Los Alamitos, CA 90720 "The CRC Handbook of Mathematical Curves and Surfaces" David von Seggern CRC Press 1990 "The CRC Handbook of Standard Mathematical Tables" CRC Press The Beginning of Time APPENDIX D LEGAL INFORMATION ============================= The following is legal information pertaining to the use of the Persistence of Vision Ray Tracer a.k.a POV-Ray. It applies to all POV-Ray source files, executable (binary) files, scene files, documentation files contained in the official POV archives. (Certain portions refer to custom versions of the software, there are specific rules listed below for these versions also.) All of these are referred to here as "the software". THIS NOTICE MUST ACCOMPANY ALL OFFICIAL OR CUSTOM PERSISTENCE OF VISION FILES. IT MAY NOT BE REMOVED OR MODIFIED. THIS INFORMATION PERTAINS TO ALL USE OF THE PACKAGE WORLDWIDE. THIS DOCUMENT SUPERSEDES ALL PREVIOUS LICENSES OR DISTRIBUTION POLICIES. IMPORTANT LEGAL INFORMATION Permission is granted to the user to use the Persistence of Vision Raytracer and all associated files in this package to create and render images. The use of this software for the purpose of creating images is free. The creator of a scene file and the image created from the scene file, retains all rights to the image and scene file they created and may use them for any purpose commercial or non-commercial. The user is also granted the right to use the scenes files and include files distributed in the INCLUDE and DEMO sub-directories of the POVDOC archive when creating their own scenes. Such permission does not extend to files in the POVSCN archive. POVSCN files are for your enjoyment and education but may not be the basis of any derivative works. This software package and all of the files in this archive are copyrighted and may only be distributed and/or modified according to the guidelines listed below. The spirit of the guidelines below is to promote POV-Ray as a standard ray tracer, provide the full POV-Ray package freely to as many users as possible, prevent POV-Ray users and developers from being taken advantage of, enhance the life quality of those who come in contact with POV-Ray. This legal document was created so these goals could be realized. You are legally bound to follow these rules, but we hope you will follow them as a matter of ethics, rather than fear of litigation. No portion of this package may be separated from the package and distributed separately other than under the conditions specified in the guidelines below. This software may be bundled in other software packages according to the conditions specified in the guidelines below. This software may be included in software-only compilations using media such as, but not limited to, floppy disk, CD-ROM, tape backup, optical disks, hard disks, or memory cards. There are specific rules and guidelines listed below for the provider to follow in order to legally offer POV-Ray with a software compilation. The user is granted the privilege to modify and compile the source for their own personal use in any fashion they see fit. What you do with the software in your own home is your business. If the user wishes to distribute a modified version of the software (here after referred to as a "custom version") they must follow the guidelines listed below. These guidelines have been established to promote the growth of POV-Ray and prevent difficulties for users and developers alike. Please follow them carefully for the benefit of all concerned when creating a custom version. You may not incorporate any portion of the POV-Ray source code in any software other than a custom version of POV-Ray. However authors who contribute source to POV-Ray may still retain all rights to use their contributed code for any purpose as described below. The user is encouraged to send enhancements and bug fixes to the POV-Team, but the team is in no way required to utilize these enhancements or fixes. By sending material to the POV-Team, the contributor asserts that he owns the materials or has the right to distribute these materials. He authorizes the POV-Team to use the materials any way they like. The contributor still retains rights to the donated material, but by donating you grant equal rights to the POV-Team. The POV-Team doesn't have to use the material, but if we do, you do not acquire any rights related to POV- Ray. We will give you credit if applicable. GENERAL RULES FOR ALL DISTRIBUTION The permission to distribute this package under certain very specific conditions is granted in advance, provided that the above and following conditions are met. These archives must not be re-archived using a different method without the explicit permission of the POV-Team. You may rename the archives only to meet the file name conventions of your system or to avoid file name duplications but we ask that you try to keep file names as similar to the originals as possible. (For example:POVDOC.ZIP to POVDOC20.ZIP) You must distribute a full package of archives as described in the next section. Non-commercial distribution (such as a user copying the software for a personal friend or colleague and not charging money or services for that copy) has no other restrictions. This does not include non-profit organizations or computer clubs. These groups should use the Shareware/Freeware distribution company rules below. The POV-Team reserves the right to withdraw distribution privileges from any group, individual, or organization for any reason. DEFINITION OF "FULL PACKAGE" POV-Ray is contained in 4 archives for each hardware platform. 1) An executable archive, 2) A documentation archive, 3) Sample scene archives, 4) Source code archive. A "full package" is defined as one of the following bundle options: 1 All archives (executable, docs, scenes, source) 2 User archives (executable, docs, scenes but no source) 3 Programmer archives (source, docs, scenes but no executable) POV-Ray is officially distributed for IBM-PC compatibles running MS-Dos; Apple Macintosh; and Commodore Amiga. Other systems may be added in the future. Distributors need not support all platforms but for each platform you support you must distribute a full package. For example an IBM-only BBS need not distribute the Mac versions. CONDITIONS FOR DISTRIBUTION OF CUSTOM VERSIONS You may distribute custom compiled versions only if you comply with the following conditions. Mark your version clearly on all modified files stating this to be a modified and unofficial version. Make all of your modifications to POV-Ray freely and publicly available. You must provide all POV-Ray support for all users who use your custom version. The POV-Ray Team is not obligated to provide you or your users any technical support. You must provide documentation for any and all modifications that you have made to the program that you are distributing. Include clear and obvious information on how to obtain the official POV-Ray. Include contact and support information for your version. Include this information in the DISTRIBUTION_MESSAGE macros in the source file FRAME.H and insure that the program prominently displays this information. Include all credits and credit screens for the official version. Include a copy of this document. CONDITIONS FOR COMMERCIAL BUNDLING Vendors wishing to bundle POV-Ray with commercial software or with publications must first obtain explicit permission from the POV-Ray Team. This includes any commercial software or publications, such as, but not limited to, magazines, books, newspapers, or newsletters in print or machine readable form. The POV-Ray Team will decide if such distribution will be allowed on a case-by-case basis and may impose certain restrictions as it sees fit. The minimum terms are given below. Other conditions may be imposed. Purchasers of your product must not be led to believe that they are paying for POV-Ray. Any mention of the POV-Ray bundle on the box, in advertising or in instruction manuals must be clearly marked with a disclaimer that POV-Ray is free software and can be obtained for free or nominal cost from various sources. Include clear and obvious information on how to obtain the official POV-Ray. Include a copy of this document. You must provide all POV-Ray support for all users who acquired POV- Ray through your product. The POV-Ray Team is not obligated to provide you or your customers any technical support. Include a credit page or pages in your documentation for POV-Ray. If you modify any portion POV-Ray for use with your hardware or software, you must follow the custom version rules in addition to these rules. Include contact and support information for your product. Must include official documentation with product. CONDITIONS FOR SHAREWARE/FREEWARE DISTRIBUTION COMPANIES Shareware and freeware distribution companies may distribute the archives under the conditions following this section. You must notify us that you are distributing POV-Ray and must provide us with information on how to contact you should any support issues arise. No more than five dollars U.S. ($5) can be charged per disk for the copying of this software and the media it is provided on. Space on each disk must used completely. The company may not put each archive on a separate disk and charge for three disks if all three archives will fit on one disk. If more than one disk is needed to store the archives then more than one disk may be used and charged for. Distribution on high volume media such as backup tape or CD-ROM is permitted if the total cost to the user is no more than $0.10 per megabyte of data. For example a CD-ROM with 600 meg could cost no more than $60.00. CONDITIONS FOR ON-LINE SERVICES AND BBS'S On-line services and BBS's may distribute the POV-Ray archives under the conditions following this section. The archives must be all be easily available on the service and should be grouped together in a similar on-line area. It is strongly requested that BBS operators remove prior versions of POV- Ray to avoid user confusion and simplify or minimize our support efforts. The on-line service or BBS may only charge standard usage rates for the downloading of this software. A premium may not be charged for this package. I.E. CompuServe or America On-Line may make these archives available to their users, but they may only charge regular usage rates for the time required to download. They must also make the all of the archives available in the same forum, so they can be easily located by a user. DISCLAIMER This software is provided as is without any guarantees or warranty. Although the authors have attempted to find and correct any bugs in the package, they are not responsible for any damage or losses of any kind caused by the use or misuse of the package. The authors are under no obligation to provide service, corrections, or upgrades to this package. APPENDIX E CONTACTING THE AUTHORS ================================== We love to hear about how you're using and enjoying the program. We also will do our best try to solve any problems you have with POV-Ray and incorporate good suggestions into the program. If you have a question regarding commercial use of, distribution of, or anything particularly sticky, please contact Chris Young, the development team coordinator. Otherwise, spread the mail around. We all love to hear from you! The best method of contact is e-mail through CompuServe for most of us. America On-Line and Internet can now send mail to CompuServe, also, just use the Internet address and the mail will be sent through to CompuServe where we read our mail daily. Please do not send large files to us through the e-mail without asking first. We pay for each minute on CompuServe and large files can get expensive. Send a query before you send the file, thanks! Chris Young (Team Coordinator. Worked on everything.) CIS: 76702,1655 Internet 76702.1655@compuserve.com US Mail: 3119 Cossell Drive Indianapolis, IN 46224 U.S.A. Drew Wells (Former team leader. Worked on everything.) CIS: 73767,1244 Internet: 73767.1244@compuserve.com AOL: Drew Wells Prodigy: SXNX74A (Not used often) Other authors and contributors in alphabetical order: ----------------------------------------------------- David Buck (Original author of DKBTrace) (Primary developer, quadrics, docs) INTERNET:(preferred) dbuck@ccs.carleton.ca CIS: 70521,1371 Aaron Collins (Co-author of DKBTrace 2.12) (Primary developer, IBM-PC display code,phong) CIS: 70324,3200 Alexander Enzmann (Primary developer, Blobs, quartics, boxes, spotlights) CIS: 70323,2461 INTERNET: xander@mitre.com Dan Farmer (Primary developer, docs, scene files) CIS:70703,1632 Douglas Muir (Bump maps and height fields) CIS: 76207,662 Internet:dmuir@media-lab.media.mit.edu Bill Pulver (Time code and IBM-PC compile) CIS: 70405,1152 Charles Marslette (IBM-PC display code) CIS: 75300,1636 Mike Miller (Artist, scene files, stones.inc) CIS: 70353,100 Jim Nitchals (Mac version, scene files) CIS: 73117,3020 AppleLink: jimn8 Internet: 73117.3020@compuserve.com Eduard Schwan (Mac version, docs) CIS: 71513,2161 AppleLink: JL.Tech Internet: 71513.2161@compuserve.com Randy Antler (IBM-PC display code enhancements) CIS: 71511,1015 David Harr (Mac balloon help) CIS: 72117,1704 Scott Taylor (Leopard and Onion textures) CIS: 72401,410 Chris Cason (colour X-Windows display code) CIS: 100032,1644 Dave Park (Amiga support; added AGA video code) CIS: 70004,1764 end.