From a2ca88eba63a98b50a5a7d037d476a9b041c5413 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 2 Jun 2017 11:28:45 -0700 Subject: ray: precompute primary ray for ray_object_sphere_t This gets rid of some computation on the primary ray:plane intersection tests The branches on depth suck though... I'm leaning towards specialized primary ray intersection test functions. --- src/modules/ray/ray_object_sphere.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/modules/ray') diff --git a/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h index 9c74752..1eb37e8 100644 --- a/src/modules/ray/ray_object_sphere.h +++ b/src/modules/ray/ray_object_sphere.h @@ -17,6 +17,8 @@ typedef struct ray_object_sphere_t { ray_3f_t center; float radius; struct { + ray_3f_t primary_v; + float primary_dot_vv; float r2; float r_inv; } _prepared; @@ -25,6 +27,9 @@ 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_dot_vv = ray_3f_dot(&sphere->_prepared.primary_v, &sphere->_prepared.primary_v); + sphere->_prepared.r2 = sphere->radius * sphere->radius; /* to divide by radius via multiplication in ray_object_sphere_normal() */ @@ -34,10 +39,17 @@ static void ray_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t static inline int ray_object_sphere_intersects_ray(ray_object_sphere_t *sphere, unsigned depth, ray_ray_t *ray, float *res_distance) { - ray_3f_t v = ray_3f_sub(&ray->origin, &sphere->center); - float b = ray_3f_dot(&v, &ray->direction); - float disc = sphere->_prepared.r2 - (ray_3f_dot(&v, &v) - (b * b)); + ray_3f_t v = sphere->_prepared.primary_v; + float dot_vv = sphere->_prepared.primary_dot_vv; + float b, disc; + + if (depth != 1) { + v = ray_3f_sub(&ray->origin, &sphere->center); + dot_vv = ray_3f_dot(&v, &v); + } + b = ray_3f_dot(&v, &ray->direction); + disc = sphere->_prepared.r2 - (dot_vv - (b * b)); if (disc > 0) { float i1, i2; -- cgit v1.2.3