diff options
Diffstat (limited to 'libdimension')
-rw-r--r-- | libdimension/dimension/scene.h | 3 | ||||
-rw-r--r-- | libdimension/raytrace.c | 26 | ||||
-rw-r--r-- | libdimension/scene.c | 1 |
3 files changed, 26 insertions, 4 deletions
diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index 747c764..7b44231 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -66,6 +66,9 @@ typedef struct dmnsn_scene { /** Recursion limit. */ unsigned int reclimit; + /** Adaptive depth control bailout. */ + double adc_bailout; + /** Number of parallel threads. */ unsigned int nthreads; 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 */ diff --git a/libdimension/scene.c b/libdimension/scene.c index 95c8f32..fadd077 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -42,6 +42,7 @@ dmnsn_new_scene(void) scene->lights = dmnsn_new_array(sizeof(dmnsn_light *)); scene->quality = DMNSN_RENDER_FULL; scene->reclimit = 5; + scene->adc_bailout = 1.0/255.0; scene->nthreads = dmnsn_ncpus(); scene->bounding_timer = NULL; scene->render_timer = NULL; |