diff options
author | Tavian Barnes <tavianator@gmail.com> | 2011-04-25 22:28:15 -0600 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2011-04-25 22:28:15 -0600 |
commit | 3c37bf39733bb53267b046c5f0aafbffeb738990 (patch) | |
tree | 633943f2dcf26d9fec2c7f93cb8462f68982a35a /libdimension/raytrace.c | |
parent | 13e11b2fafe60cad7d04d80c602adc12d6080036 (diff) | |
download | dimension-3c37bf39733bb53267b046c5f0aafbffeb738990.tar.xz |
Implement adaptive depth control.
Diffstat (limited to 'libdimension/raytrace.c')
-rw-r--r-- | libdimension/raytrace.c | 26 |
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 */ |