Back to Articles

Taming POV-Ray - Part 3: Colors and Patterns

by G. Moran, 31 Aug 2026

3D objects may look fine with plain flat colors, but we can do better than that. Time to give our objects various materials using POV-Ray's powerful texture generation system.

Table of contents

  1. The Texturing System
  2. Basic Pigments
  3. Gradients
  4. Noise
  5. Special Pigments
  6. Wrapping Up

The Texturing System

Examples of stock POV-Ray texture [POV source]

Objects in the real world are made up of different materials, such as plastic, glass, metal, stone...etc. Each material has a color or a mixture of many colors, and can have a smooth or rough surface, while also being shiny or dull. Some materials are transparent so they let light pass through and reveal objects behind them, sometimes with a bit of distortion.

POV-Ray aims to recreate many of the real world materials through clever light manipulation, color shifting, and noise functions. A user only needs to type in a few keywords for POV-Ray to generate greatly detailed textures. The possibilities are practically endless and, with a little patience, any material can be rendered.

Terminology

Before we begin, I should talk a little bit about the terms used by POV-Ray versus those used by other 3D programs. If you've never used any other 3D programs before then feel free to skip this section.

The 3D graphics industry of today uses common, standardized terms for 3D modeling properties. POV-Ray, on the other hand, uses a mixture of standardized and non-standardized terms, with certain terms having alternative meanings. This is worth noting as users of other 3D software might get confused by POV-Ray's terminology. If you are one of those users, consult this handy table that I made:

POV-Ray Other 3D Software
Texture Material
Pigment Base color, Albedo
Image map Texture map
Height map Displacement map
Phong highlights Glossiness

Keep in mind that this table is not comprehensive, and only covers the terminology of POV-Ray version 2.x. The terms in the "Other 3D Software" column are mostly pulled from this video.

Texture Block

Any 3D object rendered by POV-Ray has a texture describing its material. A texture is made up of three components; pigment, normal, and finish. Each texture component describes a different aspect of the material:

A fully textured object with a user-defined pigment, normal, and finish is specified as follows:

object {
    MyObject
    texture {
        pigment { ... }
        normal  { ... }
        finish  { ... }
    }
}

You can omit any of the three components of the texture, and POV-Ray will set the omitted components to their default properties. For example, you can only specify a pigment for an object and omit the normal and finish components, such that the object will have the default normal properties (no roughness) and default finish properties (no glossiness):

object {
    MyObject
    texture {
        pigment { ... }
    }
}

POV-Ray also allows you to specify the pigment, normal, and finish directly inside an object block, without enclosing them in a texture block. However, this is not recommended:

object {
    MyObject
    /* no `texture' block, not recommended */
    pigment { ... }
    normal  { ... }
    finish  { ... }
}

Any texture can be transformed; translation, scaling, and rotation all work on textures exactly the same way they work on 3D objects. We can write transformation statements inside a texture {} block to transform all of its 3 components together, or we can write separate transformation statements inside the pigment {}, normal {}, and/or finish {} blocks to transform each component separately.

Now let's learn more about the first texture component; the pigment.


Basic Pigments

The pigment is the first and most important texture component, and the main focus of this article. We have previously seen the pigment keyword used to give basic colors to different objects, such as the x/y/z axes and the CSG shapes. There are many types of pigments available in POV-Ray, some more complex than others, so we'll start with the easy stuff.

Single Colors

A single color is the most basic pigment there is. Objects with one assigned color will have their pixels become that color during rendering, with some pixels darkening and some pixels lightening as they get affected by light sources.

You can assign a single color pigment to an object using the color keyword followed by a color name. Here's a scene containing a sphere with an assigned orange color:

#version 2.0
#include "colors.inc"
camera {location z*-4 look_at <0,0,0>}
light_source {<2,2,-2> color White}

sphere {
    <0,0,0>, 1
    texture {
        pigment {color Orange}
    }
}

