diff options
Diffstat (limited to 'src/modules/ray/ray_scene.c')
-rw-r--r-- | src/modules/ray/ray_scene.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_scene.c index 955bab6..eb18d08 100644 --- a/src/modules/ray/ray_scene.c +++ b/src/modules/ray/ray_scene.c @@ -36,6 +36,26 @@ static inline int ray_is_obstructed(ray_scene_t *scene, ray_ray_t *ray, float di } +/* shadow test */ +static inline int point_is_shadowed(ray_scene_t *scene, ray_3f_t *light_direction, float distance, ray_3f_t *point) +{ + ray_ray_t shadow_ray; + + /* negate the light vector so it's pointed at the light rather than from it */ + shadow_ray.direction = ray_3f_negate(light_direction); + + /* we must shift the origin slightly (epsilon) towards the light to + * prevent spurious self-obstruction at the ray:object intersection */ + shadow_ray.origin = ray_3f_mult_scalar(&shadow_ray.direction, 0.00001f); + shadow_ray.origin = ray_3f_add(&shadow_ray.origin, point); + + if (ray_is_obstructed(scene, &shadow_ray, distance)) + return 1; + + return 0; +} + + /* a faster powf() that's good enough for our purposes. * XXX: note there's a faster technique which exploits the IEEE floating point format: * https://github.com/ekmett/approximate/blob/master/cbits/fast.c#L185 @@ -64,19 +84,10 @@ static inline ray_color_t shade_ray(ray_scene_t *scene, ray_ray_t *ray, ray_obje ray_3f_t lvec = ray_3f_sub(&scene->lights[i].light.emitter.point.center, &intersection); float ldist = ray_3f_length(&lvec); float lvec_normal_dot; - ray_ray_t shadow_ray; lvec = ray_3f_mult_scalar(&lvec, (1.0f / ldist)); /* normalize lvec */ #if 1 - /* skip this light if it's obstructed, - * we must shift the origin slightly towards the light to prevent - * spurious self-obstruction at the ray:object intersection */ - /* negate the light vector so it's pointed at the light rather than from it */ - shadow_ray.direction = ray_3f_negate(&lvec); - shadow_ray.origin = ray_3f_mult_scalar(&shadow_ray.direction, 0.00001f); - shadow_ray.origin = ray_3f_add(&shadow_ray.origin, &intersection); - - if (ray_is_obstructed(scene, &shadow_ray, ldist)) + if (point_is_shadowed(scene, &lvec, ldist, &intersection)) continue; #endif lvec_normal_dot = ray_3f_dot(&normal, &lvec); |