From 319491781c1389d82897075b6d890e74d82a08a9 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 9 Nov 2009 15:01:22 -0500 Subject: Calculate surface normals in intersection callbacks. --- libdimension/dimension/object.h | 3 +++ libdimension/kD_splay_tree.c | 12 ++++++++++-- libdimension/objects.c | 10 +++++++++- libdimension/raytrace.c | 9 +-------- tests/libdimension/tests.c | 4 ++-- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h index 0f53406..0393d94 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -31,6 +31,9 @@ typedef struct { dmnsn_line ray; double t; + /* The surface normal at the intersection point */ + dmnsn_vector normal; + /* The texture at the intersection point */ const dmnsn_texture *texture; } dmnsn_intersection; diff --git a/libdimension/kD_splay_tree.c b/libdimension/kD_splay_tree.c index 5c6289d..77e57dd 100644 --- a/libdimension/kD_splay_tree.c +++ b/libdimension/kD_splay_tree.c @@ -304,10 +304,12 @@ dmnsn_kD_splay_search_recursive(dmnsn_kD_splay_node *node, dmnsn_line ray, dmnsn_intersection * dmnsn_kD_splay_search(dmnsn_kD_splay_tree *tree, dmnsn_line ray) { - dmnsn_kD_splay_search_result result; - result = dmnsn_kD_splay_search_recursive(tree->root, ray, -1.0); + dmnsn_kD_splay_search_result result + = dmnsn_kD_splay_search_recursive(tree->root, ray, -1.0); + if (result.node) dmnsn_kD_splay(tree, result.node); + return result.intersection; } @@ -353,6 +355,12 @@ dmnsn_kD_splay_search_recursive(dmnsn_kD_splay_node *node, dmnsn_line ray, result.node = node; result.intersection = result_temp.intersection; t = result.intersection->t; + + /* Transform the normal vector back to the observer's view */ + result.intersection->normal = dmnsn_matrix_vector_mul( + node->object->trans, + result.intersection->normal + ); } else { dmnsn_delete_intersection(result_temp.intersection); } diff --git a/libdimension/objects.c b/libdimension/objects.c index 721d04d..b5e4a32 100644 --- a/libdimension/objects.c +++ b/libdimension/objects.c @@ -71,6 +71,7 @@ dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line) intersection = dmnsn_new_intersection(); intersection->ray = line; intersection->t = t; + intersection->normal = dmnsn_line_point(line, t); intersection->texture = sphere->texture; } } @@ -114,7 +115,7 @@ static dmnsn_intersection * dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) { double t = -1.0, t_temp; - dmnsn_vector p; + dmnsn_vector p, normal; dmnsn_intersection *intersection = NULL; /* Six ray-plane intersection tests (x, y, z) = +/- 1.0 */ @@ -127,6 +128,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(-1.0, 0.0, 0.0); } /* x = 1.0 */ @@ -136,6 +138,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(1.0, 0.0, 0.0); } } @@ -147,6 +150,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(0.0, -1.0, 0.0); } /* y = 1.0 */ @@ -156,6 +160,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(0.0, 1.0, 0.0); } } @@ -167,6 +172,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(0.0, 0.0, -1.0); } /* z = 1.0 */ @@ -176,6 +182,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) && t_temp >= 0.0 && (t < 0.0 || t_temp < t)) { t = t_temp; + normal = dmnsn_vector_construct(0.0, 0.0, 1.0); } } @@ -183,6 +190,7 @@ dmnsn_cube_intersection_fn(const dmnsn_object *cube, dmnsn_line line) intersection = dmnsn_new_intersection(); intersection->ray = line; intersection->t = t; + intersection->normal = normal; intersection->texture = cube->texture; } diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index dc017f5..262929f 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -307,7 +307,7 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene, = dmnsn_kD_splay_search(kD_splay_tree, shadow_ray); if (!shadow_caster || shadow_caster->t > 1.0) { - dmnsn_vector object_normal = x0; + dmnsn_vector object_normal = intersection->normal; dmnsn_vector normal = dmnsn_vector_normalize( dmnsn_vector_add( dmnsn_vector_normalize(dmnsn_vector_sub(ray.x0, x0)), @@ -322,13 +322,6 @@ dmnsn_raytrace_shoot(dmnsn_line ray, dmnsn_scene *scene, ), 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); diff --git a/tests/libdimension/tests.c b/tests/libdimension/tests.c index 87cbb7b..d79434d 100644 --- a/tests/libdimension/tests.c +++ b/tests/libdimension/tests.c @@ -101,7 +101,7 @@ dmnsn_new_default_scene() return NULL; } - cube->texture->pigment = dmnsn_new_solid_pigment(dmnsn_black); + cube->texture->pigment = dmnsn_new_solid_pigment(dmnsn_white); if (!cube->texture->pigment) { dmnsn_delete_scene(scene); return NULL; @@ -113,7 +113,7 @@ dmnsn_new_default_scene() dmnsn_light *light = dmnsn_new_point_light( dmnsn_vector_construct(-5.0, 20.0, -5.0), - dmnsn_white + dmnsn_color_mul(0.9, dmnsn_white) ); if (!light) { dmnsn_delete_scene(scene); -- cgit v1.2.3