POV-Ray comes with a large number of named colors, such as "Red" and "SkyBlue". Most of the color names are familiar and can be very useful when creating textures. Some colors have two names for convenience, for example "Navy" and "NavyBlue" refer to the same color... You will find all the named colors declared in a file called colors.inc, which comes bundled with POV-Ray. Here's a handy visual chart showing all these colors:

Click here for a larger version of this image

One of the interesting named colors is "Clear"; a completely transparent color. By assigning this color to an object it becomes fully see-through, essentially disappearing from view. This color can come in handy in certain CSG operations where we want a solid object to look completely hollow. For example:

difference {
    sphere {
        <0,0,0>, 1
        texture { pigment {color Orange} }
    }
    plane {
        -y, 0
        texture { pigment {color Clear} }
    }
    rotate x*-15
}

The named colors that POV-Ray provides are nice and all, but there are many many more colors in existence that we can use. In fact the average computer screen can display over 16 million different colors! There must be a way to define any color we want, or in other words, "mix our own colors"... This is where the RGB system comes in.

The RGB system defines any color as a combination of three channels; red, green, and blue. In other words, any color is a mixture of some amount of red, some amount of green, and some amount of blue. We represent each amount as a value ranging from 0.0 to 1.0 in the form rgb <R, G, B>, where R, G, B correspond to the red, green, and blue channels respectively. Let's look at some examples with the color wheel below:

This system is used pretty much everywhere digital color is involved, including your web browser, your photo editor, and of course POV-Ray. Here's how we can assign an orange color in RGB notation to our sphere from earlier:

sphere {
    <0,0,0>, 1
    texture {
        /* same as `pigment {color Orange}' */
        pigment {color rgb <1, 0.5, 0>}
    }
}

POV-Ray also supports assigning partially or fully transparent colors through the filter keyword. Just write a color name or RGB triplet as we have been doing, followed by the keyword filter, followed by a value between 0.0 and 1.0 indicating the transparency level. A color with filter 0.0 is fully opaque, while a color with filter 1.0 is fully transparent. Here's the orange sphere from earlier but with 50% transparency laid against a checkerboard wall:

sphere {
    <0,0,0>, 1
    texture {
        pigment {color Orange filter 0.5}
    }
}

And here's the exact same sphere with 100% transparency:

sphere {
    <0,0,0>, 1
    texture {
        pigment {color Orange filter 1.0}
    }
}

Notice how the sphere is still visible? That's because colors do not disappear when fully transparent, they let light pass through and tint everything behind them. The only color that disappears when fully transparent is white, in fact the color named Clear from earlier is declared as rgbf <1,1,1,1> which means "fully filtered white".

There are alternative RGB color notations that POV-Ray supports. Here's a partially transparent orange color written in multiple equivalent notations:

/* different notations, same result */
pigment {color Orange filter 0.5}
pigment {color rgb <1, 0.5, 0> filter 0.5}
pigment {color rgbf <1, 0.5, 0, 0.5>}
pigment {color red 1 green 0.5 blue 0 filter 0.5}

Geometric Patterns

POV-Ray can generate simple geometric patterns with 2 or more colors and assign them to objects.

The first pattern we'll learn is the checker pattern, which creates a basic grid of squares with 2 alternating colors. To use this pattern we write the checker keyword inside of a pigment block, followed by two colors, like this:

union {
    plane {+x,-2}   plane {-x,-2}
    plane {+y,-2}   plane {-y,-2}
    plane {-z,-8}
    texture {
        pigment {
            checker color Black color White
        }
    }
}

The checker pattern is technically a grid of cubes, not squares. Because it's generated to look correct on any plane whether it's a wall or a floor. With that being said, the checker pattern looks best on axis-aligned planes. You should always assign this pattern to perfectly horizontal or vertical planes then transform them later if needed. Avoid assigning this pattern to non-flat surfaces, or it will look weird:

sphere {
    <0,0,0>, 1
    texture {
        pigment {
            checker color Black color White
        }
        scale 1/10
    }
}

