Previous:Color Operators   Main Index   Next:Strings



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);


Previous:Color Operators   Main Index   Next:Strings