rt.c (2285B)
1 #include "rt.h" 2 3 extern inline void 4 world_init(struct world *world); 5 6 extern inline void 7 world_push(struct world *world, struct hittable *hittable); 8 9 inline color_t 10 ray_color(struct ray *ray, struct list_node *objects) 11 { 12 struct hit_record hit_record; 13 struct interval t = { .min = 0, .max = INFINITY, }; 14 int hit_something = 0; 15 16 struct hittable *it; 17 LIST_ENTRY_ITER(objects, it, list_node) { 18 if (it->impl(it, ray, t, &hit_record)) { 19 hit_something = 1; 20 t.max = hit_record.t; 21 } 22 } 23 24 if (hit_something) { 25 return VEC3MULS(color_t, 26 VEC3ADDS(vec3f_t, hit_record.normal, 1), 0.5); 27 } 28 29 vec3f_t unit_direction = VEC3UNIT(ray->direction); 30 float a = 0.5 * (unit_direction.xyz.y + 1); 31 return VEC3LERP(VEC31(color_t), VEC3(color_t, 0, 0, 1), a); 32 } 33 34 void 35 render(pixel_t *image, size_t image_width, size_t image_height, struct world *world) 36 { 37 // camera 38 float aspect_ratio = (float) image_width / image_height; 39 40 float focal_length = 1.0; 41 42 vec3f_t camera_centre = VEC30(vec3f_t); 43 44 float viewport_width = 4.0, viewport_height = viewport_width / aspect_ratio; 45 vec3f_t viewport_u = VEC3(vec3f_t, +viewport_width, 0, 0); 46 vec3f_t viewport_v = VEC3(vec3f_t, 0, -viewport_height, 0); 47 vec3f_t pixel_du = VEC3DIVS(vec3f_t, viewport_u, image_width); 48 vec3f_t pixel_dv = VEC3DIVS(vec3f_t, viewport_v, image_height); 49 50 vec3f_t viewport_origin = VEC3SUB(vec3f_t, 51 VEC3SUB(vec3f_t, 52 VEC3SUB(vec3f_t, camera_centre, VEC3(vec3f_t, 0, 0, focal_length)), 53 VEC3DIVS(vec3f_t, viewport_u, 2)), 54 VEC3DIVS(vec3f_t, viewport_v, 2)); 55 56 vec3f_t pixel00 = VEC3ADD(vec3f_t, 57 viewport_origin, 58 VEC3MULS(vec3f_t, VEC3ADD(vec3f_t, pixel_du, pixel_dv), 0.5)); 59 60 // rendering 61 for (size_t j = 0; j < image_height; j++) { 62 fprintf(stderr, "Scanline: %zu/%zu\n", j, image_height); 63 for (size_t i = 0; i < image_width; i++) { 64 vec3f_t pixel_centre = VEC3ADD(vec3f_t, 65 pixel00, 66 VEC3ADD(vec3f_t, 67 VEC3MULS(vec3f_t, pixel_du, i), 68 VEC3MULS(vec3f_t, pixel_dv, j))); 69 70 vec3f_t ray_direction = VEC3SUB(vec3f_t, pixel_centre, camera_centre); 71 72 struct ray ray = { .origin = camera_centre, .direction = ray_direction, }; 73 color_t color = ray_color(&ray, &world->objects); 74 75 image[j * image_width + i] = pixel_from_color(color, PIXEL_FORMAT_ARGB32); 76 } 77 } 78 }