The second geometric pattern is the hexagon pattern, which creates something resembling a beehive with 3 alternating colors. To use this pattern we write the hexagon keyword inside of a pigment block, followed by three colors, like this:

plane {
    -z, -8
    texture {
        pigment {
            hexagon color Gold
                    color BrightGold
                    color Silver
        }
        rotate x*-90
    }
}

Note that the hexagon pattern is generated in the xz plane, in other words it only looks correct when assigned to a plane {y ...} or a plane {-y ...}. In this example we assigned the hexagon pattern to a plane {-z ...} which is an xy plane, so the entire texture had to be rotated.


Gradients

POV-Ray can smoothly blend or transition between several colors to create a gradient, like a multi-colored sky during sunset. There are many types of gradients we can use and many ways to manipulate their look beyond basic transformations. Let's check them out.

Linear Gradients

The simplest gradient is a linear one; progressing along a single axis in a straight line. We can create a basic black-to-white linear gradient progressing across the x axis by writing gradient x inside a pigment block:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {gradient x}
    }
}

Gradients are assigned with the gradient keyword followed by a vector indicating the gradient direction, in this case x which is shorthand for <1,0,0>. The default gradient colors are black and white, in that order. We will learn how to change these colors in a moment.

There's something interesting to note in the previous render; the left half of the image (-x) is a mirrored version of the right half (+x). The gradient starts at the origin with the color black and transitions outwards in both +x and -x directions, becoming fully white at x=1 and x=-1, then it abruptly resets to black and transitions further outwards, becoming fully white again at x=2 and x=-2, and so on... This "mirroring" effect is because POV-Ray generates gradients mathematically from positions in the 3D world, so the negative part of the axis reverses the gradient in the positive part. This is much like how scaling by a negative factor produces a mirrored object.

When we use the gradient keyword we get an abrupt change from white to black every time the gradient resets, but we can eliminate these abrupt changes by using a different keyword; marble.

The marble keyword is equivalent to gradient x with one difference; whereas gradient x transitions from black to white in one unit, marble transitions from black to white in the first half of a unit, then transitions from white to black in the second half of the unit. Here's a 2D visualization using the colors blue and white:

This difference makes marble a more natural looking gradient. To use it we specify the keyword marble inside of a pigment block without a direction vector, as marble only progresses in one direction; along the x axis.

We can change the colors used by marble and gradient by specifying a color_map, which is a block containing a list of colors inside of the pigment block. Here's a marble gradient with the colors red and yellow, instead of black and white:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            marble color_map {
                [0 color Red]     /* start */
                [1 color Yellow]  /* end */
            }
        }
    }
}

The most basic color_map is a list comprised of two colors; a start color with index 0, and an end color with index 1. We can always add more colors in between, such as a color in the middle with index 0.5, or a color that's three quarters near the end with index 0.75. Here's a gradient x using a color_map with a longer list of colors:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            gradient x color_map {
                [0/3 color MediumBlue]
                [1/3 color SkyBlue]
                [2/3 color Turquoise]
                [3/3 color MediumBlue]
            }
        }
    }
}

Note that the indices above were written as fractions. A color_map index, like any other number in our file, can be written in normal decimal form (e.g. 0.333333) or in fraction form (e.g. 1/3) or in the form of a mathematical formula (e.g. SomeNumber*4+7). POV-Ray will gladly perform any calculations necessary to reach the final value that the user wants.

Color maps are quite flexible and can let us do some interesting tricks, like creating a gradient with no color transitions whatsoever:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            gradient x color_map {
                [0/3 color MediumBlue]
                [1/3 color MediumBlue]
                [1/3 color SkyBlue]
                [2/3 color SkyBlue]
                [2/3 color Turquoise]
                [3/3 color Turquoise]
            }
        }
    }
}

