|
|
1.3.4.10 Working With Layered Textures
With the multitudinous colors, patterns, and options for creating complex textures in POV-Ray, we can easily become
deeply engrossed in mixing and tweaking just the right textures to apply to our latest creations. But as we go, sooner
or later there is going to come that special texture. That texture that is sort of like wood, only varnished,
and with a kind of spotty yellow streaking, and some vertical gray flecks, that looks like someone started painting
over it all, and then stopped, leaving part of the wood visible through the paint.
Only... now what? How do we get all that into one texture? No pattern can do that many things. Before we panic and
say image map there is at least one more option: layered textures.
With layered textures, we only need to specify a series of textures, one after the other, all associated with the
same object. Each texture we list will be applied one on top of the other, from bottom to top in the order they
appear.
It is very important to note that we must have some degree of transparency (filter or transmit) in the pigments of
our upper textures, or the ones below will get lost underneath. We will not receive a warning or an error -
technically it is legal to do this: it just does not make sense. It is like spending hours sketching an elaborate
image on a bare wall, then slapping a solid white coat of latex paint over it.
Let's design a very simple object with a layered texture, and look at how it works. We create a file called LAYTEX.POV
and add the following lines.
#include "colors.inc"
#include "textures.inc"
camera {
location <0, 5, -30>
look_at <0, 0, 0>
}
light_source { <-20, 30, -50> color White }
plane { y, 0 pigment { checker color Green color Yellow } }
background { rgb <.7, .7, 1> }
box {
<-10, 0, -10>, <10, 10, 10>
texture {
Silver_Metal // a metal object ...
normal { // ... which has suffered a beating
dents 2
scale 1.5
}
} // (end of base texture)
texture { // ... has some flecks of rust ...
pigment {
granite
color_map {
[0.0 rgb <.2, 0, 0> ]
[0.2 color Brown ]
[0.2 rgbt <1, 1, 1, 1> ]
[1.0 rgbt <1, 1, 1, 1> ]
}
frequency 16
}
} // (end rust fleck texture)
texture { // ... and some sooty black marks
pigment {
bozo
color_map {
[0.0 color Black ]
[0.2 color rgbt <0, 0, 0, .5> ]
[0.4 color rgbt <.5, .5, .5, .5> ]
[0.5 color rgbt <1, 1, 1, 1> ]
[1.0 color rgbt <1, 1, 1, 1> ]
}
scale 3
}
} // (end of sooty mark texture)
} // (end of box declaration)
Whew. This gets complicated, so to make it easier to read, we have included comments showing what we are doing and
where various parts of the declaration end (so we do not get lost in all those closing brackets!). To begin, we
created a simple box over the classic checkerboard floor, and give the background sky a pale blue color. Now for the
fun part...
To begin with we made the box use the Silver_Metal texture as declared in textures.inc (for bonus
points, look up textures.inc and see how this standard texture was originally created sometime). To give
it the start of its abused state, we added the dents normal pattern, which creates the illusion of some denting in the
surface as if our mysterious metal box had been knocked around quite a bit.
The flecks of rust are nothing but a fine grain granite pattern fading from dark red to brown which then abruptly
drops to fully transparent for the majority of the color map. True, we could probably come up with a more realistic
pattern of rust using pigment maps to cluster rusty spots, but pigment maps are a subject for another tutorial
section, so let's skip that just now.
Lastly, we have added a third texture to the pot. The randomly shifting bozo texture gradually fades
from blackened centers to semi-transparent medium gray, and then ultimately to fully transparent for the latter half
of its color map. This gives us a look of sooty burn marks further marring the surface of the metal box. The final
result leaves our mysterious metal box looking truly abused, using multiple texture patterns, one on top of the other,
to produce an effect that no single pattern could generate!
1.3.4.10.1 Declaring Layered Textures
In the event we want to reuse a layered texture on several objects in our scene, it is perfectly legal to declare a
layered texture. We will not repeat the whole texture from above, but the general format would be something like this:
#declare Abused_Metal =
texture { /* insert your base texture here... */ }
texture { /* and your rust flecks here... */ }
texture { /* and of course, your sooty burn marks here */ }
POV-Ray has no problem spotting where the declaration ends, because the textures follow one after the other with no
objects or directives in between. The layered texture to be declared will be assumed to continue until it finds
something other than another texture, so any number of layers can be added in to a declaration in this fashion.
One final word about layered textures: whatever layered texture we create, whether declared or not, we must not
leave off the texture wrapper. In conventional single textures a common shorthand is to have just a pigment, or just a
pigment and finish, or just a normal, or whatever, and leave them outside of a texture statement. This shorthand does
not extend to layered textures. As far as POV-Ray is concerned we can layer entire textures, but not individual pieces
of textures. For example
#declare Bad_Texture =
texture { /* insert your base texture here... */ }
pigment { Red filter .5 }
normal { bumps 1 }
will not work. The pigment and the normal are just floating there without being part of any particular texture.
Inside an object, with just a single texture, we can do this sort of thing, but with layered textures, we would just
generate an error whether inside the object or in a declaration.
1.3.4.10.2 Another Layered Textures Example
To further explain how layered textures work another example is described in detail. A tablecloth is created to be
used in a picnic scene. Since a simple red and white checkered cloth looks entirely too new, too flat, and too much
like a tiled floor, layered textures are used to stain the cloth.
We are going to create a scene containing four boxes. The first box has that plain red and white texture we started
with in our picnic scene, the second adds a layer meant to realistically fade the cloth, the third adds some wine
stains, and the final box adds a few wrinkles (not another layer, but we must note when and where adding changes to
the surface normal have an effect in layered textures).
We start by placing a camera, some lights, and the first box. At this stage, the texture is plain tiling, not
layered. See file layered1.pov .
#include "colors.inc"
camera {
location <0, 0, -6>
look_at <0, 0, 0>
}
light_source { <-20, 30, -100> color White }
light_source { <10, 30, -10> color White }
light_source { <0, 30, 10> color White }
#declare PLAIN_TEXTURE =
// red/white check
texture {
pigment {
checker
color rgb<1.000, 0.000, 0.000>
color rgb<1.000, 1.000, 1.000>
scale <0.2500, 0.2500, 0.2500>
}
}
// plain red/white check box
box {
<-1, -1, -1>, <1, 1, 1>
texture {
PLAIN_TEXTURE
}
translate <-1.5, 1.2, 0>
}
We render this scene. It is not particularly interesting, is it? That is why we will use some layered textures to
make it more interesting.
First, we add a layer of two different, partially transparent grays. We tile them as we had tiled the red and white
colors, but we add some turbulence to make the fading more realistic. We add the following box to the previous scene
and re-render (see file layered2.pov ).
#declare FADED_TEXTURE =
// red/white check texture
texture {
pigment {
checker
color rgb<0.920, 0.000, 0.000>
color rgb<1.000, 1.000, 1.000>
scale <0.2500, 0.2500, 0.2500>
}
}
// greys to fade red/white
texture {
pigment {
checker
color rgbf<0.632, 0.612, 0.688, 0.698>
color rgbf<0.420, 0.459, 0.520, 0.953>
turbulence 0.500
scale <0.2500, 0.2500, 0.2500>
}
}
// faded red/white check box
box {
<-1, -1, -1>, <1, 1, 1>
texture {
FADED_TEXTURE
}
translate <1.5, 1.2, 0>
}
Even though it is a subtle difference, the red and white checks no longer look quite so new.
Since there is a bottle of wine in the picnic scene, we thought it might be a nice touch to add a stain or two.
While this effect can almost be achieved by placing a flattened blob on the cloth, what we really end up with is a
spill effect, not a stain. Thus it is time to add another layer.
Again, we add another box to the scene we already have scripted and re-render (see file layered3.pov ).
#declare STAINED_TEXTURE =
// red/white check
texture {
pigment {
checker
color rgb<0.920, 0.000, 0.000>
color rgb<1.000, 1.000, 1.000>
scale <0.2500, 0.2500, 0.2500>
}
}
// greys to fade check
texture {
pigment {
checker
color rgbf<0.634, 0.612, 0.688, 0.698>
color rgbf<0.421, 0.463, 0.518, 0.953>
turbulence 0.500
scale <0.2500, 0.2500, 0.2500>
}
}
// wine stain
texture {
pigment {
spotted
color_map {
[ 0.000 color rgb<0.483, 0.165, 0.165> ]
[ 0.329 color rgbf<1.000, 1.000, 1.000, 1.000> ]
[ 0.734 color rgbf<1.000, 1.000, 1.000, 1.000> ]
[ 1.000 color rgb<0.483, 0.165, 0.165> ]
}
turbulence 0.500
frequency 1.500
}
}
// stained box
box {
<-1, -1, -1>, <1, 1, 1>
texture {
STAINED_TEXTURE
}
translate <-1.5, -1.2, 0>
}
Now there is a tablecloth texture with personality.
Another touch we want to add to the cloth are some wrinkles as if the cloth had been rumpled. This is not another
texture layer, but when working with layered textures, we must keep in mind that changes to the surface normal must be
included in the uppermost layer of the texture. Changes to lower layers have no effect on the final product (no matter
how transparent the upper layers are).
We add this final box to the script and re-render (see file layered4.pov )
#declare WRINKLED_TEXTURE =
// red and white check
texture {
pigment {
checker
color rgb<0.920, 0.000, 0.000>
color rgb<1.000, 1.000, 1.000>
scale <0.2500, 0.2500, 0.2500>
}
}
// greys to "fade" checks
texture {
pigment {
checker
color rgbf<0.632, 0.612, 0.688, 0.698>
color rgbf<0.420, 0.459, 0.520, 0.953>
turbulence 0.500
scale <0.2500, 0.2500, 0.2500>
}
}
// the wine stains
texture {
pigment {
spotted
color_map {
[ 0.000 color rgb<0.483, 0.165, 0.165> ]
[ 0.329 color rgbf<1.000, 1.000, 1.000, 1.000> ]
[ 0.734 color rgbf<1.000, 1.000, 1.000, 1.000> ]
[ 1.000 color rgb<0.483, 0.165, 0.165> ]
}
turbulence 0.500
frequency 1.500
}
normal {
wrinkles 5.0000
}
}
// wrinkled box
box {
<-1, -1, -1>, <1, 1, 1>
texture {
WRINKLED_TEXTURE
}
translate <1.5, -1.2, 0>
}
Well, this may not be the tablecloth we want at any picnic we are attending, but if we compare the final box to the
first, we see just how much depth, dimension, and personality is possible just by the use of creative texturing.
One final note: the comments concerning the surface normal do not hold true for finishes. If a lower layer
contains a specular finish and an upper layer does not, any place where the upper layer is transparent, the
specular will show through.
|
|