summaryrefslogtreecommitdiffstats
path: root/libdimension/raytrace.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-04-25 22:28:15 -0600
committerTavian Barnes <tavianator@gmail.com>2011-04-25 22:28:15 -0600
commit3c37bf39733bb53267b046c5f0aafbffeb738990 (patch)
tree633943f2dcf26d9fec2c7f93cb8462f68982a35a /libdimension/raytrace.c
parent13e11b2fafe60cad7d04d80c602adc12d6080036 (diff)
downloaddimension-3c37bf39733bb53267b046c5f0aafbffeb738990.tar.xz
Implement adaptive depth control.
Diffstat (limited to 'libdimension/raytrace.c')
-rw-r--r--libdimension/raytrace.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index a35b1e6..f5c68e6 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -109,7 +109,7 @@ typedef struct dmnsn_raytrace_state {
const dmnsn_scene *scene;
const dmnsn_intersection *intersection;
- dmnsn_prtree *prtree;
+ const dmnsn_prtree *prtree;
unsigned int reclevel;
dmnsn_vector r;
@@ -121,6 +121,8 @@ typedef struct dmnsn_raytrace_state {
dmnsn_color additional;
double ior;
+
+ dmnsn_color adc_value;
} dmnsn_raytrace_state;
/** Main helper for dmnsn_raytrace_scene_impl - shoot a ray. */
@@ -156,6 +158,7 @@ dmnsn_raytrace_scene_concurrent(void *ptr, unsigned int thread,
/* Shoot a ray */
state.reclevel = scene->reclimit;
state.ior = 1.0;
+ state.adc_value = dmnsn_white;
dmnsn_color color = dmnsn_raytrace_shoot(&state, ray);
dmnsn_set_pixel(scene->canvas, x, y, color);
@@ -253,7 +256,9 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state,
dmnsn_color color = light->light_fn(light, state->r);
unsigned int reclevel = state->reclevel;
- while (reclevel > 0) {
+ while (reclevel > 0
+ && dmnsn_color_intensity(color) >= state->scene->adc_bailout)
+ {
dmnsn_intersection shadow_caster;
bool shadow_casted = dmnsn_prtree_intersection(state->prtree, shadow_ray,
&shadow_caster, false);
@@ -268,7 +273,8 @@ dmnsn_raytrace_light_ray(const dmnsn_raytrace_state *state,
dmnsn_raytrace_pigment(&shadow_state);
if ((state->scene->quality & DMNSN_RENDER_TRANSLUCENCY)
- && (shadow_state.pigment.filter || shadow_state.pigment.trans)) {
+ && (shadow_state.pigment.filter || shadow_state.pigment.trans))
+ {
color = dmnsn_filter_light(color, shadow_state.pigment);
shadow_ray.x0 = dmnsn_line_point(shadow_ray, shadow_caster.t);
shadow_ray.n = dmnsn_vector_sub(light->x0, shadow_ray.x0);
@@ -339,6 +345,11 @@ dmnsn_raytrace_reflection(const dmnsn_raytrace_state *state)
refl_ray = dmnsn_line_add_epsilon(refl_ray);
dmnsn_raytrace_state recursive_state = *state;
+ recursive_state.adc_value = TEXTURE_CALLBACK(
+ state, finish, reflection_fn, dmnsn_black,
+ state->adc_value, state->pigment, state->reflected,
+ state->intersection->normal
+ );
dmnsn_color rec = dmnsn_raytrace_shoot(&recursive_state, refl_ray);
reflected = TEXTURE_CALLBACK(
state, finish, reflection_fn, dmnsn_black,
@@ -396,6 +407,9 @@ dmnsn_raytrace_translucency(dmnsn_raytrace_state *state)
);
}
+ recursive_state.adc_value
+ = dmnsn_filter_light(state->adc_value, state->pigment);
+
dmnsn_color rec = dmnsn_raytrace_shoot(&recursive_state, trans_ray);
dmnsn_color filtered = dmnsn_filter_light(rec, state->pigment);
state->diffuse.filter = state->pigment.filter;
@@ -408,8 +422,12 @@ dmnsn_raytrace_translucency(dmnsn_raytrace_state *state)
static dmnsn_color
dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray)
{
- if (state->reclevel == 0)
+ if (state->reclevel == 0
+ || dmnsn_color_intensity(state->adc_value) < state->scene->adc_bailout)
+ {
return dmnsn_black;
+ }
+
--state->reclevel;
/* Calculate the background color */