# Pigments as Functions

 At the fundamental level, a pigment pattern is something that supplies a colour value to every point in space. When we use the pattern to paint a pigment onto a surface, POV-Ray evaluates a numerical value at each point on the surface of the object and looks up the result in a colour_map to produce the colour of that point. It's possible to use the components of these colours as an isosurface function. If we choose the "red" component, then the surface is considered to exist wherever the red component of the pigment is equal to the isosurface threshold. ``` #declare F=function{pigment{ crackle turbulence 0.1 color_map { [0 rgb 1] [1 rgb 0] } scale 0.5 } } isosurface { function { F(x,y,z).red - 0.5 } max_gradient 5.5 contained_by{box{-1,1}} pigment {rgb .9} } ``` On its own a pigment function doesn't usually look like much of anything. ``` #declare F=function{pigment{ crackle turbulence 0.1 color_map { [0 rgb 1] [1 rgb 0] } scale 0.5 } } isosurface { function { x*x + y*y +z*z -1 + F(x,y,z).grey*0.3 } max_gradient 3.5 contained_by{sphere{0,R}} pigment {rgb .9} } ``` But when we add or subtract a pigment function to a shape like a sphere it's possible to produce interesting effects. This is the same pigment function as above, but this time 0.3 of it is added to a sphere instead of just the pigment being allowed to fill the contained_by object. ``` #declare F=function{pigment{ mandel 50 color_map { [0 rgb 0] [1 rgb 1] } scale 8 translate <-3,0,0> } } isosurface { function { y - F(x,z,y).grey*0.3 } contained_by{sphere{0,R}} open pigment {rgb .9} } ``` Pigment isosurfaces can be useful for landscapes. This canyon is made from a Mandelbrot pigment added to the y plane. Because the Mandelbrot pigment faces the z direction, I flipped the axes by using F(x,z,y) instead of F(x,y,z). The Mandelbrot pigment has, by default, a rather strange colour map which isn't suitable for our purposes, so color_map { [0 rgb 0] [1 rgb 1] } is used to disable the default colour map. These pigment isosurfaces can be used to give something like "greebles" and might make a nice surface for a spaceship hull. This version uses the crackle pigment with metric 0 and solid modifiers. ``` #declare P=pigment{ crackle metric 0 solid color_map { [0 rgb 1] [1 rgb 0.5] } scale 0.1 } #declare F = function{pigment {P}} function { x*x + y*y +z*z -1 +F(x,y,z).red*0.2 } ```  ``` #declare P=pigment{ cells color_map { [0 rgb 1] [1 rgb 0.5] } scale 0.1 } #declare F = function{pigment {P}} function { x*x + y*y +z*z -1 +F(x,y,z).red*0.1 } ``` This version produces a similar effect using the cells pattern, and runs very much faster. You don't always have to stick with simple colour maps like colour_map {[0 rgb 0] [1 rgb 1]}. These two surfaces were made with the leopard pigment by changing the colour map. For the first one, the insertion of [0.3 rgb 0] holds the pigment value at zero for a while, creating a flat zone from which the bumps rise sharply. I've used P(x,0,z) instead of P(x,y,z) to prevent changes in the function values above the plane which would otherwise cause blobs of surface to become detached. ``` #declare P=function{pigment{leopard colour_map{[0.0 rgb 0.0] [0.3 rgb 0.0] [1.0 rgb 1.0]} scale 0.1 }} function { y - P(x,0,z).red*0.4} ``` In the second one, I've changed the zero entry of the colour map to push up what would normally be the lowest part of the surface. ``` #declare P=function{pigment{leopard colour_map{[0.0 rgb 0.3] [0.1 rgb 0.0] [1.0 rgb 1.0]} scale 0.15 rotate y*45 }} function { y - P(x,0,z).red*0.4} ```