packages icon

         This is the second version of a simple ray tracer written  here  at
 RPI.   The  second  version expanded its capabilities with the inclusion of
 distributed ray tracing.  Detailed  information  on  what  distributed  ray
 tracing  is  can  be  found  in  the  paper  by Cook, Porter and Carpenter:
 "Distributed Ray Tracing", ACM Computer Graphics, Vol.18, Num.3, July 1984.
         New  capabilities include: Gloss (blurred reflection), translucency
 (blurred refraction), penumbras (area light sources), motion  blur,  square
 intersection  routine  and  a field of view options.  The eye can be in any
 position now and can look towards any direction.  Antialising can  also  be
 done  using  stochastic  sampling.   The  old  version  was also supporting
 reflections, refractions and shadows using spheres.          Here is a list
 of the files, and what does each file contain:

 bg.c:           bgcolor()       evaluates the background color for a  given
 ray.

 initialize.c:   initialize()    does some useful setup.

 intersect.c:    sphere()        Intersection   routine   with   a   sphere.
                 quad()          Intersection   routine   with   a   square.
                 intersect()     Main intersection routine  (calls  sphere()
 ).

 main.c:         main()          Main body of the program.

 readfile.c:     readfile()      Reads in the input data.

 shade.c:        shadow()        Calculates the existance of a  shadow  ray.
                 reflect()       Find       the      reflection      vector.
                 refract()       Find      the      refraction       vector.
                 shade()         Calculate Phong's shading function.

 trace.c:        quickcos()      Calculate a fast cos between 0 and pi /  2.
                 quickinvcos()   Calculate    a    fast    inverse   cosine.
                 rnd()           Random number generator between  0  and  1.
                 rand1()         Random  number  generator between -1 and 1.
                 grand()         Approximate    gaussian    random    number
 generator.                   sample_ray()    Take  a ray somewhere inside a
 solid   angle.                    trace_a_ray()   Trace   a   single   ray.
                 trace()         Trace  a  single  ray inside a solid angle.
                 raytrace()      Ray trace the whole picture.

 vector.c:       vadd()          vector                            addition.
                 vsub()          vector                         subtraction.
                 vneg()          vector                            negation.
                 svproduct()     scalar        -       vector       product.
                 vdot()          dot                                product.
                 vcross()        cross                              product.
                 norm()          normalize a vector.

 ray.h:          Include file for every file used in the raytracer.

 vector.h:       Include file for every file using vectors.



         The ray tracer is written so it can be easily understood (at  least
 that  version), and it is fully commented.  Nevertheless, probably it won't
 be understood by a newcomer.

         The format of the input file is as follows:

 <fov> <eye> <dir> <up> <time> <background> <iter> <light> <nos> <nosq> x  y
 z  r  [ambient]  [diff]  [spec]  refl  r  g  b  refr  r  g  b  width  index
         refl_diffuse refr_diffuse tx ty tz x y z x y  z  x  y  z  [ambient]
 [diff]  [spec]  refl  r  g  b  refr  r g b width index         refl_diffuse
 refr_diffuse tx ty tz

 where:

 fov             field of view eye             x y z components of  the  eye
 position   dir             x   y   z   components   of  the  eye  direction
 up              x y z components of the up vector time            start and
 end   time  of  the  picture  background      a  character  specifying  the
 background cuing as follows:                 n: no cuing.  Background has a
 constant   intensity   of  0.2                  x:  the  intensity  of  the
 background depends of the x direction.                  y: the intensity of
 the   background  depends  of  the  y  direction.                   z:  the
 intensity   of   the   background   depends    of    the    z    direction.
 iter            number   of  samples  per  pixel.   light           x  y  z
 components and solid angle of the light source.  nos             number  of
 spheres  nosq            number of squares [ambient]       r g b components
 of ambient [diff]          r g b components of diffuse [spec]          r  g
 b  components of specular refl r g b      reflection ratio and color of the
 reflection refr r g b      refraction ratio and  color  of  the  refraction
 width           specular width exponent index           index of refraction
 refl_diffuse    angle of diffusion when reflecting refr_diffuse    angle of
 diffusion when refracting tx ty tz        velocities on the specified axes.

 Hints:         Each frame is a snapsot of a given time  length.   The  time
 limits  are specified in the input file.  Each object has the capability to
 move during that time in a strait line.  Motion blur is then observed.   If
 you specify only one sample per pixel, then the blur won't be so good since
 it evaluates the color of the ray with only one try.  The more samples  the
 better,  altough  anything  more than 20 or 30 doesn't do any good.  5 is a
 good approximation.  You can produce penumbras by specifying  an  angle  in
 the light source.  That deviates from real life where each life has an area
 and the further away you  are  from  the  light  source,  the  smaller  the
 penumbras.   Here,  the  size  of the blurred shadow does not depend on the
 distance from the light source.  The refl_diffuse and refr_diffuse  produce
 non-sharp  reflections  and  refractions.   The  argument  is  in  degrees.
 Anything less than 15 or 20 is good, altough the closer to zero the  better
 you can see it.

 Known bugs:         Polygons appear completely shadowd if the order of  the
 vertices is not right.  I always forget which is the right order.


 ----         The square is defined by only 3 of its points.  The first  and
 the  second  vertices  specify  one  of  the sides, and the first and third
 specify the second.  If you assume that second and third  specify  a  side,
 then you probably won't get the right result.

         The format of the output file is simple.  In  the  beginning  there
 are  2  integers (that can be read with fread() on a SUN) showing xsize and
 ysize of the picture.  After that follow the  pixels  in  scan-line  order.
 Each  pixel  uses 3 bytes (one for red, green and blue), totalling 16777216
 colors.  You can change the format of that file to tailor your  needs.   It
 can be done easily by changing the funcion raytrace() in file trace.c


         If you want you can inform me with any bugs that the program  might
 have  or  any  features  that  you  want  the  upcoming  versions  to have.
                                                 Good luck!


         George         Kyriazis                  kyriazis@turing.cs.rpi.edu
         kyriazis@yy.cicg.rpi.edu