First we have a solid block of MediumBlue from index 0/3 to 1/3, then immediately after we have a solid block of SkyBlue from index 1/3 to 2/3, then finally a solid block of Turquoise from index 2/3 to 3/3, and the colors repeat. The indices between the different blocks, 1/3 and 2/3, are specified twice. This notation introduces abrupt stops where a color ends and another begins, eliminating any transitions.

Now let's say that we wanted to edit a previously specified color map, by shifting it slightly or by reversing the color order. We could rewrite our indices, or we could let POV-Ray do that for us with two keywords; frequency and phase.

The phase keyword shifts a color map by a certain amount between 0.0 and 1.0, such that the colors appear earlier or later than usual. The default phase of 0.0 disables color map shifting, while a phase of 0.5 shifts half the the color map so it starts from the middle, and a phase of 1.0 shifts the entire color map so the result looks like there was no shifting. The best way to explain it is with a 2D visualizer of a gradient x:

The frequency keyword specifies the number of gradient iterations in a single unit, as in how many times a gradient goes from index 0 to index 1 over the span of one unit. For example a blue-to-white gradient x with the default frequency of 1 will progress from blue to white over the span of one unit. If we change the frequency to 2, then the gradient will go from blue to white twice over the span of one unit. And if we change the frequency to 0.5, then half the gradient will span one unit. We can also use a negative frequency value to reverse the gradient direction, for example a frequency of -1 will make the gradient start from index 1 and progress to index 0. Here's a 2D visualizer:

Turbulence

Gradients can get distorted and bent out of their shape using something called turbulence; a noise function that POV-Ray applies to regular patterns to make them more random looking. We can use turbulence to turn basic pigments into real life textures, such as wood and veined stones.

We apply turbulence to a pigment by writing the turbulence keyword followed by a value indicating the turbulence level. Here's a wooden pattern using a simple marble gradient and low turbulence:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            marble color_map {
                [0 color LightWood]
                [1 color DarkWood]
            }
            turbulence 0.25
        }
    }
}

Turbulence values typically range from the default of 0.0 (no turbulence) to 1.0 (very turbulent), but larger values are also accepted. Here are different turbulence values applied to the same gradient:

Turbulence can be controlled by three modifiers; octaves, omega, and lambda. These are used in POV-Ray's noise calculation function, which is fully explained in the manual. Check out the images below and try to gain an intuition for how the three turbulence modifiers affect a simple gradient.

Different values of octaves, with turbulence 1:

Different values of omega, with turbulence 1:

Different values of lambda, with turbulence 1:

To use the turbulence modifiers we start by writing the turbulence keyword followed by a turbulence value as we've done before, then we write the name of each modifier followed by its value. Here's a pigment using the default values for octaves, omega, and lambda:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            marble color_map {
                [0 color Violet]
                [1 color Orchid]
            }
            turbulence 1
            octaves 6 omega 0.5 lambda 2
        }
    }
}

Remember that specifying the turbulence modifiers is optional. You don't have to specify all three modifiers if you only want to change the value of one or two of them.

Shaped Gradients

All the gradients we have seen so far (i.e. gradient and marble) have been linear; always progressing in a straight line. There are other gradients which progress in different shapes. Let's check them out.

First is the wood gradient, where colors progress in a circle surrounding the z axis. This gradient is called "wood" because when applied to a cylinder it results in an object resembling a real life wooden log. Here's a demonstration:

cylinder {
    -z*2, +z*2, 0.5
    texture {
        pigment {
            wood
            color_map {
                [0 color LightWood]
                [1 color DarkWood]
            }
            turbulence 0.05
            scale <0.2, 0.2, 2>
        }
    }
    rotate y*-30
}

If you look at the "rings" at the tip of the cylinder you'll find that they are like a circular version of the marble gradient; the color transitions from index 0 (LightWood) to index 1 (DarkWood) then back to index 0 as the gradient repeats, but instead of going in a straight line the color transitions from the center of the axis outwards in the shape of a cirle, creating the rings that you see.

