Povray II: Basic Notions

ArticleCategory: [Choose a category for your article]

Graphics

AuthorImage:[Here we need a little image from you]

[Photo of the Author]

TranslationInfo:[Author and translation history]

original in es Antonio Castro

es to en Miguel A Sepulveda

AboutTheAuthor:[A small biography about the author]

Computer Science is my profession and also part of my free time. I like to share my hobby, as everyone probably does. I admit it! I am one of those strange characters who dislikes windoze.

Abstract:[Here you write a little summary]

This is the second article on a series about Povray. This time we review some general concepts and start describing the basic elements of the language

ArticleIllustration:[This is the title picture for your article]

[Illustration]

ArticleBody:[The article body]

Article's Images

All the images in this article have been reduced to thumbnail size and in JPEG format. Better quality images in full size GIF versions can be accessed by clicking on any of the thumbnail icons.

The animations were built in low resolution with only 15 frames in JPEG format. Limiting the resolution and size of the animation we hope to avoid using too much hard disk and making this article slow to download. Nevertheless, as always the sources for these images will also be provided and the readers have access to the tool 'pov' (discussed in the previous issue) that will render the images at any desired resolution, or allow readers to modify and experiment with the images.

If the reader has not installed Povray yet on their system, please follow the directions in the previous article in this series where we gave sufficient information on the location of the sources, installation and configuration of POVRAY.

Rendering Fundamentals

In the previous article we mentioned briefly the notion of ray tracing. Let us now explore this issue in more detail.

Rendering is the most complete technique to achieve a synthetic image. It tries to emulate in the most realistic but inexpensive manner the behavior of light and its visual effects on objects.

In our previous article we mentioned that the renderer computes the number of light rays, but interestingly enough the light source under this model behaves not as a source but as a sink, while the camera acts as the source of rays. There is a reason for this inversion of roles, if rays departed from the light source then there would be a great waste of computational time because out of all the rays that leave the light source only a very small number eventually reaches the camera. Following the points the image from the camera we are reducing the number of rays to only those which are relevant for the image. Each of the points in the image corresponds to a point in the hypothetical photosensitive film of our virtual camera. Every point is then processed independently. We have configured Povray to build the image and then visualize it with an external viewer. Had we configured Povray for SVGA then we could see that it is possible to view the image as it is being computed. This is done pixel by pixel, from left to right, top to bottom on the screen. The order is not coincidental. The most common output format for Povray is TGA 24 bits, which is constructed precisely in that order.

If anyone gets interested on configuring Povray for SVGA (I have not done it myself) the first thing that you will learn is that the speed of rendering depends on the region of the image, complex regions take longer than simpler regions. Zones with many objects take longer time to process than zones with one or none. For every impact of the rays into the objects the renderer calculates the effect on the light by looking at the position and color of the light source, its relative position with respect to the object's surface, as well as the texture of the object and other physical characteristics. The result of this calculation is specified in three RGB values that define the color and intensity of the point in the image.

A brief tour

The TGA 24bits format occupies a lot of space but is trivial to generate and easy to process.

Each pixel is given by three numbers of 8 bits that codify the RGB packet

8bits *3 = 24 bits; 2^24 = 16777216 (16 million colors)

To find out the width and height:

int w, h, i;
fseek(fi, 12L, SEEK_SET);
fread(&w, 2L, 1L, fi); /** pos 12 **/
fread(&h, 2L, 1L, fi); /** pos 14 **/

To read the first pixel:

fseek(fi, 16L, SEEK_SET); /** pos 16 **/
Blue=fgetc(fi);
Green=fgetc(fi);
Red=fgetc(fi);

This information should be sufficient to process some images and achieve a few interesting effects. If the reader has some experience with programming we propose the following exercises:

1) Brighten/Darken an image (white pixels are 255,255,255 and black pixels 0,0,0
2) Superimpose an image with a black background on top of another one using black as a transparent value
3) Blend two images by averaging color values
5) Enhance/reduce a given colour
6) Obtain the color histogram of an image (list of colors and their frequency)

All these operations can be accomplished using auxiliary programs often available on the web. Nevertheless, on some occasions we may need to apply a non trivial transformation to the image and this TGA format of 24 bits is very manageable.

End of Detour

