Fix shadow casting
authorLukáš Jiřiště <jiriste@icpf.cas.cz>
Wed, 27 Nov 2024 09:08:03 +0000 (10:08 +0100)
committerLukáš Jiřiště <jiriste@icpf.cas.cz>
Wed, 27 Nov 2024 09:08:03 +0000 (10:08 +0100)
The shadows did not work because the obstruction detection used a
function that expects ray with normalized direction vector. But the
obstruction detection did not normalize its ray because the check for
whether the obstruction is between the object and the light was easier.
The fix is normalizing the ray vector and using distance.

src/scene.c

index b7cc7aa08c8fdec4c19393df5102aac12861b9c2..005b996040da7391125c2f8e8d2590048b5be2b3 100644 (file)
@@ -283,9 +283,12 @@ t_color    get_light_contribution(t_vec3 point, const t_object *object, const t_lig
        const t_object  *obstruction;
        t_vec3                  normal;
        double                  angle_multiplier;
+       double                  distance;
 
        new_ray.start = point;
        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)
@@ -293,7 +296,7 @@ t_color     get_light_contribution(t_vec3 point, const t_object *object, const t_lig
        if (object->type == PLANE)
                angle_multiplier = fabs(angle_multiplier);
        if (angle_multiplier > 0 && (!obstruction
-                       || 1 < get_intersection_arg(&new_ray, obstruction)
+                       || distance < get_intersection_arg(&new_ray, obstruction)
                        || get_intersection_arg(&new_ray, obstruction) < 0))
                return (vec_real_mul(
                                        vec_elwise_mul(light->color, object->object.plane.color),