From: Lukas Jiriste Date: Thu, 21 Nov 2024 21:47:22 +0000 (+0100) Subject: Implement the color calculation X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=fb9aa1624c137b50a476a9ac236142469b516996;p=42%2FminiRT.git Implement the color calculation Also reimplement the t_color as typedef of t_vec3 so that I can use the vec* operations on color. The t_color now signifies the linear RGB and needs to be converted to (and from) sRGB upon printing (reading). --- diff --git a/inc/miniRT.h b/inc/miniRT.h index 318eb3a..d2f0fef 100644 --- a/inc/miniRT.h +++ b/inc/miniRT.h @@ -22,20 +22,21 @@ typedef struct s_color_sRGB typedef struct s_sphere { + t_color color; t_vec3 center; double radius; - t_color color; } t_sphere; typedef struct s_plane { + t_color color; t_vec3 point; t_vec3 normal; - t_color color; } t_plane; typedef struct s_cylinder { + t_color color; t_vec3 center; t_vec3 rot_axis; double radius; @@ -44,9 +45,9 @@ typedef struct s_cylinder typedef struct s_light { - t_vec3 position; - double brightness; t_color color; + double brightness; + t_vec3 position; } t_light; typedef struct s_camera @@ -79,8 +80,8 @@ typedef struct s_object typedef struct s_ambient_light { - double brightness; t_color color; + double brightness; } t_ambient_light; typedef struct s_scene @@ -118,7 +119,6 @@ typedef struct s_session } t_session; t_ray get_camera_ray(int x, int y, const t_session *session); -t_color get_object_color(const t_ray *ray, const t_object *object); double get_intersection_arg_cylinder(const t_ray *ray, const t_cylinder *cylinder); t_color trace_ray(const t_ray *ray, const t_scene *scene); diff --git a/src/scene.c b/src/scene.c index e5def95..ffb58f9 100644 --- a/src/scene.c +++ b/src/scene.c @@ -65,6 +65,16 @@ double vec_scalar_mul(t_vec3 v, t_vec3 u) return (v.x * u.x + v.y * u.y + v.z * u.z); } +t_vec3 vec_elwise_mul(t_vec3 v, t_vec3 u) +{ + t_vec3 res; + + res.x = v.x * u.x; + res.y = v.y * u.y; + res.z = v.z * u.z; + return (res); +} + double vec_norm(t_vec3 vec) { return (sqrt(vec_scalar_mul(vec, vec))); @@ -163,7 +173,7 @@ double get_intersection_arg(const t_ray *ray, const t_object *object) return (get_intersection_arg_bounded(ray, object)); } -t_color trace_ray(const t_ray *ray, const t_scene *scene) +const t_object *find_nearest_object(const t_ray *ray, const t_vec *objects) { size_t i; const t_object *object_found; @@ -173,18 +183,60 @@ t_color trace_ray(const t_ray *ray, const t_scene *scene) object_found = NULL; distance_found = INFINITY; i = 0; - while (i < scene->objects.size) + while (i < objects->size) { - distance = get_intersection_arg(ray, ft_vec_caccess(&scene->objects, i)); + distance = get_intersection_arg(ray, ft_vec_caccess(objects, i)); if (0 < distance && distance < distance_found) { distance_found = distance; - object_found = ft_vec_caccess(&scene->objects, i); + object_found = ft_vec_caccess(objects, i); } ++i; } + return (object_found); +} + +t_color get_ambient_color(const t_object *object, const t_ambient_light *amb) +{ + return (vec_real_mul( + vec_elwise_mul(amb->color, object->object.plane.color), + amb->brightness)); +} + +t_color get_object_color(const t_ray *ray, const t_object *object, + const t_scene *scene) +{ + t_color result; + const t_light *light; + size_t i; + t_ray new_ray; + const t_object *obstruction; + + i = 0; + while (i < scene->lights.size) + { + light = ft_vec_caccess(&scene->lights, i); + new_ray.start = vec_add(ray->start, vec_real_mul(ray->direction, + get_intersection_arg(ray, object))); + new_ray.direction = vec_diff(light->position, new_ray.start); + obstruction = find_nearest_object(&new_ray, &scene->objects); + if (!obstruction || 1 < get_intersection_arg(&new_ray, obstruction) + || get_intersection_arg(&new_ray, obstruction) < 0) + result = vec_add(result, vec_real_mul(vec_elwise_mul(light->color, + object->object.plane.color), light->brightness)); + ++i; + } + result = vec_add(result, get_ambient_color(object, &scene->ambient_light)); + return (result); +} + +t_color trace_ray(const t_ray *ray, const t_scene *scene) +{ + const t_object *object_found; + + object_found = find_nearest_object(ray, &scene->objects); if (object_found) - return (get_object_color(ray, object_found)); + return (get_object_color(ray, object_found, scene)); else return (DEFAULT_COLOR); }