77 * with parameters such as field of view, resolution, and sampling for anti-aliasing.
88 */
99
10+ #include " camera_cuda.h"
1011#include " constants.h"
1112#include " utils.h"
12- #include " camera_cuda.h"
1313
1414#include < atomic>
1515#include < chrono>
@@ -31,13 +31,13 @@ class Camera
3131 public:
3232 int image_width;
3333 int image_height;
34- double vfov = 35.0 ; // vertical field of view in degrees
34+ double vfov = 35.0 ; // Vertical field of view in degrees
3535 Point3 lookfrom = Point3(-2 , 2 , 5 ); // Point camera is looking from
3636 Point3 lookat = Point3(-2 , -0.5 , -1 ); // Point camera is looking at
3737 Vec3 vup = Vec3(0 , 1 , 0 ); // Camera-relative "up" direction
3838
39- int samples_per_pixel = 1 ;
40- const int max_depth = 24 ; // Maximum ray bounce depth
39+ int samples_per_pixel; // Number of samples per pixel for anti-aliasing
40+ const int max_depth = constants::MAX_DEPTH ; // Maximum ray bounce depth
4141
4242 std::atomic<long long > n_rays{0 }; // Number of rays traced so far with this cam (thread-safe)
4343
@@ -51,8 +51,6 @@ class Camera
5151
5252 Camera () : Camera(Vec3(0 , 0 , 0 ), 720, 3, 1) {}
5353
54- void set_samples_per_pixel (int new_samples_per_pixel) { samples_per_pixel = new_samples_per_pixel; }
55-
5654 void renderPixels (const Hittable &scene, vector<unsigned char > &image)
5755 {
5856
@@ -74,10 +72,10 @@ class Camera
7472 Vec3 ray_direction = pixel_center - camera_center;
7573
7674 // Create a ray from the camera center through the pixel
77- Ray r (camera_center, unit_vector (ray_direction));
75+ Ray ray (camera_center, unit_vector (ray_direction));
7876
7977 // And launch baby, launch the ray to get the color
80- Color sample (ray_color (r , scene, max_depth));
78+ Color sample (ray_color (ray , scene, max_depth));
8179 pixel_color += sample;
8280 }
8381
@@ -93,6 +91,69 @@ class Camera
9391 cout << endl;
9492 }
9593
94+ void renderPixelsParallel (const Hittable &scene, vector<unsigned char > &image)
95+ {
96+ const int num_threads = 72 ;
97+ std::vector<std::thread> threads (num_threads);
98+ std::mutex progress_mutex;
99+ int completed_rows = 0 ; // Track globally completed rows
100+
101+ auto render_chunk = [&](int start_y, int end_y)
102+ {
103+ for (int y = start_y; y < end_y; ++y)
104+ {
105+ for (int x = 0 ; x < image_width; ++x)
106+ {
107+ Color pixel_color (0 , 0 , 0 ); // The pixel color starts as black
108+
109+ // Supersampling anti-aliasing by averaging multiple samples per pixel
110+ for (int s = 0 ; s < samples_per_pixel; ++s)
111+ {
112+ // Random offsets in the range [0, 1) for jittering within the pixel
113+ double offset_x = RndGen::random_double ();
114+ double offset_y = RndGen::random_double ();
115+
116+ // Calculate the direction of the ray for the current pixel
117+ Vec3 pixel_center = pixel00_loc + (x + offset_x) * pixel_delta_u + (y + offset_y) * pixel_delta_v;
118+ Vec3 ray_direction = pixel_center - camera_center;
119+
120+ // Create a ray from the camera center through the pixel
121+ Ray ray (camera_center, unit_vector (ray_direction));
122+ Color sample (ray_color (ray, scene, max_depth));
123+ pixel_color += sample;
124+ }
125+
126+ pixel_color /= samples_per_pixel; // Average the samples
127+
128+ setPixel (image, x, y, pixel_color);
129+ }
130+
131+ // Update progress - increment global counter and show progress
132+ {
133+ std::lock_guard<std::mutex> lock (progress_mutex);
134+ completed_rows++;
135+ showProgress (completed_rows - 1 , image_height);
136+ }
137+ }
138+ };
139+
140+ int chunk_size = image_height / num_threads;
141+ for (int t = 0 ; t < num_threads; ++t)
142+ {
143+ int start_y = t * chunk_size;
144+ int end_y = (t == num_threads - 1 ) ? image_height : start_y + chunk_size;
145+ threads[t] = std::thread (render_chunk, start_y, end_y);
146+ }
147+
148+ for (auto &thread : threads)
149+ {
150+ thread.join ();
151+ }
152+
153+ showProgress (image_height - 1 , image_height);
154+ cout << endl;
155+ }
156+
96157 void renderPixelsCUDA (vector<unsigned char > &image)
97158 {
98159 auto start_time = std::chrono::high_resolution_clock::now ();
@@ -129,6 +190,20 @@ class Camera
129190 }
130191 }
131192
193+ void renderPixelsParallelWithTiming (const Hittable &scene, vector<unsigned char > &image)
194+ {
195+ auto start_time = std::chrono::high_resolution_clock::now ();
196+
197+ renderPixelsParallel (scene, image);
198+
199+ auto end_time = std::chrono::high_resolution_clock::now ();
200+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
201+
202+ cout << " Parallel rendering completed in " << duration.count () << " milliseconds" << endl;
203+ }
204+
205+
206+
132207#ifdef SDL2_FOUND
133208 void renderPixelsCUDART (vector<unsigned char > &image)
134209 {
@@ -251,77 +326,6 @@ class Camera
251326 }
252327#endif
253328
254- void renderPixelsParallelWithTiming (const Hittable &scene, vector<unsigned char > &image)
255- {
256- auto start_time = std::chrono::high_resolution_clock::now ();
257-
258- renderPixelsParallel (scene, image);
259-
260- auto end_time = std::chrono::high_resolution_clock::now ();
261- auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
262-
263- cout << " Parallel rendering completed in " << duration.count () << " milliseconds" << endl;
264- }
265-
266- void renderPixelsParallel (const Hittable &scene, vector<unsigned char > &image)
267- {
268- const int num_threads = 72 ;
269- std::vector<std::thread> threads (num_threads);
270- std::mutex progress_mutex;
271-
272- auto render_chunk = [&](int start_y, int end_y)
273- {
274- for (int y = start_y; y < end_y; ++y)
275- {
276- for (int x = 0 ; x < image_width; ++x)
277- {
278- Color pixel_color (0 , 0 , 0 ); // The pixel color starts as black
279-
280- // Supersampling anti-aliasing by averaging multiple samples per pixel
281- for (int s = 0 ; s < samples_per_pixel; ++s)
282- {
283- // Random offsets in the range [0, 1) for jittering within the pixel
284- double offset_x = RndGen::random_double ();
285- double offset_y = RndGen::random_double ();
286-
287- // Calculate the direction of the ray for the current pixel
288- Vec3 pixel_center = pixel00_loc + (x + offset_x) * pixel_delta_u + (y + offset_y) * pixel_delta_v;
289- Vec3 ray_direction = pixel_center - camera_center;
290-
291- // Create a ray from the camera center through the pixel
292- Ray r (camera_center, unit_vector (ray_direction));
293- Color sample (ray_color (r, scene, max_depth));
294- pixel_color += sample;
295- }
296-
297- pixel_color /= samples_per_pixel; // Average the samples
298-
299- setPixel (image, x, y, pixel_color);
300- }
301-
302- // Update progress
303- std::lock_guard<std::mutex> lock (progress_mutex);
304- showProgress (y, image_height);
305- }
306- };
307-
308- int chunk_size = image_height / num_threads;
309- for (int t = 0 ; t < num_threads; ++t)
310- {
311- int start_y = t * chunk_size;
312- int end_y = (t == num_threads - 1 ) ? image_height : start_y + chunk_size;
313- threads[t] = std::thread (render_chunk, start_y, end_y);
314- }
315-
316- for (auto &thread : threads)
317- {
318- thread.join ();
319- }
320-
321- showProgress (image_height - 1 , image_height);
322- cout << endl;
323- }
324-
325329 private:
326330 int image_channels = 3 ; // Number of color channels per pixel (e.g., 3 for RGB)
327331
@@ -335,28 +339,28 @@ class Camera
335339 {
336340 camera_center = lookfrom;
337341
338- // Determine viewport dimensions.
342+ // Determine viewport dimensions
339343 auto focal_length = (lookfrom - lookat).length ();
340344 auto theta = degrees_to_radians (vfov);
341345 auto h = tan (theta / 2 );
342346
343347 auto viewport_height = 2 * h * focal_length;
344348 auto viewport_width = viewport_height * (double (image_width) / image_height);
345349
346- // Compute camera basis vectors.
350+ // Compute camera basis vectors
347351 w = unit_vector (lookfrom - lookat);
348352 u = unit_vector (cross (vup, w));
349353 v = cross (w, u);
350354
351- // Calculate the vectors across the horizontal and down the vertical viewport edges.
355+ // Calculate the vectors across the horizontal and down the vertical viewport edges
352356 auto viewport_u = viewport_width * u;
353357 auto viewport_v = viewport_height * -v;
354358
355- // Calculate the horizontal and vertical delta vectors from pixel to pixel.
359+ // Calculate the horizontal and vertical delta vectors from pixel to pixel
356360 pixel_delta_u = viewport_u / image_width;
357361 pixel_delta_v = viewport_v / image_height;
358362
359- // Calculate the location of the upper left pixel.
363+ // Calculate the location of the upper left pixel
360364 auto viewport_upper_left = camera_center - (focal_length * w) - viewport_u / 2 - viewport_v / 2 ;
361365 pixel00_loc = viewport_upper_left + 0.5 * (pixel_delta_u + pixel_delta_v);
362366 }
@@ -376,20 +380,22 @@ class Camera
376380 if (world.hit (r, Interval (0.0001 , inf), rec))
377381 {
378382 // Display only normal
379- // return 0.5 * (rec.normal + color (1, 1, 1));
383+ return 0.5 * (rec.normal + Color (1 , 1 , 1 ));
380384
381- if (rec.isMirror )
382- {
383- Vec3 reflected = r.direction () - 2 * dot (r.direction (), rec.normal ) * rec.normal ;
384- return Color (1 , 0.85 , .47 ) * 0.2 + 0.8 * ray_color (Ray (rec.p , unit_vector (reflected)), world, depth - 1 );
385- }
385+ // if (rec.isMirror)
386+ // {
387+ // Vec3 reflected = r.direction() - 2 * dot(r.direction(), rec.normal) * rec.normal;
388+ // return Color(1, 0.85, .47) * 0.2 + 0.8 * ray_color(Ray(rec.p, unit_vector(reflected)), world, depth - 1);
389+ // }
386390
387391 auto new_ray = Vec3::random_in_hemisphere (rec.normal );
392+
393+ // A ray bounces and keeps only 70% of its color. It's a grey object.
394+ // If it returns 100%, it's white and if 0% it's black.
388395 return 0.7 * ray_color (Ray (rec.p , new_ray), world, depth - 1 );
389396 }
390397
391- // Le vecteur unit_direction variera entre -1 et +1 en x et y
392- // A blue to white gradient backgroun
398+ // A blue to white gradient universe, where unit_direction varies between -1 and +1 in x and y
393399 Vec3 unit_direction = unit_vector (r.direction ());
394400 float t = 0 .5f * (unit_direction.y () + 1 .0f );
395401 return (1 .0f - t) * Vec3 (1 .0f , 1 .0f , 1 .0f ) + t * Vec3 (0 .5f , 0 .7f , 1 .0f );
0 commit comments