The rays depart from a point in the film of the virtual camera but to calculate the resulting colour each ray determines whether it intercepts any of the objects in the scene. If it does the ray-tracing algorithm continues analyzing the characteristics of the object in the area reached by the ray. Then there is a very effective optimization technique for designing complex objects. It consists of defining a new invisible object that contains the first complex object. Generally the most common used container is an sphere, but boxes are also popular. The main goal here is to use the container to force the ray-tracer to approximate the complex object by using the container instead, arriving rays bounce off the invisible spherical container. This removes a great deal of the computational process. The primitive used is "bounce_by" and it is commented next to illustrate how well the ray-tracer works. We will see an example later on in the article when we treat complex figures.

The seven errors

As an illustration of the issues explored so far let us review an image created using several techniques and discuss them one by one

This scene is titled the "7 Errors"

7errores

Please notice that some of the features of the scene are odd:

  1. There is a single intense light source at the center of the ring and even though we are looking almost directly to that point the light source itself is invisible.
  2. The white sphere located behind the light source casts a large shadow on the sky. This reveals that instead of a "real sky" we have an inexpensive decoration.
  3. The sea surface shows some waves but they are constructed using a very thin flat surface. We have cut the flat surface to show that the border is a straight line without wave ripples.
  4. On a closer plane there are three boxes. The middle box does not cast a shadow.
  5. The lighting and shadows over the three boxes is very strange. What kind of lighting is being used? A direct light source? A diffuse light? Apparently each box has a different lighting environment.
  6. The glass ball appears to be solid at its left side but we removed a small section to the right and inserted an object to show that the ball is hollow.
  7. Looking at the scene in whole it becomes evident that there is a lack of atmospheric effects. The air is excessively "transparent". The color of the sea should be deep blue and diffuse towards the horizon. The white ball casts a conical umbra that leaves no trace on the air.

At this moment we can not really explain the details of the numerous techniques used. Our point with this example is to show the reader that ray tracers attempt to imitate natural phenomena but they are not always totally compliant with natural laws of physics because there is a high price to pay in terms of processing time for a greater degree of reality. Some techniques are mostly good to fix defects produced by others. What is most important is to find a balance between final result and processing time.

The Povray language

This series about Povray can not go beyond a superficial excursion of its possibilities. The Povray language is too extensive to be treated in depth in the series. For this reason at this moment we can only make a few remarks on the most important features of the language.

Often Povray permits use of a number of grammatical forms to accomplish the same result. This is due in part to the genesis of Povray, the actual syntax of Povray has profoundly changed from version to version. The current syntax is very much improved and perhaps will not suffer so many changes in the future. For compatibility reasons old syntax features are preserved in newer versions in its original or slightly modified form. An example of flexibility in the syntax are the rotations that we will examine shortly.

There is a compilation option that allows to process the input source file using previous versions of Povray.

For example:

To use in the same source file structures from versions 1, 2, or 3 simply add:

#version 1.0
.......
#version 2.0
.......
#version 3.0
.......


Amazingly this allows the developer to mix source code written in Povray 1.0, 2.0 or 3.0

There is already a very good manual on Povray so please refer to it. Here we will save time by pointing to most important features.

Comments, Declarations, Include files

Comments are written following the C++ style.

Example:

// This comment ends with a return line
/* This comment is contained within slash characters */

The elements starting with '#' are known as Language Directives. The most commonly used directives are '#declare' and '#include'.

Declaration syntax:

#declare IDENTIFIER = ITEM;

Example:

Declaration of multiple identifiers:

#declare Rows = 5;
#declare Count = Count+1;
#declare Here = <1,2,3>;
#declare White = rgb <1,1,1>;
#declare Cyan = color blue 1.0 green 1.0;
#declare Font_Name = "ariel.ttf"
#declare Ring = torus {5,1};
#declare Checks = pigment { checker White, Cyan };

The statement '#declare' can be used to store a great variety of elements: a rotation, texture, color, object, numerical values, ...

Another crucial element is include statements that allows you to include source file code fragments previously saved in other files.

By default the include directive searches the local directory for the file. If the file is not found it then passes to search the Library_Path.


We will use mainly two directories:

Library_Path=${POVRAY}/include // For the include files of Povray
Library_Path=${HOMEPOV}/include // For the user include files

This is what I have implemented in the new version of the script 'pov' to generate an appropriate initialization file. We will come back to this.

There is a collection of include files one has to be familiar with to get the maximum output from Povray. It is a library of resources that can be included in our code and also customized to the developers taste.