Next there's the onion gradient, where colors progress in the shape of a sphere centered around the origin, exactly like a real life onion. Here's an object modeled to look like an onion that was freshly cut:

difference {
    sphere {z-z,1} plane {-y,0}
    texture {
        pigment {
            onion color_map {
                [0 color Pink]
                [1 color White]
            }
            turbulence 0.1
            scale 0.2
        }
    }
    rotate x*-30
}

You can see a cross-section of the gradient on the flat part of the object above. The gradient starts with index 0 (Pink) at the origin then grows in the shape of a sphere until it reaches index 1 (White) at radius 1, then abruptly resets to index 0 and the gradient repeats.

The onion gradient looks good on the flat part of the object, but doesn't look too good on the spherical part. Maybe we can change that... The object is made up of two shapes; a sphere and a plane. By giving each shape a different pigment we can create something more natural looking:

difference {
    sphere {
        z-z, 1
        texture {
            pigment {color VioletRed}
        }
    }
    plane {
        -y, 0
        texture {
            pigment {
                onion color_map {
                    [0 color Pink]
                    [1 color White]
                }
                turbulence 0.1
                scale 0.2
            }
        }
    }
    rotate x*-30
}

Next we have the radial gradient, which is a little tricky to explain. The colors in this gradient rotate around the y axis, such that the result looks like the top view of a cone. Here's an example:

cylinder {
    y-y, -y*4, 1
    texture {
        pigment {
            radial color_map {
                [0 color Red]
                [1 color Yellow]
            }
        }
    }
    rotate x*-30
}

And finally there's the leopard gradient, where color transitions in a pattern resembling a real life lepard's skin. Here's the gradient in action:

sphere {
    z-z, 1
    texture {
        pigment {
            leopard color_map {
                [0.3 color Gold]
                [0.3 color Black]
                [0.7 color Black]
                [0.7 color Gold]
            }
            scale 0.05
        }
    }
}

We introduced some abrupt transitions in this color map, however we did not specify index 0 nor index 1, only the indexes in between. This notation is perfectly valid. POV-Ray will automatically set index 0 to the first specified index in the color map, in this case index 0.3 (Gold), and set index 1 to the last specified index, in this case index 0.7 (Gold).


Noise

POV-Ray provides a few complex pigments that are based on noise functions, for creating materials where gradients don't suffice. Noise pigments use color maps just like gradients, except the result is more randomized.

The first noise pigment is bozo; a pigment that creates random blob-like patterns following a color map. Here's an example:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            bozo color_map {
                [0/2 color Black]
                [1/2 color SeaGreen]
                [2/2 color White]
            }
            scale 0.5
        }
    }
}

We can add turbulence to a bozo pigment to make it more noisy, like this:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            bozo color_map {
                [0/2 color Black]
                [1/2 color SeaGreen]
                [2/2 color White]
            }
            scale 0.5
            turbulence 0.5
        }
    }
}

Next we have agate; another noise pigment that is very turbulent by default. The patterns formed by agate bear some resemblance to marble when turbulent, however they are two separate pigments that are generated differently from each other. Here's an example:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            agate color_map {
                [0 color Orchid]
                [1 color White]
            }
        }
    }
}

We didn't specify a turbulence value here yet the result was already very turbulent. We can adjust the turbulence of agate but we will have to use a special keyword; agate_turb. Unlike other pigments, agate is unaffected by the turbulence keyword and is instead affected by the unique agate_turb keyword, which is not used by any other pigment. The default value for agate_turb is 1, here's an example with a lower value:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            agate color_map {
                [0 color Orchid]
                [1 color White]
            }
            agate_turb 0.5
        }
    }
}

Finally we have granite; a very unique noise pigment. Like bozo, the granite pigment can be controlled by turbulence, however it already looks very noisy even with a turbulence value of zero:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {granite}
    }
}

Cranking up the turbulence gives granite a very unique look that's even noisier. I'm not sure which real life stone has this look, but it's definitely interesting to see:

