From 59b96f25f0d8e277c4f5267d923056a37baa302e Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Fri, 3 Jan 2025 14:17:58 +0100 Subject: [PATCH] Fix "translucence" of surfaces 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 | 22 +++++++++++++--------- test_scene.rt | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/scene.c b/src/scene.c index 290b404..475002d 100644 --- a/src/scene.c +++ b/src/scene.c @@ -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)); diff --git a/test_scene.rt b/test_scene.rt index bbdf879..aac6168 100644 --- a/test_scene.rt +++ b/test_scene.rt @@ -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 -- 2.30.2