Some common include files:

#include "colors.inc"
#include "textures.inc"
#include "shapes.inc"
#include "finish.inc"
#include "glass.inc"
#include "metals.inc"
#include "stones.inc"
#include "woods.inc"
#include "atmos.inc"

Povray also has directives that implement loops and conditional statements. The first versions of Povray lacked directives for loops or conditionals, moreover the description of elements in the scene could appear in any order and as result the developer had to take a big mental departure from traditional programming languages. The order of declaration of elements in the scene is still irrelevant but the loops can save the developer from writing multitude of similar lines and the conditional lines let us for example define a scene according to the value of the 'clock' used in animations. When we discuss composite images in the next article we will give an example of conditional statements.

There are many more language directives (beginning with '#') but we insist that the two presented here (i.e '#declare' and '#include') are by far the most often used.

I will skip discussing language features that are very similar to other programming languages like constants of various types, logical operators, relation operators, operators for vectors, predefined functions, etc..

It is convenient to use at least one upper case character for identifiers labels in order to distinguish them from the reserved words of the language.

Basics about animations

Dealing with this issue so early on deserves a short explanation

It is often said that an image is worth a thousand words, and this is especially true when we try to explain the functionality of a ray tracer. We will try to illustrate abundantly each concept, otherwise the reader would be forced to write code to test the explanations using his own examples in order to follow the article. This is one of the main reason for including so many images in the Povray series. Our hope is that consulting the images included might be sufficient to remind the reader of the concept studied avoiding that you have to go through the text once more. Sometimes an image is not sufficient and instead we require a sequence of them to see small differences between images and special effects. This is why we see it justified to discuss animations at this moment.

Povray limits itself to generate a sequence of images and save them to the disk one at a time. For the moment we are only interested on a very simple method. The ray tracer will be launched several times passing each time a number that selects the image in the sequence to be produced. In order to re-launch multiple times Povray there are some nice options that can be added to the *.ini file specially thought for generating animations:

Initialization file example for animations :

Initial_Clock = 0.0
Final_Clock = 2.0
Initial_Frame = 1
Final_Frame = 200
Subset_Start_Frame = 51
Subset_End_Frame = 75

Since in our previous article we proposed a simple program to generate *.ini files thus making the use of Povray simple and convenient let us proceed to update it in order the allow the generation of animations.

The new script has an additional include directory that can be shared among several projects, '$HOME/dat/pov/include'. This would be the ideal location to place user libraries.

Pov ver 2.0

Example of an *.ini file:
-----------------------------------------------8<-----------------
#!/bin/bash
#####################################################################
#  Author: Antonio Castro Snurmacher  (Feb-1998)
#
#     pov (ver 2.0)
#
#     Esta versión esta dedicada a su inclusión en la
#     revista LinuxFocus  (freeware)
#
#  Esta version (2.0) incorpora posibilidad de generar animaciones
#
#  Requiere 'xv' e 'imagemagick (convert,animate) '
# 
#  Este programa puede ser utilizado, distribuido, y modificado
#  libremente pero siempre se deberá respetar la propiedad
#  intelectual de su autor. Esta cabecera debe ser conservada 
#  tal cual en todas las modificaciones. 
#
#  En caso de traduccion deberá conservarse el texto original de
#  esta cabecera y añadirse la traducción a 
#  continuación de ella.
#
#  El autor renuncia a todo tipo de beneficio 
#  económico y no se hace 
#  responsable de los posibles perjuicios derivados del uso del mismo. 
# 
#       This version is written for its inclusion in the              
#       magazine LinuxFocus (freeware)
#
#  This version (2.0) is capable of generating animations         
#
#  Requires 'xv' and 'imagemagick (convert,animate) '
# 
#  This program can be used, distribute and modified freely as long as
#  the copyright is respected. This header must be 
#  always included without  modifications. 
#
#  In case of translations preserve the original header text 
#  and add the translation
#  next.  
#
#  The author renounces to any kind of economic profit 
#  from this code and is not 
#  responsible for the possible damage derived from its use.
# 
#  E-mail ([email protected])
# 
#################################################################
uso(){
   echo "Usage: pov <project> <size=0..6> <quality=1..11> "
   echo "    [ <Initial_Frame> <Final_Frame>
<Initial_Clock> <Final_Clock>"
   echo "      [ <Subset_Start_Frame>
<Subset_End_Frame> ] ]"
   echo
   echo "0) 40x30     (STD/20) No backup"
   echo "1) 80x60     (STD/10) No backup"
   echo "2) 100x75    (STD/8)  No backup"
   echo "3) 200x150   (STD/4)"
   echo "4) 266x200   (STD/3)"
   echo "5) 320x200 *"
   echo "6) 400x300   (STD/2)"
   echo "7) 640x480 *"
   echo "8) 800x600 *   (STD)"
   echo "9) 1024x768 *"
   echo
   echo "Projects should be located in a directory within        "
   echo "${HOMEPOV} and the same base name for the directory and the"
   echo "main *.pov file will be used."
   echo "(STD) is the default standard resolution."
   echo
   exit 1
}

