Specifying Colors

### 6.1.5 Specifying Colors

    COLOR:
        COLOR_BODY             |
        color COLOR_BODY       | (this means the keyword color or
        colour COLOR_BODY         colour may optionally precede
                                  any color specification)
    COLOR_BODY:
        COLOR_VECTOR           |
        COLOR_KEYWORD_GROUP    |
        COLOR_IDENTIFIER
    COLOR_VECTOR:
        rgb <3_Term_Vector>  |
        rgbf <4_Term_Vector> |
        rgbt <4_Term_Vector> |
        [ rgbft ] <5_Term_Vector>
    COLOR_KEYWORD_GROUP:
        [ COLOR_KEYWORD_ITEM ]...
    COLOR_KEYWORD_ITEM:
        COLOR_IDENTIFIER       |
        red Red_Amount         |
        blue Blue_Amount       |
        green Green_Amount     |
        filter Filter_Amount   |
        transmit Transmit_Amount

Note: COLOR_IDENTIFIERS are identifiers previously declared to have color values. The 3, 4, and 5 term vectors are usually vector literals but may be vector expressions or floats promoted to vectors. See "Operator Promotion" and the sections below.

POV-Ray often requires you to specify a color. Colors consist of five values or color components. The first three are called `red`, `green`, and `blue`. They specify the intensity of the primary colors red, green and blue using an additive color system like the one used by the red, green and blue color phosphors on a color monitor.

The 4th component, called `filter`, specifies the amount of filtered transparency of a substance. Some real-world examples of filtered transparency are stained glass windows or tinted cellophane. The light passing through such objects is tinted by the appropriate color as the material selectively absorbs some frequencies of light while allowing others to pass through. The color of the object is subtracted from the light passing through so this is called subtractive transparency.

The 5th component, called `transmit`, specifies the amount of non-filtered light that is transmitted through a surface. Some real-world examples of non-filtered transparency are thin see-through cloth, fine mesh netting and dust on a surface. In these examples, all frequencies of light are allowed to pass through tiny holes in the surface. Although the amount of light passing through is diminished, the color of the light passing through is unchanged.

The color of the object and the color transmitted through the object together contribute 100% of the final color. So if `transmit` is set to 0.9, the transmitted color contributes 90% and the color of the object contributes only 10%. This is also true outside of the 0-1 range, so for example if `transmit` is set to 1.7, the transmitted color contributes with 170% and the color of the object contributes with minus 70%. Using `transmit` values outside of the 0-1 range can be used to create interesting special effects, but does not correspond to any phenomena seen in the real world. An example:

    #version 3.5;
    global_settings {assumed_gamma 1.0}
    camera {location -2.5*z look_at 0 orthographic}
    box {
       0,1
       texture {
          pigment {
             gradient y
             colour_map {
                [0, red 1]
                [1, blue 1]
             }
          }
          finish{ambient 1}
       }
       texture {
          pigment {
             gradient x
             colour_map {
                [0, rgb 0.5 transmit -3]
                [1, rgb 0.5 transmit  3]
             }
          }
          finish{ambient 1}
       }
       translate <-0.5,-0.5,0>
       scale <3,2,1>
    }

When using the `transmit` value for special effects, you can visualize it this way: The `transmit` value means "contrast". 1.0 is no change in contrast, 0.5 is half contrast, 2.0 is double contrast and so on. You could say that `transmit` "scales" the colors. The color of the object is the "center value". All colors will get closer to the "center value" if `transmit` is between 0 and 1, and all colors will spread away from the "center value" if `transmit` is greater than 1. If `transmit` is negative the colors will be inverted around the "center value". Rgb 0.5 is common to use as "center value", but other values can be used for other effects. The "center value" really is a color, and non-gray colors can be used for interesting effects. The red, green and blue components are handled seperately.

Note: early versions of POV-Ray used the keyword `alpha` to specify filtered transparency. However that word is often used to describe non-filtered transparency. For this reason `alpha` is no longer used.

Each of the five components of a color are float values which are normally in the range between 0.0 and 1.0. However any values, even negatives may be used.

Under most circumstances the keyword `color` is optional and may be omitted. We also support the British or Canadian spelling `colour`. Colors may be specified using vectors, keywords with floats or identifiers. You may also create very complex color expressions from combinations of any of these using various familiar operators. The syntax for specifying a color has evolved since POV-Ray was first released. We have maintained the original keyword-based syntax and added a short-cut vector notation. Either the old or new syntax is acceptable however the vector syntax is easier to use when creating color expressions.

The syntax for combining color literals into color expressions is almost identical to the rules for vector and float expressions. In the syntax for vector expressions, some of the syntax items are defined in the section for float expressions. See "Float Expressions" for those definitions. Detailed explanations of color-specific issues are given in the following sub-sections.

#### 6.1.5.1 Color Vectors

