home *** CD-ROM | disk | FTP | other *** search
-
- 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
-