union {
    plane {+y,-1}   plane {-z,-2}
    texture {
        pigment {
            granite
            turbulence 1
        }
    }
}


Special Pigments

POV-Ray provides two special pigments that are quite different from the other pigments we have seen so far. The first is the image_map pigment, which directly "maps" an external 2D image file to a 3D object. We will demonstrate how this works using the famous Lena test image:

Save this image with the file name lena.gif and place it in the same folder as your POV file. Now let's turn this image into an image_map:

plane {
    -z, 0
    texture {
        pigment {
            image_map {
                gif "lena.gif" once
            }
        }
    }
}

Here we specified the image file type, which is typically gif or tga, followed by the image file name in double quotes, followed by the "once" keyword to avoid repeating the image.

We can see that POV-Ray mapped our Lena image onto a flat plane, like a slide projector mapping an image onto a wall. By default an image_map is mapped onto the xy plane and fitted in a square from x,y coordinates <0,0> to <1,1> like this:

Every image_map is confined to this 1 x 1 square regardless of the original dimensions of the image file, so a tall portrait or a wide panorama would get squashed into the shape of a square when rendered. Thankfully we can scale image maps to fit any aspect ratio using the typical POV-Ray transformations, just like we did with other pigments.

If the "once" keyword is specified then the image is rendered only once; the aforementioned 1 x 1 square is colored while the rest of the 3D object is transparent. If we omit the "once" keyword then the image is repeated across both x and y axes, filling the xy plane entirely:

plane {
    -z, 0
    texture {
        pigment {
            image_map {
                gif "lena.gif"
            }
        }
    }
}

So far we have been mapping our image onto a flat surface, what about other non-flat shapes like spheres? We can easily do image mapping in almost any shape by writing the map_type keyword followed by one of the following values:

Here's a sphere with spherical image mapping:

sphere {
    z-z, 1
    texture {
        pigment {
            image_map {
                gif "lena.gif"
                map_type 1
            }
            rotate y*-45
        }
    }
}

By taking a closer look at the previous render, you'll find the pixels of the image map are very apparent, looking like little squares. This look may be acceptable in certain cases where image maps contain pixel art or similar, but usually you'll want to apply some smoothing. This is easily done with the interpolate keyword:

sphere {
    z-z, 1
    texture {
        pigment {
            image_map {
                gif "lena.gif"
                map_type 1
                interpolate 2
            }
            rotate y*-45
        }
    }
}

The interpolate keyword must be followed by a value; 0 for a pixelated look using no interpolation, 2 for a smooth look using bilinear interpolation, or 4 for a look that's somewhere in between pixelated and smooth.

We can make our image maps partially or fully transparent by using the filter keyword. Here's an image map that's 75% transparent, laid against a checkerboard plane:

sphere {
    z-z, 1
    texture {
        pigment {
            image_map {
                gif "lena.gif"
                map_type 1
                filter all 0.5
            }
            rotate y*-45
        }
    }
}

There are other, more advanced ways of controlling transparency in image maps that use indexed color. These are covered in depth in the manual.

Now let's move on to our last special pigment; mandel. This is a pigment that plots a Mandelbrot fractal onto the xy plane with colors from a color map. Here's an example:

plane {
    -z,0
    texture {
        pigment {
            mandel 20
            color_map {
                [0/2 color Navy]
                [1/2 color Turquoise]
                [2/2 color Black]
            }
        }
    }
}

First we write the mandel keyword, followed by a value that's basically the "level of detail" of the fractal, followed by a regular color_map. The fractal seen here may look uninteresting at first glance, however by transforming it in certain ways one may be able to achieve some stunning images.


Wrapping Up

You should now know how to give an object a pigment, which is the first component of the POV-Ray texture block, as well as how to mix colors and incorporate them into different patterns. In the following articles we'll learn about the other components of the POV-Ray texture; the normal and finish. Until then feel free to play around with POV-Ray and practice what you learned.

Back to Articles