newversion(){
mv ${PREFIX}.pov.8.gz ${PREFIX}.pov.9.gz 2> /dev/null
mv ${PREFIX}.pov.7.gz ${PREFIX}.pov.8.gz 2> /dev/null
mv ${PREFIX}.pov.6.gz ${PREFIX}.pov.7.gz 2> /dev/null
mv ${PREFIX}.pov.5.gz ${PREFIX}.pov.6.gz 2> /dev/null
mv ${PREFIX}.pov.4.gz ${PREFIX}.pov.5.gz 2> /dev/null
mv ${PREFIX}.pov.3 ${PREFIX}.pov.4 2> /dev/null
mv ${PREFIX}.pov.2 ${PREFIX}.pov.3 2> /dev/null
mv ${PREFIX}.pov.1 ${PREFIX}.pov.2 2> /dev/null
cp ${PREFIX}.pov   ${PREFIX}.pov.1 
gzip ${PREFIX}.pov.4 2> /dev/null
}

#################################################
size(){
   export SAVE="yes"
   case  $1 in
      0) Width=40 ; Height=30; SAVE="no" ;;
      1) Width=80 ; Height=60  SAVE="no" ;;
      2) Width=100; Height=75  SAVE="no" ;;
      3) Width=200; Height=150;;
      4) Width=266; Height=200;;
      5) Width=320; Height=200;;
      6) Width=400 ;Height=300;;
      7) Width=640 ;Height=480;;
      8) Width=800 ;Height=600;;
      9) Width=1024;Height=768;;
      *) uso
   esac
}

quality(){
   case $1 in
   1) ;;
   2) ;;
   3) ;;
   4) ;;
   5) ;;
   6) ;;
   7) ;;
   8) ;;
   9) ;;
   10) ;;
   11) ;;
       *) uso
   esac
   export Quality=$1
}

#############################################################
Single(){ 
cat <<-FIN >> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
FIN
}

#############################################################
SubSet(){
cat <<-FIN >> ${PREFIX}.ini
   Subset_Start_Frame=$Subset_Start_Frame
   Subset_End_Frame=$Subset_End_Frame
FIN
}

