diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2017-06-02 11:28:45 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2017-06-02 11:28:45 -0700 |
commit | a2ca88eba63a98b50a5a7d037d476a9b041c5413 (patch) | |
tree | 8ec724237c8e000f7bc99f2c39fa9c9a4173c251 /src/modules/ray | |
parent | 90d3a46622d9af4dd9a1ade5cd3491810c3cc3ab (diff) |
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.
Diffstat (limited to 'src/modules/ray')
-rw-r--r-- | src/modules/ray/ray_object_sphere.h | 18 |
1 files changed, 15 insertions, 3 deletions
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; |