diff options
Diffstat (limited to 'libdimension/raytrace.c')
-rw-r--r-- | libdimension/raytrace.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index 6cb6d8b..da78411 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -259,11 +259,7 @@ static dmnsn_color dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene, dmnsn_kD_splay_tree *kD_splay_tree, dmnsn_color color) { - dmnsn_intersection *intersection; - const dmnsn_texture *texture; - const dmnsn_pigment *pigment; - - intersection = dmnsn_kD_splay_search(kD_splay_tree, ray); + dmnsn_intersection *intersection = dmnsn_kD_splay_search(kD_splay_tree, ray); if (intersection) { /* Default to black if we have no texture/pigment */ @@ -271,13 +267,15 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene, if (scene->quality >= DMNSN_RENDER_PIGMENT) { /* Use the default texture if given a NULL texture */ - texture = intersection->texture ? intersection->texture - : scene->default_texture; + const dmnsn_texture *texture + = intersection->texture ? intersection->texture + : scene->default_texture; if (texture) { /* Use the default pigment if given a NULL pigment */ - pigment = texture->pigment ? texture->pigment - : scene->default_texture->pigment; + const dmnsn_pigment *pigment + = texture->pigment ? texture->pigment + : scene->default_texture->pigment; if (pigment) { color = (*pigment->pigment_fn)( @@ -288,6 +286,56 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene, } } + if (scene->quality >= DMNSN_RENDER_LIGHTS) { + dmnsn_color illum = dmnsn_color_mul(0.3, color); + + const dmnsn_light *light; + unsigned int i; + + for (i = 0; i < dmnsn_array_size(scene->lights); ++i) { + dmnsn_array_get(scene->lights, i, &light); + dmnsn_vector x0 = dmnsn_line_point(ray, intersection->t); + dmnsn_line shadow_ray = dmnsn_line_construct( + dmnsn_vector_add( + x0, + dmnsn_vector_mul(1.0e-6, dmnsn_vector_sub(light->x0, x0)) + ), + dmnsn_vector_sub(light->x0, x0) + ); + + dmnsn_intersection *shadow_caster + = dmnsn_kD_splay_search(kD_splay_tree, shadow_ray); + + if (!shadow_caster || shadow_caster->t > 1.0) { + dmnsn_vector object_normal = x0; + dmnsn_vector normal = dmnsn_vector_normalize( + dmnsn_vector_add( + dmnsn_vector_normalize(dmnsn_vector_sub(ray.x0, x0)), + dmnsn_vector_normalize(dmnsn_vector_sub(light->x0, x0)) + ) + ); + + illum = dmnsn_color_add( + dmnsn_color_mul( + dmnsn_vector_dot(normal, object_normal), + dmnsn_color_illuminate((*light->light_fn)(light, x0), color) + ), + illum + ); + illum = dmnsn_color_add( + dmnsn_color_mul( + 0.1*dmnsn_vector_dot(normal, object_normal), + dmnsn_color_illuminate((*light->light_fn)(light, x0), dmnsn_white) + ), + illum + ); + } + + dmnsn_delete_intersection(shadow_caster); + color = illum; + } + } + /* Delete the intersection */ dmnsn_delete_intersection(intersection); } |