diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2017-08-08 09:42:30 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2017-08-15 16:46:40 -0700 |
commit | adb76b79d39a185be4659193baff0cb1fe043506 (patch) | |
tree | fdc51e2d986e7ef6bd22d0897bdbca10ed51f550 /src/modules/ray | |
parent | 760112de102f36ba5aaf16d9e949d0bfa3623175 (diff) |
ray: misc computational fixups
ray:object intersection coordinates were incorrectly being computed
relative to the ray origin using a subtraction instead of addition, a
silly mistake with surprisingly acceptable results. Those results
were a result of other minor complementary mistakes compensating to
produce reasonable looking results.
In the course of experimenting with an acceleration data structure it
became very apparent that 3d space traversal vectors were not behaving
as intended, leading to review and correction of this code.
Diffstat (limited to 'src/modules/ray')
-rw-r--r-- | src/modules/ray/ray.c | 9 | ||||
-rw-r--r-- | src/modules/ray/ray_object_plane.h | 6 | ||||
-rw-r--r-- | src/modules/ray/ray_object_sphere.h | 4 | ||||
-rw-r--r-- | src/modules/ray/ray_scene.c | 14 |
4 files changed, 15 insertions, 18 deletions
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c index 89d114c..ac00806 100644 --- a/src/modules/ray/ray.c +++ b/src/modules/ray/ray.c @@ -98,7 +98,7 @@ static ray_camera_t camera = { .order = RAY_EULER_ORDER_YPR, /* yaw,pitch,roll */ .yaw = RAY_EULER_DEGREES(0.0f), .pitch = RAY_EULER_DEGREES(0.0f), - .roll = RAY_EULER_DEGREES(180.0f), + .roll = RAY_EULER_DEGREES(0.0f), }, .focal_length = 700.0f, }; @@ -128,7 +128,7 @@ static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fra #if 1 /* animated point light source */ - r += .02; + r += -.02; scene.lights[0].light.emitter.point.center.x = cosf(r) * 4.5f; scene.lights[0].light.emitter.point.center.z = sinf(r * 3.0f) * 4.5f; @@ -141,10 +141,11 @@ static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fra camera.position.y = cosf(r * 1.3f) * 4.0f + 2.08f; /* keep camera facing the origin */ - camera.orientation.yaw = r; + camera.orientation.yaw = r + RAY_EULER_DEGREES(180.0f); + /* tilt camera pitch in time with up and down movements, phase shifted appreciably */ - camera.orientation.pitch = sinf((M_PI * 1.5f) + r * 1.3f) * .6f + -.35f; + camera.orientation.pitch = -(sinf((M_PI * 1.5f) + r * 1.3f) * .6f + -.35f); #endif ray_scene_prepare(&scene, &camera); } diff --git a/src/modules/ray/ray_object_plane.h b/src/modules/ray/ray_object_plane.h index 490238c..0d3a51b 100644 --- a/src/modules/ray/ray_object_plane.h +++ b/src/modules/ray/ray_object_plane.h @@ -29,14 +29,14 @@ static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, uns { float d = ray_3f_dot(&plane->normal, &ray->direction); - if (d >= 0.00001f) { + if (d < 0.0f) { float distance = plane->_prepared.primary_dot_plus; if (depth) distance = (ray_3f_dot(&plane->normal, &ray->origin) + plane->distance); - distance /= d; - if (distance > 0) { + distance /= -d; + if (distance > 0.0f) { *res_distance = distance; return 1; diff --git a/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h index c07f345..0077a68 100644 --- a/src/modules/ray/ray_object_sphere.h +++ b/src/modules/ray/ray_object_sphere.h @@ -27,7 +27,7 @@ typedef struct ray_object_sphere_t { static void ray_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t *camera) { - sphere->_prepared.primary_v = ray_3f_sub(&camera->position, &sphere->center); + sphere->_prepared.primary_v = ray_3f_sub(&sphere->center, &camera->position); sphere->_prepared.primary_dot_vv = ray_3f_dot(&sphere->_prepared.primary_v, &sphere->_prepared.primary_v); sphere->_prepared.r2 = sphere->radius * sphere->radius; @@ -44,7 +44,7 @@ static inline int ray_object_sphere_intersects_ray(ray_object_sphere_t *sphere, float b, disc; if (depth) { - v = ray_3f_sub(&ray->origin, &sphere->center); + v = ray_3f_sub(&sphere->center, &ray->origin); dot_vv = ray_3f_dot(&v, &v); } diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_scene.c index 2ad7f99..2026f6d 100644 --- a/src/modules/ray/ray_scene.c +++ b/src/modules/ray/ray_scene.c @@ -36,13 +36,8 @@ static inline int point_is_shadowed(ray_scene_t *scene, unsigned depth, ray_3f_t { 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); + shadow_ray.direction = *light_direction; + shadow_ray.origin = *point; if (ray_is_obstructed(scene, depth + 1, &shadow_ray, distance)) return 1; @@ -85,13 +80,14 @@ static inline ray_color_t shade_intersection(ray_scene_t *scene, ray_object_t *o #if 1 float rvec_lvec_dot = ray_3f_dot(&ray->direction, &lvec); ray_color_t diffuse; - ray_color_t specular; diffuse = ray_3f_mult_scalar(&surface.color, lvec_normal_dot); diffuse = ray_3f_mult_scalar(&diffuse, surface.diffuse); color = ray_3f_add(&color, &diffuse); if (rvec_lvec_dot > 0) { + ray_color_t specular; + /* FIXME: assumes light is a point for its color */ specular = ray_3f_mult_scalar(&scene->lights[i].light.emitter.point.surface.color, approx_powf(rvec_lvec_dot, surface.highlight_exponent)); specular = ray_3f_mult_scalar(&specular, surface.specular); @@ -178,7 +174,7 @@ static inline ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *primary_ray) ray_3f_t rvec; rvec = ray_3f_mult_scalar(&ray->direction, nearest_distance); - intersection = ray_3f_sub(&ray->origin, &rvec); + intersection = ray_3f_add(&ray->origin, &rvec); normal = ray_object_normal(nearest_object, &intersection); more_color = shade_intersection(scene, nearest_object, ray, &intersection, &normal, depth, &reflectivity); |