The syntax for a color vector is...

    COLOR_VECTOR:
        rgb <3_Term_Vector>   |
        rgbf <4_Term_Vector>  |
        rgbt <4_Term_Vector>  |
        [ rgbft ] <5_Term_Vector>

...where the vectors are any valid vector expressions of 3, 4 or 5 components. For example

     color rgb <1.0, 0.5, 0.2>

This specifies a color whose red component is 1.0 or 100% of full intensity. The green component is 0.5 or 50% of full intensity and the blue component is 0.2 or 20% of full intensity. Although the filter and transmit components are not explicitly specified, they exist and are set to their default values of 0 or no transparency.

The `rgbf` keyword requires a four component vector. The 4th component is the filter component and the transmit component defaults to zero. Similarly the `rgbt` keyword requires four components where the 4th value is moved to the 5th component which is transmit and then the filter component is set to zero.

The `rgbft` keyword allows you to specify all five components. Internally in expressions all five are always used.

Under some circumstances, if the vector expression is a 5 component expression or there is a color identifier in the expression then the `rgbtf` keyword is optional.

#### 6.1.5.2 Color Keywords

The older keyword method of specifying a color is still useful and many users prefer it.

    COLOR_KEYWORD_GROUP:
        [ COLOR_KEYWORD_ITEM ]...
    COLOR_KEYWORD_ITEM:
        COLOR_IDENTIFIER |
        red Red_Amount | blue Blue_Amount | green Green_Amount |
        filter Filter_Amount | transmit Transmit_Amount

Although the `color` keyword at the beginning is optional, it is more common to see it in this usage. This is followed by any of five additional keywords `red`, `green`, `blue`, `filter`, or `transmit`. Each of these component keywords is followed by a float expression. For example

     color red 1.0 green 0.5

This specifies a color whose red component is 1.0 or 100% of full intensity and the green component is 0.5 or 50% of full intensity. Although the blue, filter and transmit components are not explicitly specified, they exist and are set to their default values of 0. The component keywords may be given in any order and if any component is unspecified its value defaults to zero. A COLOR_IDENTIFIER can also be specified but it should always be first in the group. See "Common Color Pitfalls" for details.

#### 6.1.5.3 Color Identifiers

Color 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.

    COLOR_DECLARATION:
        #declare IDENTIFIER = COLOR; |
        #local IDENTIFIER = COLOR;

Where IDENTIFIER is the name of the identifier up to 40 characters long and COLOR is any valid specification.

Note: there should be a semi-colon at the end of the declaration. If omitted, it generates a warning and some macros may not work properly. See " #declare vs. #local" for information on identifier scope.

Here are some examples....

     #declare White = rgb <1,1,1>;
     #declare Cyan = color blue 1.0 green 1.0;
     #declare Weird = rgb <Foo*2,Bar-1,Bob/3>;
     #declare LightGray = White*0.8;
     #declare LightCyan = Cyan red 0.6;

As the `LightGray` example shows you do not need any color keywords when creating color expressions based on previously declared colors. The last example shows you may use a color identifier with the keyword style syntax. Make sure that the identifier comes first before any other component keywords.

Like floats and vectors, you may re-define colors throughout a scene but the need to do so is rare.

#### 6.1.5.4 Color Operators

Color vectors may be combined in expressions the same as float or vector values. Operations are performed on a component-by-component basis. For example `rgb <1.0,0.5,0.2>*0.9` evaluates the same as `rgb<1.0,0.5,0.2>*<0.9,0.9,0.9>` or `rgb<0.9,0.45,0.18>`. Other operations are done on a similar component-by-component basis.

You may use the dot operator to extract a single component from a color. Suppose the identifier `Shade` was previously defined as a color. Then `Shade.red` is the float value of the red component of `Shade`. Similarly `Shade.green`, `Shade.blue`, `Shade.filter` and `Shade.transmit` extract the float value of the other color components. `shade.gray` returns the gray value of the color vector.

#### 6.1.5.5 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

or

     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. Another issue to consider: 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.4>` 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. Finally there is another problem which arises when using color dot operators in `#declare` or `#local` directives. Consider the directive:

     #declare MyColor = rgb <0.75, 0.5, 0.75>;
     #declare RedAmt = MyColor.red;

Now `RedAmt` should be a float but unfortunately it is a color. POV-Ray looks at the first keyword after the equals to try to guess what type of identifier you want. It sees the color identifier `MyColor` and assumes you want to declare a color. It then computes the float value as 0.75 then promotes that into `rgbft<0.75,0.75,0.75,0.75,0.75>`. It would take a major rewrite to fix this problem so we're just warning you about it. Any of the following work-arounds will work properly.

     #declare RedAmt = 0.0+MyColor.red;
     #declare RedAmt = 1.0*MyColor.red;
     #declare RedAmt = (MyColor.red);