summaryrefslogtreecommitdiffstats
path: root/libdimension/raytrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension/raytrace.c')
-rw-r--r--libdimension/raytrace.c66
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);
}