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 of this series
where we gave sufficient information on the location of the sources,
installation and configuration of POVRAY.
Rendering Fundaments.
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 realistically 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 the leave the light source
only a very small number eventually reach 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 they 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 value RGB that define the color and intensity of the point in the image.
A brief detour
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 millon colours)
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 and 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 colour histogram of an image (list of colours 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
analysing 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 on 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 used 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"
Please notice that some of the features of the scene are odd:
-
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.
-
The white sphere located behind the light source casts a large shadow
on the sky. This reveals that instead of a "real sky" what we have
is an inexpensive decoration.
-
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.
-
On a closer plane there are three boxes. The middle box does not
cast a shadow.
-
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.
-
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 appreciate the ball
is hollow.
-
Looking at the scene in whole it becomes evident the 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 change 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 preserve 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 lets 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' lets store a great variety of elements:
a rotation, texture, color, object, numerical value, ...
Another crucial element are the include statements that allow
to include in our 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 how we 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 to define an 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 statement.
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
force 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 having to go through the
text once more. Sometimes an image is not sufficient and instead we require
a sequence of them to appreciate small differences between images and special
effects. This is why we see 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 select 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 writen 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 (acastro@ctv.es)
#
#####################################################################
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
Post_Scene_Command=xv ${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
Post_Scene_Command=animate -delay $DELAY \`ls -tr
--color=none ${PREFIX}*.tga.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 hight 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<----------------------------------------------&nb
sp; |
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 apply 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 move 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> &nb
sp;
// Remember <-3> = <-3, -3, -3>
}
The result is an sphere of radius 10 centered at <-1,-1,-1>
Rotation
Objects can be rotated about 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 about 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 sense 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 breaks 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 decline in the horizon
(this example remains me of something but I forget now).
----------------------------------8<------------------------------&nb
sp;
#include "colors.inc"
#include "textures.inc"
//##### To launch animation execute: ######
//# pov LF2-PlanetBue 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<------------------------------&nb
sp; |
To launch the animation we use the new version of 'pov' and execute:
pov LF2-PlanetBue 4 9 1 100 1 360
This is what the parameters mean:
-
Source file $HOME/dat/pov/LF2-PlanetBue/LF2-PlanetBue.pov
-
Size 4 = (266x200)
-
Quality 9 (the highest)
-
Initial frame = 1
-
Final frame = 100
-
Clock's initial value = 1
-
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
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. No 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 (3342
bytes)
translation Miguel A Sepulveda & Mark Kuchel
|