This project is an introduction to the beautiful world of Raytracing. Once completed you will be able to render simple Computer-Generated-Images and you will never be afraid of implementing mathematical formulas again.
To accurately render a two-dimensional image of a three-dimensional scene, global illumination information that affects the intensity of each pixel of the image must be known at the time the intensity is calculated. In a simplified form, this information is stored in a tree of “rays” extending from the viewer to the first surface encountered and from there to other surfaces and to the light sources. A visible surface algorithm creates this tree for each pixel of the display and passes it to the shader. The shader then traverses the tree to determine the intensity of the light received by the viewer. Consideration of all of these factors allows the shader to accurately simulate true reflection, shadows, and refraction, as well as the effects simulated by conventional shaders. Anti-aliasing is included as an integral part of the visibility calculations. Surfaces displayed include curved as well as polygonal surfaces.
Turner Whitted : An Improved illumination model for shaded display Communications of the ACM June 1980 volume 23 Number 6.
operations | Array of Doubles arg passed by ref | Array of Floats arg passed by ref | 3 double escalars arg passed by ref | 3 float escalars arg passed by ref | 3 float escalars arg passed by copy |
---|---|---|---|---|---|
10 000 000 | typedef struct s_vec3 { double e[3]; } t_vec3; |
typedef struct s_vec3 { float e[3]; } t_vec3; |
typedef struct s_vec3 { double x; double y; double z; } t_vec3; |
typedef struct s_vec3 { float x; float y; float z; } t_vec3; |
typedef struct s_vec3 { float x; float y; float z; } t_vec3; |
sums | 47 | 60 | 60 | 58 | 131 |
subs | 44 | 65 | 58 | 58 | 105 |
mult | 45 | 47 | 50 | 52 | 98 |
dots | 39 | 39 | 38 | 38 | 36 |
cross | 110 | 109 | 109 | 109 | 97 |
According to this table of times in milliseconds, an array of doubles passed by reference cd float performs better.
An ambient light must NOT influence the object's color.
In the first approach, We tested it with nine images, changing ambient light intensity from 0.1 to 0.9 in 0.1 steps. First, we tested with a plane. Second, we tested with a sphere
However, the discussion with 42 peers showed our approach was wrong. We change it to impact only the background color.
Starting with a black background color, increasing blue ambient light intensity produces this image.
Testing with red ambient light, we got.
01.- self->coor=coor
02.- self->novec= novec_unit
03.- self->hfov = hfov;
04.- self->aspect_ratio = ASPECT_RATIO_W / ASPECT_RATIO_H
05.- self->image_width = WINDOW_W
06.- self->image_height = self->image_width / self->aspect_ratio
07.- self->samples_per_pixel = 20
08.- self->max_depth = 10
09.- self->vfov = hfov
10.- self->pixel_samples_scale = 1.0 / self->samples_per_pixel
11.- self->lookfrom = self->coor
12.- self->lookat = self->lookfrom + self->novec
13.- self->vup = (0,1,0)
14.- self->focal_lenght = length(self->coor)
15.- self->theta = (self->vfov * M_PI) / 180.0
16.- self->h = tan(self->theta / 2)
17.- self->viewport_height = 2 * self->h * self->focal_lenght;
18.- self->viewport_width = self->viewport_height * ((double)self->image_width / self->image_height)
19.- self->w = novec_unit
20.- self->u = self->w cross self->vup
21.- self->v = self->w cross &self->u
22.- self->vp_v = -(self->v) times self->viewport_height
23.- self->vp_u = &self->u, self->viewport_width
24.- self->pd_u = self->vp_u / self->image_width
25.- self->pd_v = self->vp_v / self->image_height
26.- self->vp_ul = self->center - ((self->vp_u / 2) + (self->vp_v / 2) + (self->w times self->focal_lenght))
27.- self->pixel00_loc = &self->vp_ul + (self->pd_u + self->pd_v) / 2
28.- self->color_start, 0.5, 0.7, 0.5;
29.- self->color_end, 0.0, 0.0, 0.0;
03.- self->hfov = hfov;
09.- self->vfov = hfov
15.- self->theta = (self->vfov * M_PI) / 180.0
16.- self->h = tan(self->theta / 2)
17.- self->viewport_height = 2 * self->h * self->focal_lenght;
18.- self->viewport_width = self->viewport_height * ((double)self->image_width / self->image_height)
22.- self->vp_v = -(self->v) times self->viewport_height
23.- self->vp_u = &self->u, self->viewport_width
24.- self->pd_u = self->vp_u / self->image_width
25.- self->pd_v = self->vp_v / self->image_height
26.- self->vp_ul = self->center - ((self->vp_u / 2) + (self->vp_v / 2) + (self->w times self->focal_lenght))
27.- self->pixel00_loc = &self->vp_ul + (self->pd_u + self->pd_v) / 2
14.- self->focal_lenght = length(self->coor)
17.- self->viewport_height = 2 * self->h * self->focal_lenght;
18.- self->viewport_width = self->viewport_height * ((double)self->image_width / self->image_height)
22.- self->vp_v = -(self->v) times self->viewport_height
23.- self->vp_u = &self->u, self->viewport_width
24.- self->pd_u = self->vp_u / self->image_width
25.- self->pd_v = self->vp_v / self->image_height
26.- self->vp_ul = self->center - ((self->vp_u / 2) + (self->vp_v / 2) + (self->w times self->focal_lenght))
27.- self->pixel00_loc = &self->vp_ul + (self->pd_u + self->pd_v) / 2
I found very convenient conditional breapoint in this project. It help me to stop the execution at object hitting coordinates to explore this part of code.
break is_scene4.c:71 if ((wy0 == 300) && (wx0 ==600))
I combined it with info break
and disable/enable break n
to
activate/desactivate breakppoitns at convenience.