summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/ray/ray.c2
-rw-r--r--src/modules/ray/ray_object.h21
-rw-r--r--src/modules/ray/ray_object_light.h9
-rw-r--r--src/modules/ray/ray_object_plane.h5
-rw-r--r--src/modules/ray/ray_object_point.h5
-rw-r--r--src/modules/ray/ray_object_sphere.h5
-rw-r--r--src/modules/ray/ray_scene.c20
-rw-r--r--src/modules/ray/ray_scene.h2
8 files changed, 38 insertions, 31 deletions
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index 1143db1..b80f384 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -146,7 +146,7 @@ static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fra
/* 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;
#endif
- ray_scene_prepare(&scene);
+ ray_scene_prepare(&scene, &camera);
}
diff --git a/src/modules/ray/ray_object.h b/src/modules/ray/ray_object.h
index f4c3225..f882e86 100644
--- a/src/modules/ray/ray_object.h
+++ b/src/modules/ray/ray_object.h
@@ -3,6 +3,7 @@
#include <assert.h>
+#include "ray_camera.h"
#include "ray_object_light.h"
#include "ray_object_plane.h"
#include "ray_object_point.h"
@@ -25,20 +26,20 @@ typedef union ray_object_t {
* If the object has any pre-calculating to do, this is where it happens.
* The pre-calculated stuff is object-resident under a _prepared struct member.
*/
-static inline void ray_object_prepare(ray_object_t *object)
+static inline void ray_object_prepare(ray_object_t *object, ray_camera_t *camera)
{
switch (object->type) {
case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_prepare(&object->sphere);
+ return ray_object_sphere_prepare(&object->sphere, camera);
case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_prepare(&object->point);
+ return ray_object_point_prepare(&object->point, camera);
case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_prepare(&object->plane);
+ return ray_object_plane_prepare(&object->plane, camera);
case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_prepare(&object->light);
+ return ray_object_light_prepare(&object->light, camera);
default:
assert(0);
}
@@ -48,20 +49,20 @@ static inline void ray_object_prepare(ray_object_t *object)
/* Determine if a ray intersects object.
* If the object is intersected, store where along the ray the intersection occurs in res_distance.
*/
-static inline int ray_object_intersects_ray(ray_object_t *object, ray_ray_t *ray, float *res_distance)
+static inline int ray_object_intersects_ray(ray_object_t *object, unsigned depth, ray_ray_t *ray, float *res_distance)
{
switch (object->type) {
case RAY_OBJECT_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&object->sphere, ray, res_distance);
+ return ray_object_sphere_intersects_ray(&object->sphere, depth, ray, res_distance);
case RAY_OBJECT_TYPE_POINT:
- return ray_object_point_intersects_ray(&object->point, ray, res_distance);
+ return ray_object_point_intersects_ray(&object->point, depth, ray, res_distance);
case RAY_OBJECT_TYPE_PLANE:
- return ray_object_plane_intersects_ray(&object->plane, ray, res_distance);
+ return ray_object_plane_intersects_ray(&object->plane, depth, ray, res_distance);
case RAY_OBJECT_TYPE_LIGHT:
- return ray_object_light_intersects_ray(&object->light, ray, res_distance);
+ return ray_object_light_intersects_ray(&object->light, depth, ray, res_distance);
default:
assert(0);
}
diff --git a/src/modules/ray/ray_object_light.h b/src/modules/ray/ray_object_light.h
index 44b59d4..a6213e8 100644
--- a/src/modules/ray/ray_object_light.h
+++ b/src/modules/ray/ray_object_light.h
@@ -3,6 +3,7 @@
#include <assert.h>
+#include "ray_camera.h"
#include "ray_light_emitter.h"
#include "ray_object_light.h"
#include "ray_object_point.h"
@@ -19,20 +20,20 @@ typedef struct ray_object_light_t {
} ray_object_light_t;
-static void ray_object_light_prepare(ray_object_light_t *light)
+static void ray_object_light_prepare(ray_object_light_t *light, ray_camera_t *camera)
{
}
/* TODO: point is really the only one I've implemented... */
-static inline int ray_object_light_intersects_ray(ray_object_light_t *light, ray_ray_t *ray, float *res_distance)
+static inline int ray_object_light_intersects_ray(ray_object_light_t *light, unsigned depth, ray_ray_t *ray, float *res_distance)
{
switch (light->emitter.type) {
case RAY_LIGHT_EMITTER_TYPE_POINT:
- return ray_object_point_intersects_ray(&light->emitter.point, ray, res_distance);
+ return ray_object_point_intersects_ray(&light->emitter.point, depth, ray, res_distance);
case RAY_LIGHT_EMITTER_TYPE_SPHERE:
- return ray_object_sphere_intersects_ray(&light->emitter.sphere, ray, res_distance);
+ return ray_object_sphere_intersects_ray(&light->emitter.sphere, depth, ray, res_distance);
default:
assert(0);
}
diff --git a/src/modules/ray/ray_object_plane.h b/src/modules/ray/ray_object_plane.h
index cc7ea8d..0be28f4 100644
--- a/src/modules/ray/ray_object_plane.h
+++ b/src/modules/ray/ray_object_plane.h
@@ -2,6 +2,7 @@
#define _RAY_OBJECT_PLANE_H
#include "ray_3f.h"
+#include "ray_camera.h"
#include "ray_object_type.h"
#include "ray_ray.h"
#include "ray_surface.h"
@@ -15,12 +16,12 @@ typedef struct ray_object_plane_t {
} ray_object_plane_t;
-static void ray_object_plane_prepare(ray_object_plane_t *plane)
+static void ray_object_plane_prepare(ray_object_plane_t *plane, ray_camera_t *camera)
{
}
-static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, ray_ray_t *ray, float *res_distance)
+static inline int ray_object_plane_intersects_ray(ray_object_plane_t *plane, unsigned depth, ray_ray_t *ray, float *res_distance)
{
float d = ray_3f_dot(&plane->normal, &ray->direction);
diff --git a/src/modules/ray/ray_object_point.h b/src/modules/ray/ray_object_point.h
index 0eddf25..2b58f5f 100644
--- a/src/modules/ray/ray_object_point.h
+++ b/src/modules/ray/ray_object_point.h
@@ -2,6 +2,7 @@
#define _RAY_OBJECT_POINT_H
#include "ray_3f.h"
+#include "ray_camera.h"
#include "ray_object_type.h"
#include "ray_ray.h"
#include "ray_surface.h"
@@ -14,12 +15,12 @@ typedef struct ray_object_point_t {
} ray_object_point_t;
-static void ray_object_point_prepare(ray_object_point_t *point)
+static void ray_object_point_prepare(ray_object_point_t *point, ray_camera_t *camera)
{
}
-static inline int ray_object_point_intersects_ray(ray_object_point_t *point, ray_ray_t *ray, float *res_distance)
+static inline int ray_object_point_intersects_ray(ray_object_point_t *point, unsigned depth, ray_ray_t *ray, float *res_distance)
{
/* TODO: determine a ray:point intersection */
return 0;
diff --git a/src/modules/ray/ray_object_sphere.h b/src/modules/ray/ray_object_sphere.h
index aadda18..9c74752 100644
--- a/src/modules/ray/ray_object_sphere.h
+++ b/src/modules/ray/ray_object_sphere.h
@@ -4,6 +4,7 @@
#include <math.h>
#include "ray_3f.h"
+#include "ray_camera.h"
#include "ray_color.h"
#include "ray_object_type.h"
#include "ray_ray.h"
@@ -22,7 +23,7 @@ typedef struct ray_object_sphere_t {
} ray_object_sphere_t;
-static void ray_object_sphere_prepare(ray_object_sphere_t *sphere)
+static void ray_object_sphere_prepare(ray_object_sphere_t *sphere, ray_camera_t *camera)
{
sphere->_prepared.r2 = sphere->radius * sphere->radius;
@@ -31,7 +32,7 @@ static void ray_object_sphere_prepare(ray_object_sphere_t *sphere)
}
-static inline int ray_object_sphere_intersects_ray(ray_object_sphere_t *sphere, ray_ray_t *ray, float *res_distance)
+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);
diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_scene.c
index a95058f..b5d1e81 100644
--- a/src/modules/ray/ray_scene.c
+++ b/src/modules/ray/ray_scene.c
@@ -16,14 +16,14 @@ static ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *ray, unsigned depth)
/* Determine if the ray is obstructed by an object within the supplied distance, for shadows */
-static inline int ray_is_obstructed(ray_scene_t *scene, ray_ray_t *ray, float distance)
+static inline int ray_is_obstructed(ray_scene_t *scene, unsigned depth, ray_ray_t *ray, float distance)
{
unsigned i;
for (i = 0; i < scene->n_objects; i++) {
float ood;
- if (ray_object_intersects_ray(&scene->objects[i], ray, &ood) &&
+ if (ray_object_intersects_ray(&scene->objects[i], depth, ray, &ood) &&
ood < distance) {
return 1;
}
@@ -34,7 +34,7 @@ static inline int ray_is_obstructed(ray_scene_t *scene, ray_ray_t *ray, float di
/* shadow test */
-static inline int point_is_shadowed(ray_scene_t *scene, ray_3f_t *light_direction, float distance, ray_3f_t *point)
+static inline int point_is_shadowed(ray_scene_t *scene, unsigned depth, ray_3f_t *light_direction, float distance, ray_3f_t *point)
{
ray_ray_t shadow_ray;
@@ -46,7 +46,7 @@ static inline int point_is_shadowed(ray_scene_t *scene, ray_3f_t *light_directio
shadow_ray.origin = ray_3f_mult_scalar(&shadow_ray.direction, 0.00001f);
shadow_ray.origin = ray_3f_add(&shadow_ray.origin, point);
- if (ray_is_obstructed(scene, &shadow_ray, distance))
+ if (ray_is_obstructed(scene, depth + 1, &shadow_ray, distance))
return 1;
return 0;
@@ -84,7 +84,7 @@ static inline ray_color_t shade_ray(ray_scene_t *scene, ray_ray_t *ray, ray_obje
lvec = ray_3f_mult_scalar(&lvec, (1.0f / ldist)); /* normalize lvec */
#if 1
- if (point_is_shadowed(scene, &lvec, ldist, &intersection))
+ if (point_is_shadowed(scene, depth, &lvec, ldist, &intersection))
continue;
#endif
lvec_normal_dot = ray_3f_dot(&normal, &lvec);
@@ -149,7 +149,7 @@ static ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *ray, unsigned depth)
float distance;
/* Does this ray intersect object? */
- if (ray_object_intersects_ray(&scene->objects[i], ray, &distance)) {
+ if (ray_object_intersects_ray(&scene->objects[i], depth, ray, &distance)) {
/* Is it the nearest intersection? */
if (distance < nearest_object_distance) {
@@ -187,13 +187,15 @@ void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_frag
}
-/* prepare the scene for rendering, must be called whenever the scene has been changed. */
-void ray_scene_prepare(ray_scene_t *scene)
+/* prepare the scene for rendering with camera, must be called whenever anything in the scene+camera pair has been changed. */
+/* this is basically a time for the raytracer to precompute whatever it can which otherwise ends up occurring per-ray */
+/* the camera is included so primary rays which all have a common origin may be optimized for */
+void ray_scene_prepare(ray_scene_t *scene, ray_camera_t *camera)
{
unsigned i;
scene->_prepared.ambient_light = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
for (i = 0; i < scene->n_objects; i++)
- ray_object_prepare(&scene->objects[i]);
+ ray_object_prepare(&scene->objects[i], camera);
}
diff --git a/src/modules/ray/ray_scene.h b/src/modules/ray/ray_scene.h
index 820b16b..98928ee 100644
--- a/src/modules/ray/ray_scene.h
+++ b/src/modules/ray/ray_scene.h
@@ -24,7 +24,7 @@ typedef struct ray_scene_t {
} _prepared;
} ray_scene_t;
-void ray_scene_prepare(ray_scene_t *scene);
+void ray_scene_prepare(ray_scene_t *scene, ray_camera_t *camera);
void ray_scene_render_fragment(ray_scene_t *scene, ray_camera_t *camera, fb_fragment_t *fragment);
#endif
© All Rights Reserved