A pattern is a function of a point in space. Every pattern in POV-Ray is three-dimensional: it has a value for every point <x, y, z>, and objects are “carved” out of it. A continuous pattern returns a number, usually from 0 to 1. That number is changed by a wave type, then looked up in a blend map, which turns it into a colour, a pigment, a normal, a slope, a texture or a density. A block pattern (checker, brick, hexagon …) does not return a number: it picks one item out of a short list. This page lists every pattern the parser accepts, the keywords that belong to a pattern, the modifiers that work on all patterns, and the grammar of the maps. The texture, pigment and normal statements that use patterns are on Textures and pigments and Normals and finishes; media density is on Media, interior and atmosphere.
Unless a row says otherwise, defaults on this page are the values of the parser source of POV-Ray 3.8. A scene without a #version directive runs as language version 3.62 (the value of the version constant), see Versions.
Where a pattern can be used
| Statement | What the pattern value selects | Map used |
|---|---|---|
pigment { … } | a colour | color_map, pigment_map |
normal { … } | a bump height or a perturbed normal | slope_map, normal_map |
texture { … } | a whole texture | texture_map |
density { … } inside media | a density (a colour whose three components are used) | color_map, density_map |
function { pattern { … } } | a number, see pattern functions | none |
pigment_pattern, image_pattern (inside a pigment, normal or texture) | the grey value of another pigment or of an image | any map of the outer statement |
Grammar of a pattern inside a statement: the pattern type comes first, then any number of modifiers in any order. In a normal an optional number (the bump size) may follow the pattern type: bumps 0.4, gradient x, 0.5 (the comma matters when the number is negative). Statements that take a block list (checker, brick …) accept colours, or wrapped items, directly after the keyword.
Continuous patterns
These return a number. The result goes through the wave type (ramp unless noted) after value * frequency + phase. “Default map” is the blend map used when a pigment uses the pattern without any map of its own; all other patterns use a black-to-white ramp ([0 rgb 0] [1 rgb 1]).
| Pattern | Syntax | Value | Default wave | Default map |
|---|---|---|---|---|
agate | agate [agate_turb s] | banded noise: 0.5 * (cycloidal(1.3 * T + 1.1 * z) + 1) raised to 0.77, where T is s times the turbulence at the point. Turbulence settings are always present (see below) | ramp | six entries, white to brown |
bozo, spotted | bozo | smooth noise, the same pattern under two names | ramp | bozo: six entries, white, green, blue, red; spotted: black to white |
bumps | bumps | as a pigment or texture pattern the same noise as bozo; in a normal it uses its own perturbation (see Normals and finishes) | ramp | black to white |
boxed | boxed | 1 - min(1, max(|x|, |y|, |z|)): 1 at the origin, 0 outside the cube of side 2 | ramp | black to white |
cells | cells | a random value from 0 to 1, the same inside every unit cube | ramp | black to white |
cylindrical | cylindrical | 1 - min(1, sqrt(x² + z²)): a cylinder of radius 1 around the y axis | ramp | black to white |
dents | dents | noise based; in a normal it uses its own perturbation | ramp | black to white |
function | function { expression } | the value of a user function of x, y, z | ramp | black to white |
gradient | gradient <direction> | the position along the direction, which the parser normalises to length 1; the wave type makes it repeat every unit | ramp | black to white |
granite | granite | 1/f fractal noise | ramp | black to white |
leopard | leopard | ((sin x + sin y + sin z) / 3)² | ramp | black to white |
marble | marble | x plus (when there is turbulence) turbulence.x * T | triangle | three entries, pink to dark red to black |
onion | onion | fmod(distance from the origin, 1): concentric spheres, one unit thick | ramp | black to white |
planar | planar | 1 - min(1, |y|): a slab one unit above and below the x-z plane | ramp | black to white |
quilted | quilted [control0 c0] [control1 c1] | unit cubes with sloped seams; c0 and c1 (default 1 and 1) bend the slope at the top and bottom of the seam | ramp, frequency 0 | black to white |
radial | radial | 0.25 + (atan2(x, z) + π) / 2π: an angle around the y axis. 1.0 is at +x, 0.25 at −z, 0.5 at −x, 0.75 at +z. Inside radius 0.001 of the axis the value is 0.25 | ramp | four entries, cyan, yellow, magenta, cyan |
ripples | ripples | rings around random centres inside the unit cube, repeated everywhere. The number of centres is number_of_waves of global_settings (see Global settings) | ramp | black to white |
spherical | spherical | 1 - min(1, distance from the origin) | ramp | black to white |
spiral1 | spiral1 arms | a screw-shaped spiral around the z axis with arms arms (integer) | triangle | black to white |
spiral2 | spiral2 arms | two overlapping spirals that twist in opposite directions | triangle | black to white |
waves | waves | like ripples, rounder and broader; the same number_of_waves | ramp | black to white |
wood | wood | the distance from the z axis, sqrt(x² + y²) (with turbulence added to x and y), so rings of one unit | triangle | two entries, light and dark brown, both at 0.6 |
wrinkles | wrinkles | 1/f noise with sharper features than granite | ramp | black to white |
crackle | crackle and its keywords | Voronoi cells, see pattern keywords | ramp | black to white |
pavement | pavement and its keywords | polyform tiles in the x-z plane; value 0 to 1 | ramp | black to white |
tiling | tiling n (1 to 27) | tiles in the x-z plane; for a tiling of N tile types the main colour of tile x is at x / N and its caulking edge at (x + 1) / N. Another number is the error “Tiling number must be between 1 and 27.” | ramp | black to white |
mandel, julia, magnet | see fractals | an escape-time value | ramp | mandel: five entries, black, cyan, yellow, magenta, cyan; the others black to white |
density_file | density_file df3 "file" [interpolate n] | the data of a df3 file in the unit cube <0,0,0> to <1,1,1>, scaled to 0 to 1; 0 outside the cube. interpolate 0 (default) none, 1 trilinear, 2 tricubic. The word df3 is required | ramp | black to white |
potential | potential { blob or isosurface } [threshold bool] | the potential field of the object; with threshold on, the isosurface threshold is subtracted. Not limited to 0 to 1 | raw (no wave unless one is written) | black to white |
pigment_pattern | pigment_pattern { pigment body } | the grey value of the pigment | ramp | black to white |
image_pattern | image_pattern { image [use_colour | use_index | use_alpha] … } | the grey value of an image, see image pattern | ramp, frequency 0 | black to white |
spotted and bozo share their noise, but only bozo has its own colourful default map. The default maps matter when such a pattern is used without a map, for instance in a function or in media. The patterns facets (normals only), slope and aoi depend on the surface normal and are listed below.
Block patterns
A block pattern has no number between 0 and 1: it selects item n of a list. The list is written right after the keyword. In a pigment each item is a colour (a comma between colours is optional) or pigment { … }. In a normal each item is normal { … }, in a texture texture { … }, in a density density { … }. Items you leave out take the defaults of the table. Block patterns cannot use color_map, slope_map or wave types, and frequency and phase only give a warning (“has no effect on discrete patterns”).
| Pattern | Items | Geometry | Default colours (item 1, 2, …) |
|---|---|---|---|
checker | 2 | alternating unit cubes | blue, green |
brick | 2 | item 1 is the mortar, item 2 the brick. brick_size <x,y,z> is the size of brick plus mortar (default <8, 3, 4.5>); mortar t is the thickness (default 0.5). Every other row is shifted by half a brick | mortar grey 0.5, brick <0.6, 0.15, 0.15> |
hexagon | 3 | hexagonal rods along y, side length 1; item 1 at the origin, item 2 towards +z, item 3 to the sides | blue, green, red |
square | 4 | square rods along y, side 1 | red, green, blue, yellow |
triangular | 6 | triangular rods along y, side 1 | red, green, blue, yellow, cyan, magenta |
cubic | 6 | one item for each face of a cube around the origin, in the order +x, +y, +z, −x, −y, −z | red, green, blue, yellow, cyan, magenta |
object | 2 | object { solid object outside, inside }: item 1 outside the object, item 2 inside. The object must be a solid and cannot have a texture | blue, green |
With normal, the optional bump size after the keyword is parsed when no item is written (checker 0.5).
Fractal patterns
mandel iterations [exponent n] [exterior type, factor] [interior type, factor]
julia <re, im>, iterations [exponent n] [exterior …] [interior …]
magnet 1|2 mandel iterations [exterior …] [interior …]
magnet 1|2 julia <re, im>, iterations [exterior …] [interior …]
| Keyword | Value | Default | Meaning |
|---|---|---|---|
| iterations | integer, at least 1 | none | iteration limit (“fractal iterations limit”) |
exponent | 2 to 33 | 2 | exponent of the Mandelbrot or Julia formula z = z^n + c. 2, 3 and 4 have fast code; another value gives a warning and exponent 2. Only mandel and julia, not magnet |
exterior | type 0 to 8, factor | 1, 1 | colouring outside the set (below); other types are an error |
interior | type 0 to 6, factor | 0, 1 | colouring inside the set |
| Type | Value returned |
|---|---|
| 0 | 1 |
| 1 | exterior: iterations until bailout divided by the limit (not scaled by the factor); interior: the smallest absolute value on the orbit |
| 2, 3 | real part, imaginary part of the last point of the orbit |
| 4, 5 | squared real part, squared imaginary part of the last point |
| 6 | absolute value of the last point |
| 7 (exterior only) | iterations modulo the factor, divided by the factor |
| 8 (exterior only) | iterations modulo (factor + 1), divided by the factor |
For types 0 and 2 to 6 the result is multiplied by the factor. For magnet a type other than 1 or 2 is the error “Invalid magnet-mandel pattern type found. Valid types are 1 and 2.”
Patterns that depend on the surface
| Pattern | Syntax | Value |
|---|---|---|
aoi | aoi | proportional to the angle between the ray and the surface: 0.5 where the ray is tangent, 1.0 where it is perpendicular. Values below 0.5 can occur on smooth triangles and meshes |
slope | slope <direction>slope { [point_at] <vector> [, lo, hi] [altitude <vector> [, lo_alt, hi_alt]] } | depends on the angle between the direction and the surface normal: 0 when the normal points the opposite way, 0.5 when it is perpendicular, 1 when it is parallel. lo and hi (default 0, 0 = unused) stretch the range of slopes between them to 0 to 1. With point_at the vector is a reference point, 0 for a surface facing away from it, 1 for a surface facing it. With altitude the value is a weighted average of the slope and a gradient along the second vector, weighted by the lengths of the two vectors; lo_alt and hi_alt give the range of the gradient (default 0, 0 = 0 to 1). altitude cannot be combined with point_at and the parser marks it as experimental. If both vectors have length 0 the parser stops: “Zero length for both slope and gradient.” Equal lo and hi give the warning “Zero gradient range, ignoring.” |
facets | facets [coords s | size f] [metric m] | normals only (an error in a pigment: “Only in normal”). size (default 0.1) makes facets on curved surfaces; coords (default 0, off) makes facets of that size on any surface, following the cells of the crackle pattern; metric (default 2) is the distance metric |
These patterns need a surface; they have no value for a sky sphere or media.
Special patterns
average
average does not return a number. It blends all entries of its map. With a pigment map, texture map or density map the entries are weighted and divided by the sum of the weights. With a normal map the perturbed normals are weighted, added and normalised. The number in each entry is the weight and is optional (default 1). The parser stops with “Average must have map.” when there is no map, and color_map and slope_map are refused with it.
image_pattern
image_pattern {
[bitmap_type] "file" [gamma g] [premultiplied bool]
[map_type n] [once] [interpolate n]
[use_colour | use_index | use_alpha]
[repeat <u, v>] [offset <u, v>]
}
The grey value of the pixel (or the palette index with use_index, or the alpha with use_alpha) is the pattern value. The image fills the square <0,0> to <1,1> of the x-y plane. The keywords are the same as for image_map, see Textures and pigments. Instead of a file, function w, h { … } builds an image from a function, a pattern function or a pigment (the example below). An image pattern has frequency 0, so the wave type applies without a frequency.
user_defined
pigment {
user_defined {
function { red }, function { green }, function { blue },
function { filter }, function { transmit }
}
}
A pigment (or density) pattern that sets the colour directly. Each of the five functions is optional; a missing one is 0 (the commas stay, ,,). It cannot have a map. It is an error in a normal or texture (“Only in pigment or density”) and it is not accepted in a pattern function.
Plain colour and uv_mapping
A colour written where a pattern type is expected is the “plain” pattern: one colour, no pattern. Modifiers on it have no effect. uv_mapping inside a pigment, normal or texture turns the statement into a surface-coordinate pattern (see Textures and pigments).
Keywords that belong to one pattern
Using one of these keywords with another pattern is an error such as “Only in crackle” or “Not with non-agate”.
| Keyword | Pattern | Value | Default | Meaning |
|---|---|---|---|---|
agate_turb | agate | number | 1 | amount of the built-in turbulence |
brick_size | brick | vector | <8, 3, 4.5> | size of a brick with its mortar |
mortar | brick | number | 0.5 | thickness of the mortar |
control0, control1 | quilted | number | 1, 1 | curvature of the seams; keep to about 0 to 1 |
interpolate | density_file | 0, 1 or 2 | 0 | none, trilinear, tricubic |
form | crackle | vector | <-1, 1, 0> | multiples of the distances to the closest, second closest and third closest cell point that are added up. <1,0,0> is the distance to the closest point |
metric | crackle, facets | vector (first component used) | 2 | distance metric: 2 is Euclidean, 1 is Manhattan. Others are slower |
offset | crackle | number | 0 | shift along a fourth dimension; rounds off the points of cells |
repeat | crackle | vector of integers ≥ 0 | <0, 0, 0> | period along x, y, z; 0 means no repeat. A negative component is an error |
solid | crackle | none | off | one value for every point of a cell |
number_of_sides | pavement | 3, 4 or 6 | 3 | basic polygon of the tile |
number_of_tiles | pavement | integer | 1 | polygons in a tile; at most 6 for sides 3 and 4, at most 5 for sides 6 |
pattern | pavement | integer | 1 | which tile variant; the largest value is 1,1,1,3,4,12 (sides 3), 1,1,2,5,12,35 (sides 4), 1,1,3,7,22 (sides 6) for 1 to 6 tiles |
exterior, interior | pavement | 0, 1, 2 (taken modulo 3) | 0, 0 | shape of quick convex and of concave angles (exterior is not used for hexagons) |
form | pavement | integer | 0 | shape of slow convex angles (modulo 3; for squares modulo 4) |
exterior, interior, exponent | mandel, julia, magnet | see fractals | ||
coords, size, metric | facets | number | 0, 0.1, 2 | see above |
threshold | potential | bool | off | subtract the threshold from the potential |
Pattern modifiers
These can follow the pattern in a pigment, normal, texture and density.
| Modifier | Value | Default | Meaning |
|---|---|---|---|
frequency | number | 1 | repeats the map that many times per cycle of the pattern; negative reverses it. The value becomes fmod(value * frequency + phase, 1.00001); 0 skips this step. Not on block patterns (warning) |
phase | number | 0 | shifts the map along the pattern. Not on block patterns (warning) |
ramp_wave | default of most patterns | use the value unchanged | |
triangle_wave | marble, wood, spiral1, spiral2 | 0 to 1 and back to 0 | |
sine_wave | (1 + cycloidal(v)) / 2, a smooth roll | ||
scallop_wave | |cycloidal(v / 2)|, like corduroy | ||
cubic_wave | v² * (3 − 2v), an S curve with zero slope at both ends | ||
poly_wave | exponent (optional) | exponent 1 | v to the power of the exponent |
turbulence | number or vector | <0, 0, 0> | pushes the sample point about with noise (the “classic” turbulence). A single number is used for x, y and z. Always applied before the transformations, whatever the order in the text. Described at Textures and pigments |
octaves | integer | 6 | number of turbulence steps, clamped to 1 to 10. Needs turbulence to have an effect |
omega | number | 0.5 | size of each step compared to the one before |
lambda | number | 2.0 | how different the direction of each step is from the one before |
noise_generator | 1, 2 or 3 | 2 (or the value of global_settings) | 1: noise of POV-Ray 3.1, 2: range-corrected version, 3: Perlin noise. Another number is an error |
warp { … } | see warps | geometric distortion of the sample point; the order relative to other warps and transformations matters | |
translate, rotate, scale, matrix, transform | as for objects | move the pattern. Each becomes a transform step in the same list as the warps and is applied in the order written | |
no_bump_scale | off | the depth of normals is not changed by scaling (see Normals and finishes) | |
accuracy | number | 0.02 | normals only (an error elsewhere): the distance of the sample points used to find the slope of a pattern that has no normal of its own |
bump_size | number | 0.5 | normals only |
frequency, phase and the wave types have no effect on image_map, bump_map and material_map. The manual also states that the pattern-specific normals bumps, dents, quilted, ripples, waves, wrinkles ignore maps and wave types in a normal.
Blend maps
A map is a list of entries [ value item ]. The square brackets are part of the syntax. The pattern value (after the wave) is searched in the list: below the first entry the first item is used, at or above the last entry the last item is used, and between two entries the items are blended in proportion to the distance. Two entries with the same value make a hard edge: a value equal to that number gets the second one. Entries must be written in ascending order of value; the parser does not sort them. A comma after value is optional. At least one entry is needed (“Must have at least one entry in map.”); version 3.8 has no upper limit.
| Map | Entry | Used in | Blending |
|---|---|---|---|
color_map, colour_map | [ v colour ] | pigment, density | linear mix of the colours (see blend modes) |
pigment_map | [ v pigment body ] | pigment | both pigments are evaluated and the colours mixed; the same blend modes |
density_map | [ v density body ] | density | as pigment_map |
normal_map | [ v normal body ] | normal | the normals are mixed. Not with facets |
slope_map | [ v <height, slope> ] | normal | a cubic spline through heights and slopes. Not with average |
texture_map | [ v texture body ] | texture | both textures are fully evaluated and the results mixed |
An entry body is what could stand inside the braces of the statement, without the keyword and braces: [0.3 wood scale 0.2], [0.6 Jade] (an identifier), [0.9 pigment { rgb 1 } finish { phong 1 }] for a texture. A map can be declared and used by its identifier: color_map { Rainbow }. An identifier map must be of the same kind, otherwise “Wrong identifier type”.
Colour map entries
| Form | Meaning |
|---|---|
[0.3 rgb <1, 0, 0>] | normal entry; any colour: rgb, rgbf, rgbt, rgbft, a colour identifier, or a single number (grey) |
[0.3 rgbft <1, 0, 0, 0.5, 0>] and the same with transmit, filter | the fourth and fifth components are the filter and transmit values of the entry (see Textures and pigments) |
[0.0, 0.1 color Red color Red] | obsolete double entry: two values and two colours, equal to two normal entries |
Two entries that are exactly equal in value and colour next to each other are merged.
Blend modes
A color_map or pigment_map (also in a density) may start with these two items before the first entry:
| Item | Value | Default | Meaning |
|---|---|---|---|
blend_mode | 0 to 3 | 0 | 0: mix in the working gamma space (assumed_gamma); 1: mix in linear light; 2: mix in the gamma space given by blend_gamma; 3: mix the chromaticity in linear light and the brightness in the blend_gamma space. Another number is an error |
blend_gamma | number, srgb, bt709, bt2020 | 2.5 | the gamma for modes 2 and 3. It needs assumed_gamma in global_settings (“blend_gamma requires that assumed_gamma has been set.”) |
Both are errors in other maps (“Only in colour_map or pigment_map”).
Pattern functions
A pattern can be used as a function of x, y, z inside function { … }:
function { pattern { pattern [modifiers…] } }
The result is the number of the pattern after its wave type, before any map. These patterns are accepted: agate, bozo, bumps, cells, checker, brick, hexagon, cubic, object, crackle, cylindrical, dents, density_file, function, gradient, granite, image_pattern, julia, leopard, magnet, mandel, marble, onion, pavement, pigment_pattern, planar, potential, quilted, radial, ripples, spherical, spiral1, spiral2, spotted, tiling, boxed, waves, wood, wrinkles. Not accepted: square, triangular, slope, aoi, average, facets, image_map, bump_map, user_defined, uv_mapping, a plain colour, and the maps (the parser stops with a parse error for them). The modifiers are the same as above except that accuracy, bump_size and the maps are not accepted.
A pattern function can also be used as a pattern: pigment { function { MyFn(x, y, z) } color_map { … } }. A pigment can be turned into a function as well; its components are read with .red, .green, .blue, .filter, .transmit (see Functions and constants).
Examples
plane { y, 0
pigment {
gradient x
color_map {
[0 rgb <1, 0, 0>]
[1 rgb <0, 0, 1>]
}
triangle_wave
frequency 2
phase 0.25
}
}
sphere { 0, 1
pigment {
average
pigment_map {
[2 checker rgb 1, rgb 0 scale 0.25]
[1 gradient y color_map { [0 rgb <1, 0.5, 0>] [1 rgb <0, 0.5, 1>] }]
}
}
}
sphere { <2, 0, 0>, 1
pigment {
checker
pigment { rgb <1, 0, 0> }
pigment { wood scale 0.2 }
scale 0.5
}
}
#declare Cyl = function { pattern { cylindrical } }
#declare Grad = function { pattern { gradient x ramp_wave } }
#declare Wd = function { pattern { wood } }
#debug concat("cylindrical at (0.5, 3, 0): ", str(Cyl(0.5, 3, 0), 0, 3), "\n")
#debug concat("gradient at x = 1.25: ", str(Grad(1.25, 0, 0), 0, 3), "\n")
#debug concat("wood at x = 0.5: ", str(Wd(0.5, 0, 0), 0, 3), "\n")
sphere { 0, 1
pigment {
function { Cyl(x, y, z) * 0.5 + Wd(x, y, z) * 0.5 }
color_map { [0 rgb 0] [1 rgb 1] }
}
}
box { <-2, -2, 0>, <2, 2, 0.1>
pigment {
julia <0.353, 0.288>, 30
interior 1, 1
color_map {
[0 rgb 0]
[0.2 rgb x]
[0.4 rgb x + y]
[1 rgb 1]
}
}
}
box { <-2, -2, 0.2>, <2, 2, 0.3>
pigment {
mandel 25
exponent 3
exterior 7, 8
color_map { [0 rgb <0, 0, 0.3>] [1 rgb <1, 1, 0>] }
}
}
box { <-2, -2, 0.4>, <2, 2, 0.5>
pigment {
magnet 2 julia <0.5, 0.2>, 30
}
}
sphere { 0, 1
texture {
slope { y, 0.0, 0.5 }
texture_map {
[0 pigment { rgb <0.9, 0.9, 1> }]
[1 pigment { rgb <0.2, 0.5, 0.1> } finish { phong 0.3 }]
}
}
}
plane { y, -1
pigment {
image_pattern { function 16, 16 { pattern { checker } } interpolate 2 }
color_map { [0 rgb <1, 1, 0>] [1 rgb <0, 0, 1>] }
}
}
sphere { <2, 0, 0>, 0.7
pigment {
crackle form <1, 0, 0> metric 1 offset 0.1 repeat <3, 3, 3>
color_map { [0 rgb 0] [1 rgb 1] }
}
}
Internals and notes
- The parser keeps one list of “warps” for each pattern. Classic turbulence (
turbulence,octaves,omega,lambdaoutside awarp) is always the first item in the list. Eachtranslate,rotate,scale,matrixandtransformis merged into the last transform step, or added as a new one after awarp. The sample point passes through the list from first to last, and the result is looked up in the pattern. agate,marble,spiral1,spiral2andwoodhandle the classic turbulence themselves (the turbulence value is part of their formula);agatealways has turbulence settings, so a turbulence step is always present. For other patterns the classic turbulence moves the point before the pattern is evaluated.- Noise patterns (
bozo,spotted,bumps,granite,wrinkles,dents) depend onnoise_generator.cracklecaches data per unit cube (the manual gives 30 MB per thread) and discards new entries once the cache is full. - The default blend maps are used only when a pigment (or density) has a pattern but no map. A pattern with a map ignores them.
- The parser accepts
repeatandoffsetinimage_pattern(and in the other bitmaps), which the manual does not list. The manual gives other default colours forsquare(“red, blue, yellow and green”) andtriangular(“blue, green, red, magenta, cyan and yellow”) than the default colour list insource/core/material/pattern.cpp, which is the one in the table above.