Implement the color calculation
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 21 Nov 2024 21:47:22 +0000 (22:47 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Sat, 23 Nov 2024 11:05:51 +0000 (12:05 +0100)
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).

inc/miniRT.h
src/scene.c

index 318eb3a18079912899d6cd38264cce56907a86f7..d2f0fef7a77442d25f911780b9511994667966d2 100644 (file)
@@ -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);
index e5def9582a24990f3dfca0756dfa97a86baff654..ffb58f9378fdc5e148e67ba3b264578bb1bef9a9 100644 (file)
@@ -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);
 }