#############################################################
Animation(){
cat <<-FIN >> ${PREFIX}.ini
   Output_File_Name=${PREFIX}.tga
   Initial_Frame=$Initial_Frame
   Final_Frame=$Final_Frame
   Initial_Clock=$Initial_Clock
   Final_Clock=$Final_Clock
FIN
if [ $NumParm = 9 ]
   then 
      SubSet
fi
cat <<-FIN >> ${PREFIX}.ini
   Pre_Scene_Command=rm -f \`ls --color=none ${PREFIX}*.tga.gif\`   
   Pre_Frame_Command=rm -f \`ls --color=none ${PREFIX}*.tga\`   
   Post_Frame_Command=convert %o %o.gif
FIN
}

####################### main ##############################
export HOMEPOV=${HOME}/dat/pov
export PROYECT=$1
export PREFIX=${HOMEPOV}/${PROYECT}/${PROYECT}
if [ $# != 3 ] && [ $# != 7 ] && [ $# != 9 ]
   then uso
fi
NumParm=$#
if [ $NumParm -le 3 ] && [ grep Clock ${PREFIX}.pov > /dev/null
2>&1 ]
   then 
      echo "No econtrado identificador Clock en el fuente"
      uso
fi
export POVRAY=/usr/local/apli/povray/povray3
size $2
quality $3
Initial_Frame=$4
Final_Frame=$5
Initial_Clock=$6
Final_Clock=$7
Subset_Start_Frame=$8
Subset_End_Frame=$9

NumClocks=`expr $Final_Clock - $Initial_Clock`
if [ $NumClocks -gt 0 ]
   then if [ $NumClocks -le 40 ]
           then export
DELAY=`expr 4000 / $NumClocks`
           else export
DELAY=100
        fi
   else export DELAY=4000
fi

if [ $SAVE = "yes" ]
   then newversion
fi
cat <<-FIN > ${PREFIX}.ini
   Width=$Width
   Height=$Height
   Quality=$Quality
   Library_Path=${POVRAY}/include
   Library_Path=${HOMEPOV}/include
   Input_File_Name=${PREFIX}.pov
   Output_to_File=on
   Output_File_Type=t
   verbose=on
FIN
if [ $NumParm = 3 ]
   then ## Single image
       Single
   else ## Animation
      Animation
fi
#montage ${PREFIX}.tga.* ; animate ${PREFIX}.

#   Output_File_Type=t
## Others height performace options ##
#   Antialias_Depth=3
#   Antialias=On
#   Antialias_Threshold=0.1
#   Jitter_Amount=0.5
#   Jitter=On

# Low nice value just in case you want to run other processes
nice -20 x-povray ${PREFIX}.ini 

if [ $SAVE != "yes" ]
    then echo "!! Attention  !! No backup generated. "
fi

---------------------------8<-----------------------------------

From time to time we will use utilities external to Povray. For example to visualize animations we will use the utilities "animate" and "convert" from imagemagick.

Once I asked Enrique Zanardi, the maintainer of the Povray package for Debian whether there was a modeler for Povray. He wrote:

I have used ScEd (also available in Debian). Once you get used to it, is very easy. It can be compiled using a Scheme interpreter so that users can define their own "tokens", no matter how complex. People also recommend Ac3D but I believe it is not free.

There is another method for generating animations. This methods was very popular with the first versions of Povray but it is still a valid option. It consists of an external program that generates a loop that launches Povray several times. During each iteration of the loop the program generates a file to be included through a '#include' statement in the main source, each of these files contains information about the current time.

Here is a C code fragment that demonstrates the second method:

-------------8<------------------------------------

for(Frame=1; Frame < UltimoFrame; Frame++){
   fi=fopen("pajaro.inc", "w");
   fprintf(fi, "#declare PosX_pajaro1 = %d\n",
         FuncionPosX_pajaro1(Frame));
   fprintf(fi, "#declare PosY_pajaro1 = %d\n",
         FuncionPosY_pajaro1(Frame));
   fprintf(fi, "#declare AnguloAlas_p1 = %d\n",
         FuncionAngAlas_p1(Frame));
   fclose(fi);
   sprintf(comando,"povray -ipajaro.pov -opajaro%04d.tga",Frame);
   system(comando);
}

-------------8<------------------------------------

In the following section we examine an example of animation that illustrates the specification of rotations and translations.

3D Transformations

A number of 3D transformations can be applied on an object. Furthermore objects can be a group and the same 3D transformations will apply to the ensemble as a whole, i.e. translations, rotations, scaling...

Position

The position of an object is determined by its coordinates <x,y,z >. It is common practice to define objects centered at the origin of coordinates.

Any object can be moved from it initial position to a well defined location <x,y,z > by using a translation. The best way to represent the data of a translation is through vectors. Vectors are very often used in POVRAY. A common shorthand notation for a vector with x, y and z components is <x, y, z> ; if all the components are identical then <24, 24, 24> = <24>. POVRAY predefines three vectors: x=<1,0,0> y=<0,1,0> and z=<0,0,1>. Then 3*y = <0,3,0> and -2*x = <-2,0,0>.

Often it is necessary to work with paper and pencil to plan were to place objects in an scene. It also helps to start from an initial guess and use POVRAY to generate images at low resolution and low quality so that by trial and error we can determine the best location for the objects.

The 3D transformations available in POVRAY are:

rotate <VECTOR>
scale <VECTOR>
translate <VECTOR>

Translational and rotational transformation are very useful for animations as well as for setting up objects in a complex scene

Translations

Any object can be moved to a different location by adding a vector which is calculated by subtracting the initial coordinates from the coordinates of the final location. Geometrically this vector of translation can be viewed as an arrow going from the initial location to the final location. Here is an example:

sphere { <2, 2, 2>, 10
pigment { White }
translate <-3> // Remember <-3> = <-3, -3, -3>
}

The result is an sphere of radius 10 centered at <-1,-1,-1>

Rotation

Objects can be rotated arround axis going through the center of coordinates. This is a common convention to express rotations and because of this objects (that should be represented centered at the origin) are first rotated to the appropriate orientation and then translated to the final location. Notice that the opposite order of operations (first translation and then rotation) would not yield the same result.

A rotation must be defined by specifying a rotation axis and an angle of rotation around that axis. The sense of rotation follows the left-hand rule (take your left hand with the thumb pointing along the positive direction of the axis and then close your fist, the direction of motion of the closing fist shows the direction of rotation).

There are two ways of defining a rotation in POVRAY: "axis * degrees" or " <n,n,n>" that represents three rotations about the X, Y and Z axis. Here are some examples:

rotate x * 45 = rotate <45, 0, 0>
rotate <45, -30, 20> = rotate x*45 rotate y*-30 rotate z*20
rotate 20*z = rotate z*20
rotate y*90 x*90 = rotate <0, 90, 0> rotate <90, 0, 0>
rotate y*90 x*90 != rotate <90, 90, 0>

The last example is not an equality and this is a case that often leads to errors. The order of rotations is very important. When using the notation <n,n,n> rotations are performed in the X, Y and Z order and whenever a different order is necessary one must concatenate several rotation instructions. We will use preferably the notation "axis * degrees". If desired the developer can use angles in radians by using the function "radians". There are many mathematical functions in POVRAY that facilitate the evaluation of mathematical arithmetic.


Scaling

The size of objects can be modified by using scaling transformations. Three numbers are used to scale the X, Y and Z directions of an object. This allows to increase, decrease and flatten an object.


Here is a way to build an ellipsoid using an sphere

sphere { <0,0,0>, 10
pigment { White }
scale <1,4,10>
}

Final notes about the 3D transformations.

Translation and scaling operations can be performed in any order. However the presence of a single rotation operation is enough to break the commutativity of the operations and thus order becomes very important. Here is a simple example to illustrate the importance of ordering with 3D transformations. It is a blue sphere rotating about is center and an external point. The axis of rotation at the center of the sphere is slightly declining in the horizon.



----------------------------------8<------------------------------
#include "colors.inc"
#include "textures.inc"
//##### To launch animation execute: ######
//# pov PlanetAzul 4 9 1 100 1 360 #
//###############################
#declare RY1 = clock * 5;
#declare RZ1 = 25;
#declare T1 = <5 ,0 ,0 >;
#declare RY2 = clock;

camera {
location < -5, 5, 15>
look_at < 0, -2, 0>
}

light_source { <-15, 15, 15> color White}

sphere { <0, 0, 0> 4
texture { Shadow_Clouds }
rotate y * RY1
rotate z * RZ1
translate T1 rotate y * RY2
}
----------------------------------8<------------------------------

To launch the animation we use the new version of 'pov' and execute:

./pov PlanetAzul 4 9 1 100 1 360

This is what the parameters mean:

  1. Source file PlanetAzul.pov
  2. Size 4 = (266x200)
  3. Quality 9 (the highest)
  4. Initial frame = 1
  5. Final frame = 100
  6. Clock's initial value = 1
  7. Clock's final value = 360

Next we show a few frames of the animation. It is not good enough for a realistic model of the planet Earth but it is sufficient as a metaphor

Example planetblue.jpg:

Planeta Azul

Lighting

Light sources are modeled as point sources in space. The point of light source has no dimensions and is invisible in the sense that a camera focus on it will show nothing. A light source is only perceived by its effects on nearby objects. By the default this point shines light in all directions, although it is possible to define spot lights (light irradiated as a cone). The default color is white and this attribute can also be change as well as the intensity of the light.

A scene may have one or more light sources in order to produce the appropriate lighting and shadows. However increasing the number of light sources means also to increase the amount of CPU used to generate the image.

Camera

The camera in POVRAY is an abstraction that permits to easily specify a view in the scene. A number of parameters control the camera and the view of the scene: field of view and angle and direction of the camera. There are several methods of defining a camera in POVRAY, the one used in our examples is very flexible and easy to use. Not all methods are equally useful. Some of the methods are not very intuitive and are still preserved in the POVRAY specification just for compatibility with older versions. The field of view of the camera controls the perspective of the scene.


Sources for the code in this article, pov2.tar.gz (40Kb)