Common Color Pitfalls

The variety and complexity of color specification methods can lead to some common mistakes. Here are some things to consider when specifying a color.

When using filter transparency, the colors which come through are multiplied by the primary color components. For example if gray light such as rgb <0.9,0.9,0.9> passes through a filter such as rgbf <1.0,0.5,0.0,1.0> the result is rgb <0.9,0.45,0.0> with the red let through 100%, the green cut in half from 0.9 to 0.45 and the blue totally blocked. 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 either

color red 1.0 green 1.0 blue 1.0 filter 1.0


color transmit 1.0

In the 2nd example it doesn't matter what the rgb values are. All of the light passes through untouched.

Another pitfall is the use of color identifiers and expressions with color keywords. For example...

color My_Color red 0.5

this substitutes whatever was the red component of My_Color with a red component of 0.5 however...

color My_Color + red 0.5

adds 0.5 to the red component of My_Color and even less obvious...

color My_Color * red 0.5

that cuts the red component in half as you would expect but it also multiplies the green, blue, filter and transmit components by zero! The part of the expression after the multiply operator evaluates to rgbft <0.5,0,0,0,0> as a full 5 component color.

The following example results in no change to My_Color.

color red 0.5 My_Color

This is because the identifier fully overwrites the previous value. When using identifiers with color keywords, the identifier should be first.

One final issue, some POV-Ray syntax allows full color specifications but only uses the rgb part. In these cases it is legal to use a float where a color is needed. For example:

finish { ambient 1 }

The ambient keyword expects a color so the value 1 is promoted to <1,1,1,1,1> which is no problem. However

pigment { color 0.4 }

is legal but it may or may not be what you intended. The 0.4 is promoted to <0.4,0.4,0.4,0.4,0.> with the filter and transmit set to 0.4 as well. It is more likely you wanted...

pigment { color rgb 0.4 }

in which case a 3 component vector is expected. Therefore the 0.4 is promoted to <0.4,0.4,0.4,0.0,0.0> with default zero for filter and transmit.

Section 7.1.6

The POV-Ray language requires you to specify a string of characters to be used as a file name, text for messages or text for a text object. Strings may be specified using literals, identifiers or functions which return string values. Although you cannot build string expressions from symbolic operators such as are used with floats, vectors or colors, you may perform various string operations using string functions. Some applications of strings in POV-Ray allow for non-printing formatting characters such as newline or form-feed.

String Literals

String literals begin with a double quote mark '"' which is followed by up to 256 printable ASCII characters and are terminated by another double quote mark. The following are all valid string literals:

  "Here"   "There"    "myfile.gif"    ""

Note if you need to specify a quote mark in a string literal you must preceed it with a backslash. For example

  "Joe said \"Hello\" as he walked in."

is converted to

  Joe said "Hello" as he walked in.

If you need to specify a backslash, most of the time you need do nothing special. However if the string ends in a backslash, you will have to specify two. For example:

  "This is a backslash  and so is this"

Is converted to:

  This is a backslash  and so is this\


regardless usage however other formating codes such as \n for new line are supported in user message streams. See "Text Formatting" for details.

String Identifiers

String identifiers may be declared to make scene files more readable and to parameterize scenes so that changing a single declaration changes many values. An identifier is declared as follows...


Where IDENTIFIER is the name of the identifier up to 40 characters long and STRING is a string literal, string identifier or function which returns a string value. Here are some examples...

#declare Font_Name = "ariel.ttf" #declare Inc_File = "" #declare Name = "John" #declare Name = concat(Name," Doe")

As the last example shows, you can re-declare a string identifier and may use previously declared values in that re-declaration.

Section 7.1.7
Built-in Identifiers

There are several built-in float and vector identifiers. You can use them to specify values or to create expressions but you cannot re-declare them to change their values.

Constant Built-in Identifiers

Most built-in identifiers never change value. They are defined as though the following lines were at the start of every scene.

#declare pi = 3.1415926535897932384626 #declare true = 1 #declare yes = 1 #declare on = 1 #declare false = 0 #declare no = 0 #declare off = 0 #declare u = <1,0> #declare v = <0,1> #declare x = <1,0,0> #declare y = <0,1,0> #declare z = <0,0,1> #declare t = <0,0,0,1>

The built-in float identifier pi is obviously useful in math expressions involving circles.

The built-in float identifiers on,off, yes, no, true and false are designed for use as boolean constants.

The built-in vector identifiers x, y and z provide much greater readability for your scene files when used in vector expressions. For example....

plane { y, 1} // The normal vector is obviously "y". plane { <0,1,0>, 1} // This is harder to read. translate 5*x // Move 5 units in the "x" direction. translate <5,0,0> // This is less obvious.

An expression like 5*x evaluates to 5 <1,0,0> or <5,0,0>.

Similarly u and v may be used in 2D vectors. When using 4D vectors you should use x, y, z, and t and POV-Ray will promote x, y and z to 4D when used where 4D is required.

Built-in Identifier 'clock'

The built-in float identifier clock is used to control animations in POV-Ray. Unlike some animation packages, the action in POV-Ray animated scenes does not depend upon the integer frame numbers. Rather you should design your scenes based upon the float identifier clock. For non-animated scenes its default value is 0 but you can set it to any float value using the INI file option Clock=n.n or the command-line switch +Kn.n to pass a single float value your scene file.

Other INI options and switches may be used to animate scenes by automatically looping through the rendering of frames using various values for clock. By default, the clock value is 0 for the initial frame and 1 for the final frame. All other frames are interpolated between these values. For example if your object is supposed to rotate one full turn over the course of the animation you could specify rotate 360*clock*y. Then as clock runs from 0 to 1, the object rotates about the y-axis from 0 to 360 degrees.

Although the value of clock will change from frame-to-frame, it will never change throughout the parsing of a scene.

See section "Animation Options" for more details.

Built-in Identifier 'version'

The built-in float identifier version contains the current setting of the version compatibility option. Although this value defaults to 3 which is the current POV-Ray version number, the initial value of version may be set by the INI file option Version=n.n or by the +MVn.n command-line switch. This tells POV-Ray to parse the scene file using syntax from an earlier version of POV-Ray.

The INI option or switch only affects the initial setting. Unlike other built-in identifiers, you may change the value of version throughout a scene file. You do not use #declare to change it though. The #version language directive is used to change modes. Such changes may occur several times within scene files.

Together with the built-in version identifier the #version directive allows you to save and restore the previous values of this compatibility setting. For example suppose is in version 1 format. At the top of the file you could put:

#declare Temp_Vers = version // Save previous value #version 1.0 // Change to 1.0 mode ... // Version 1.0 stuff goes here... #version Temp_Vers // Restore previous version
Next Section
Table Of Contents