Fix "translucence" of surfaces
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 3 Jan 2025 13:17:58 +0000 (14:17 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 3 Jan 2025 13:17:58 +0000 (14:17 +0100)
The surfaces "glow" instead of reflect light. In other words the lights
and shadows that are seen from one side of a (eq.) plane are seen from
the other (unilluminated) side.
This commit makes it so the light only reflects.
The sphere needs to get self-obstruction implemented. On he inside it
does not cast its own shadow for now.

The test_scene now contains a green light inside the sphere to test the
interior rendering.

src/scene.c
test_scene.rt

index 290b404f384ca9aee7b27cd11ba06fc677069092..475002dc09257f17b39cdad7e354215e337f90a7 100644 (file)
@@ -278,22 +278,20 @@ t_vec3    get_object_normal(const t_object *object, t_vec3 point)
        return ((t_vec3){.x = 0, .y = 0, .z = 0});
 }
 
-t_color        get_light_contribution(t_vec3 point, const t_object *object, const t_light *light, const t_scene *scene)
+t_color        get_light_contribution(t_ray normal, const t_object *object, const t_light *light, const t_scene *scene)
 {
        t_ray                   new_ray;
        const t_object  *obstruction;
-       t_vec3                  normal;
        double                  angle_multiplier;
        double                  distance;
 
-       new_ray.start = point;
+       new_ray.start = normal.start;
        new_ray.direction = vec_diff(light->position, new_ray.start);
        distance = vec_norm(new_ray.direction);
        new_ray.direction = vec_real_mul(new_ray.direction, 1 / distance);
        obstruction = find_nearest_object(&new_ray, &scene->objects, object);
-       normal = get_object_normal(object, point);
-       angle_multiplier = vec_scalar_mul(normal, new_ray.direction)
-               / (vec_norm(normal) * vec_norm(new_ray.direction));
+       angle_multiplier = vec_scalar_mul(normal.direction, new_ray.direction)
+               / (vec_norm(normal.direction) * vec_norm(new_ray.direction));
        if (object->type == PLANE)
                angle_multiplier = fabs(angle_multiplier);
        if (angle_multiplier > 0 && (!obstruction
@@ -310,17 +308,23 @@ t_color   get_object_color(const t_ray *ray, const t_object *object,
                        const t_scene *scene)
 {
        t_color                 result;
+       t_ray                   normal_at_intersect;
        const t_light   *light;
        size_t                  i;
 
        result = (t_color){.x = 0, .y = 0, .z = 0};
+       normal_at_intersect.start = ray_point(ray, get_intersection_arg(ray, object));
+       normal_at_intersect.direction = get_object_normal(object, normal_at_intersect.start);
+       if (vec_scalar_mul(normal_at_intersect.direction, ray->direction) > 0)
+               normal_at_intersect.direction = vec_real_mul(normal_at_intersect.direction, -1);
        i = 0;
        while (i < scene->lights.size)
        {
                light = &((const t_element *)ft_vec_caccess(&scene->lights, i))->object.light;
-               result = vec_add(result, get_light_contribution(
-                                       ray_point(ray, get_intersection_arg(ray, object)),
-                                       object, light, scene));
+               if (vec_scalar_mul(normal_at_intersect.direction, vec_diff(light->position, normal_at_intersect.start)) > 0)
+                       result = vec_add(result, get_light_contribution(
+                                               normal_at_intersect,
+                                               object, light, scene));
                ++i;
        }
        result = vec_add(result, get_ambient_color(object, &scene->ambient_light));
index bbdf879116797c8b91af04904fd1d3427d51c78a..aac6168e3cdeabd10a78b78e4f9e543ba134d7c6 100644 (file)
@@ -2,6 +2,7 @@ L 3,0,0 0.4 255,0,0
 L 3,1,0 0.4 0,0,255
 C 0,0,0 1,0,0 90
 sp 3,0.5,-0.7 0.6 255,255,255
+L  3,0.5,-0.5 0.01 0,255,0
 pl 0,0,-1 0,0,1 255,255,255
 cy 3,-0.5,-0.7 0,0,1 0.5 0.6 255,255,255
 A 0.01 255,255,255