summaryrefslogtreecommitdiff
path: root/src/modules/ray
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/ray')
-rw-r--r--src/modules/ray/Makefile.am2
-rw-r--r--src/modules/ray/ray.c19
-rw-r--r--src/modules/ray/ray_render.c (renamed from src/modules/ray/ray_scene.c)61
-rw-r--r--src/modules/ray/ray_render.h15
-rw-r--r--src/modules/ray/ray_scene.h20
5 files changed, 79 insertions, 38 deletions
diff --git a/src/modules/ray/Makefile.am b/src/modules/ray/Makefile.am
index 872efb6..a0d7cb9 100644
--- a/src/modules/ray/Makefile.am
+++ b/src/modules/ray/Makefile.am
@@ -1,4 +1,4 @@
noinst_LIBRARIES = libray.a
-libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.c ray_euler.h ray_light_emitter.h ray_object.h ray_object_light.h ray_object_plane.h ray_object_point.h ray_object_sphere.h ray_object_type.h ray_ray.h ray_scene.c ray_scene.h ray_surface.h
+libray_a_SOURCES = ray_3f.h ray.c ray_camera.c ray_camera.h ray_color.h ray_euler.c ray_euler.h ray_light_emitter.h ray_object.h ray_object_light.h ray_object_plane.h ray_object_point.h ray_object_sphere.h ray_object_type.h ray_ray.h ray_render.c ray_render.h ray_scene.h ray_surface.h
libray_a_CFLAGS = @ROTOTILLER_CFLAGS@ -ffast-math
libray_a_CPPFLAGS = @ROTOTILLER_CFLAGS@ -I@top_srcdir@/src
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index 5f6326d..bb9c042 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -8,6 +8,7 @@
#include "ray_camera.h"
#include "ray_object.h"
+#include "ray_render.h"
#include "ray_scene.h"
/* Copyright (C) 2016-2017 Vito Caputo <vcaputo@pengaru.com> */
@@ -118,6 +119,7 @@ static float r;
typedef struct ray_context_t {
+ ray_render_t *render;
} ray_context_t;
@@ -142,6 +144,8 @@ static int ray_fragmenter(void *context, const fb_fragment_t *fragment, unsigned
/* prepare a frame for concurrent rendering */
static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
+ ray_context_t *ctxt = context;
+
*res_fragmenter = ray_fragmenter;
/* TODO: the camera doesn't need the width and height anymore, the fragment has the frame_width/frame_height */
@@ -169,14 +173,24 @@ 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, &camera);
+ ctxt->render = ray_render_new(&scene, &camera);
}
/* ray trace a simple scene into the fragment */
static void ray_render_fragment(void *context, fb_fragment_t *fragment)
{
- ray_scene_render_fragment(&scene, fragment);
+ ray_context_t *ctxt = context;
+
+ ray_render_trace_fragment(ctxt->render, fragment);
+}
+
+
+static void ray_finish_frame(void *context, fb_fragment_t *fragment)
+{
+ ray_context_t *ctxt = context;
+
+ ray_render_free(ctxt->render);
}
@@ -185,6 +199,7 @@ rototiller_module_t ray_module = {
.destroy_context = ray_destroy_context,
.prepare_frame = ray_prepare_frame,
.render_fragment = ray_render_fragment,
+ .finish_frame = ray_finish_frame,
.name = "ray",
.description = "Ray tracer (threaded)",
.author = "Vito Caputo <vcaputo@pengaru.com>",
diff --git a/src/modules/ray/ray_scene.c b/src/modules/ray/ray_render.c
index 21a3bfa..bfa5112 100644
--- a/src/modules/ray/ray_scene.c
+++ b/src/modules/ray/ray_render.c
@@ -12,13 +12,20 @@
#define MAX_RECURSION_DEPTH 4
#define MIN_RELEVANCE 0.05f
+typedef struct ray_render_t {
+ const ray_scene_t *scene; /* scene being rendered */
+ const ray_camera_t *camera; /* camera rendering the scene */
+
+ ray_color_t ambient_light;
+ ray_camera_frame_t frame;
+} ray_render_t;
/* 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, unsigned depth, ray_ray_t *ray, float distance)
+static inline int ray_is_obstructed(ray_render_t *render, unsigned depth, ray_ray_t *ray, float distance)
{
ray_object_t *object;
- for (object = scene->objects; object->type; object++) {
+ for (object = render->scene->objects; object->type; object++) {
float ood;
if (ray_object_intersects_ray(object, depth, ray, &ood) &&
@@ -32,14 +39,14 @@ static inline int ray_is_obstructed(ray_scene_t *scene, unsigned depth, ray_ray_
/* shadow test */
-static inline int point_is_shadowed(ray_scene_t *scene, unsigned depth, ray_3f_t *light_direction, float distance, ray_3f_t *point)
+static inline int point_is_shadowed(ray_render_t *render, unsigned depth, ray_3f_t *light_direction, float distance, ray_3f_t *point)
{
ray_ray_t shadow_ray;
shadow_ray.direction = *light_direction;
shadow_ray.origin = *point;
- if (ray_is_obstructed(scene, depth + 1, &shadow_ray, distance))
+ if (ray_is_obstructed(render, depth + 1, &shadow_ray, distance))
return 1;
return 0;
@@ -57,21 +64,21 @@ static inline float approx_powf(float x, float y)
/* Determine the color @ distance on ray on object viewed from origin */
-static inline ray_color_t shade_intersection(ray_scene_t *scene, ray_object_t *object, ray_ray_t *ray, ray_3f_t *intersection, ray_3f_t *normal, unsigned depth, float *res_reflectivity)
+static inline ray_color_t shade_intersection(ray_render_t *render, ray_object_t *object, ray_ray_t *ray, ray_3f_t *intersection, ray_3f_t *normal, unsigned depth, float *res_reflectivity)
{
ray_surface_t surface = ray_object_surface(object, intersection);
- ray_color_t color = ray_3f_mult(&surface.color, &scene->_prepared.ambient_light);
+ ray_color_t color = ray_3f_mult(&surface.color, &render->ambient_light);
ray_object_t *light;
/* visit lights for shadows and illumination */
- for (light = scene->lights; light->type; light++) {
+ for (light = render->scene->lights; light->type; light++) {
ray_3f_t lvec = ray_3f_sub(&light->light.emitter.point.center, intersection);
float ldist = ray_3f_length(&lvec);
float lvec_normal_dot;
lvec = ray_3f_mult_scalar(&lvec, (1.0f / ldist)); /* normalize lvec */
#if 1
- if (point_is_shadowed(scene, depth, &lvec, ldist, intersection))
+ if (point_is_shadowed(render, depth, &lvec, ldist, intersection))
continue;
#endif
lvec_normal_dot = ray_3f_dot(normal, &lvec);
@@ -109,13 +116,13 @@ static inline ray_color_t shade_intersection(ray_scene_t *scene, ray_object_t *o
}
-static inline ray_object_t * find_nearest_intersection(ray_scene_t *scene, ray_object_t *reflector, ray_ray_t *ray, unsigned depth, float *res_distance)
+static inline ray_object_t * find_nearest_intersection(ray_render_t *render, ray_object_t *reflector, ray_ray_t *ray, unsigned depth, float *res_distance)
{
ray_object_t *nearest_object = NULL;
float nearest_object_distance = INFINITY;
ray_object_t *object;
- for (object = scene->objects; object->type; object++) {
+ for (object = render->scene->objects; object->type; object++) {
float distance;
/* Don't bother checking if a reflected ray intersects the object reflecting it,
@@ -140,7 +147,7 @@ static inline ray_object_t * find_nearest_intersection(ray_scene_t *scene, ray_o
}
-static inline ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *primary_ray)
+static inline ray_color_t trace_ray(ray_render_t *render, ray_ray_t *primary_ray)
{
ray_color_t color = { .x = 0.0f, .y = 0.0f, .z = 0.0f };
ray_3f_t intersection, normal;
@@ -165,7 +172,7 @@ static inline ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *primary_ray)
ray = &reflected_ray;
}
- nearest_object = find_nearest_intersection(scene, reflector, ray, depth, &nearest_distance);
+ nearest_object = find_nearest_intersection(render, reflector, ray, depth, &nearest_distance);
if (nearest_object) {
ray_3f_t more_color;
ray_3f_t rvec;
@@ -174,7 +181,7 @@ static inline ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *primary_ray)
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);
+ more_color = shade_intersection(render, nearest_object, ray, &intersection, &normal, depth, &reflectivity);
more_color = ray_3f_mult_scalar(&more_color, relevance);
color = ray_3f_add(&color, &more_color);
}
@@ -186,16 +193,16 @@ static inline ray_color_t trace_ray(ray_scene_t *scene, ray_ray_t *primary_ray)
}
-void ray_scene_render_fragment(ray_scene_t *scene, fb_fragment_t *fb_fragment)
+void ray_render_trace_fragment(ray_render_t *render, fb_fragment_t *fb_fragment)
{
uint32_t *buf = fb_fragment->buf;
ray_camera_fragment_t fragment;
ray_ray_t ray;
- ray_camera_fragment_begin(&scene->_prepared.frame, fb_fragment, &ray, &fragment);
+ ray_camera_fragment_begin(&render->frame, fb_fragment, &ray, &fragment);
do {
do {
- *buf = ray_color_to_uint32_rgb(trace_ray(scene, &ray));
+ *buf = ray_color_to_uint32_rgb(trace_ray(render, &ray));
buf++;
} while (ray_camera_fragment_x_step(&fragment));
@@ -207,13 +214,29 @@ void ray_scene_render_fragment(ray_scene_t *scene, fb_fragment_t *fb_fragment)
/* 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)
+ray_render_t * ray_render_new(ray_scene_t *scene, ray_camera_t *camera)
{
+ ray_render_t *render;
ray_object_t *object;
- scene->_prepared.ambient_light = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
- ray_camera_frame_prepare(camera, &scene->_prepared.frame);
+ render = malloc(sizeof(ray_render_t));
+ if (!render)
+ return NULL;
+
+ render->scene = scene;
+ render->camera = camera;
+
+ render->ambient_light = ray_3f_mult_scalar(&scene->ambient_color, scene->ambient_brightness);
+ ray_camera_frame_prepare(camera, &render->frame);
for (object = scene->objects; object->type; object++)
ray_object_prepare(object, camera);
+
+ return render;
+}
+
+
+void ray_render_free(ray_render_t *render)
+{
+ free(render);
}
diff --git a/src/modules/ray/ray_render.h b/src/modules/ray/ray_render.h
new file mode 100644
index 0000000..a6d6c67
--- /dev/null
+++ b/src/modules/ray/ray_render.h
@@ -0,0 +1,15 @@
+#ifndef _RAY_RENDER_H
+#define _RAY_RENDER_H
+
+#include "fb.h"
+
+#include "ray_camera.h"
+#include "ray_scene.h"
+
+typedef struct ray_render_t ray_render_t;
+
+ray_render_t * ray_render_new(ray_scene_t *scene, ray_camera_t *camera);
+void ray_render_free(ray_render_t *render);
+void ray_render_trace_fragment(ray_render_t *render, fb_fragment_t *fb_fragment);
+
+#endif
diff --git a/src/modules/ray/ray_scene.h b/src/modules/ray/ray_scene.h
index 5c7cd5e..ff9c440 100644
--- a/src/modules/ray/ray_scene.h
+++ b/src/modules/ray/ray_scene.h
@@ -1,28 +1,16 @@
#ifndef _RAY_SCENE_H
#define _RAY_SCENE_H
-#include "fb.h"
-
-#include "ray_camera.h"
#include "ray_color.h"
-#include "ray_ray.h"
typedef union ray_object_t ray_object_t;
typedef struct ray_scene_t {
- ray_object_t *objects;
- ray_object_t *lights;
-
- ray_color_t ambient_color;
- float ambient_brightness;
+ ray_object_t *objects;
+ ray_object_t *lights;
- struct {
- ray_color_t ambient_light;
- ray_camera_frame_t frame;
- } _prepared;
+ ray_color_t ambient_color;
+ float ambient_brightness;
} ray_scene_t;
-void ray_scene_prepare(ray_scene_t *scene, ray_camera_t *camera);
-void ray_scene_render_fragment(ray_scene_t *scene, fb_fragment_t *fb_fragment);
-
#endif
© All Rights Reserved