home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 5
/
DATAFILE_PDCD5.iso
/
utilities
/
p
/
povray
/
Docs
/
texture
< prev
next >
Wrap
Text File
|
1991-09-17
|
6KB
|
214 lines
Persistence of Vision Raytracer
Adding new textures tutorial.
-----------------------------------
The textures that modify the color, transparency and surface normal of an
object are a very powerful and effective feature of the the PV-Ray
raytracer. They are the best and easiest way to achieve many visual effects.
The following text is a short and simple tutorial on how to add new
textures to PV-Ray. If you would like to experiment with
new textures without going to all this trouble I have added several new
"fill-in-the-blank" textures in the file TXTTEST.C. The work described here
has already been done for six new textures (PAINTED1, 2 & 3 BUMPY1, 2 & 3)
so you can try out new texture ideas without having to modify and recompile
the entire program.
The examples that follow describe how to add two new textures, NEW_COLOUR and
NEW_BUMP. Several source files must be modified to add new textures to
PV-Ray.
-----POVPROTO.H
POVPROTO.H contains all the function prototypes for STAR-Light. The first
step to creating a new texture is to add a function prototype for your
texture. It should be in the txttest.c section and in the form,
void new_colour PARAMS((DBL x, DBL y, DBL z, TEXTURE *Texture, COLOUR *Colour));
or
void new_bump PARAMS((DBL x, DBL y, DBL z, TEXTURE *Texture, VECTOR *normal));
depending on whether your function will modify the colour or the surface
normal.
-----FRAME.H
In frame.h the texture must be added to either the coloured texture
list or the perturb normal (bumpy) texture list in the form,
/* Coloured texture list */
#define NO_TEXTURE 0
#define COLOUR_TEXTURE 1
#define BOZO_TEXTURE 2
#define MARBLE_TEXTURE 3
...(list of textures)
#define NEW_COLOUR_TEXTURE 13 (last texture+1) <----
/* Perturb normal (bumpy) texture list */
#define NO_BUMPS 0
#define WAVES 1
#define RIPPLES 2
#define WRINKLES 3
#define BUMPS 4
...(list of textures)
#define NEW_BUMP 13 (last texture+1) <-----
The texture also needs a token definition for the parser. Add that
like this,
/* Token Definitions for Parser */
#define AGATE_TOKEN 0
#define ALL_TOKEN 1
#define ALPHA_TOKEN 2
#define AMBIENT_TOKEN 3
#define AMPERSAND_TOKEN 4
#define AT_TOKEN 5
...(token list)
#define BUMPY3_TOKEN 137
#define BUMPMAP_TOKEN 138
#define BUMPSIZE_TOKEN 139
#define NEW_COLOUR_TOKEN 140 <-----
#define NEW_BUMP_TOKEN 141 <-----
#define LAST_TOKEN 142 <----- LAST_TOKEN must be last number
-----TOKENIZE.C
Add your new keywords to the Reserved_Words structure in Tokenize.c in
correct alphabetical order.
struct Reserved_Word_Struct Reserved_Words [LAST_TOKEN] = {
AGATE_TOKEN, "AGATE",
ALL_TOKEN, "ALL",
ALPHA_TOKEN, "ALPHA",
...(long list of tokens)
LOOK_AT_TOKEN, "LOOK_AT",
MARBLE_TOKEN, "MARBLE",
METALLIC_TOKEN, "METALLIC",
NEW_BUMP_TOKEN, "NEW_BUMP", <-----
NEW_COLOUR_TOKEN, "NEW_COLOUR", <-----
OBJECT_TOKEN, "OBJECT",
...
WOOD_TOKEN, "WOOD",
WRINKLES_TOKEN, "WRINKLES"
};
-----PARSE.C
In parse.c the routine Parse_Texture() must be changed for your new texture.
The simplest way is to copy and modify an exsisting texture parse block. For
example the granite texture parsing,
CASE (GRANITE_TOKEN)
if (Texture->Constant_Flag) {
Texture = Copy_Texture (Texture);
Texture->Constant_Flag = FALSE;
}
Texture -> Texture_Number = GRANITE_TEXTURE;
END_CASE
, becomes new colour texture parsing by changing two lines
CASE (NEW_COLOUR_TOKEN) <-----
if (Texture->Constant_Flag) {
Texture = Copy_Texture (Texture);
Texture->Constant_Flag = FALSE;
}
Texture -> Texture_Number = NEW_COLOUR_TEXTURE; <-----
END_CASE
The syntax for NEW_COLOUR will be identical to granite and other textures
like marble, agate, etc.
New_bump is parsed the almost the same way, but the bumpy textures
parse a mandatory Bump_Amount value directly after the texture keyword...
CASE (RIPPLES_TOKEN)
if (Texture->Constant_Flag) {
Texture = Copy_Texture (Texture);
Texture->Constant_Flag = FALSE;
}
Texture -> Bump_Number = RIPPLES;
Texture -> Bump_Amount = Parse_Float ();
END_CASE
CASE (NEW_BUMP_TOKEN) <-----
if (Texture->Constant_Flag) {
Texture = Copy_Texture (Texture);
Texture->Constant_Flag = FALSE;
}
Texture -> Bump_Number = NEW_BUMP; <-------
Texture -> Bump_Amount = Parse_Float ();
END_CASE
The syntax for NEW_BUMP will be identical to ripples and other textures
such as bumps, dents, wrinkles, etc.
-----LIGHTING.C
Lighting.c is where your new texture is called from. Your texture has to
be added to the Colour_At() or the Perturb_Normal() function. Each of these
have a switch statement that calls the correct texture,
---Colour_At():
switch (Texture->Texture_Number) {
case NO_TEXTURE:
/* No colouring texture has been specified - make it black. */
Make_Colour (Colour, 0.0, 0.0, 0.0);
Colour -> Alpha = 0.0;
break;
case BOZO_TEXTURE:
Bozo (x, y, z, Texture, Colour);
break;
case MARBLE_TEXTURE:
marble (x, y, z, Texture, Colour);
break;
case NEW_COLOUR_TEXTURE: <-----
new_colour (x, y, z, Texture, Colour); <-----
break; <-----
}
---Perturb_Normal():
switch (Texture->Bump_Number) {
case NO_BUMPS:
break;
case WAVES:
waves (x, y, z, Texture, New_Normal);
break;
case RIPPLES:
ripples (x, y, z, Texture, New_Normal);
break;
case NEW_BUMP:
new_bump (x, y, z, Texture, New_Normal); <-----
break; <-----
}
Now everything is set up to add the actual routines NEW_COLOUR and NEW_BUMP
to txttest.c or a new file.
-----TXTTEST.C (or MYTXT.C or whatever)
Everything up to this point has been preparing the raytracer to
recognize your new texture keywords in the scene description file, store
a description of that texture for later retrieval and call the texture
code at the correct time. With all that work done the only thing left is
to write the routine that actually modifies the surface color or perturbs
the surface normal. The best way to learn how to do this is to study the
code in txtcolor.c and txtbump.c.
Good luck & have fun!
Drew Wells