diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_path.h')
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 115 |
1 files changed, 47 insertions, 68 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 850bfb22b3c..721e0fc32d5 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -448,21 +448,13 @@ ccl_device bool kernel_path_subsurface_scatter( /* do bssrdf scatter step if we picked a bssrdf closure */ if(sc) { - uint lcg_state = lcg_state_init(rng, state, 0x68bc21eb); + /* We should never have two consecutive BSSRDF bounces, + * the second one should be converted to a diffuse BSDF to + * avoid this. + */ + kernel_assert(!ss_indirect->tracing); - /* If indirect ray hits BSSRDF we replace it with diffuse BSDF. */ - if(ss_indirect->num_rays) { - float bssrdf_u, bssrdf_v; - path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); - subsurface_scatter_step(kg, - sd, - state->flag, - sc, - &lcg_state, - bssrdf_u, bssrdf_v, - false); - return false; - } + uint lcg_state = lcg_state_init(rng, state, 0x68bc21eb); SubsurfaceIntersection ss_isect; float bssrdf_u, bssrdf_v; @@ -493,9 +485,10 @@ ccl_device bool kernel_path_subsurface_scatter( sc, false); - PathState *hit_state = &ss_indirect->state; + PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays]; Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays]; float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays]; + PathRadiance *hit_L = &ss_indirect->L[ss_indirect->num_rays]; *hit_state = *state; *hit_ray = *ray; @@ -503,51 +496,25 @@ ccl_device bool kernel_path_subsurface_scatter( hit_state->rng_offset += PRNG_BOUNCE_NUM; - kernel_path_surface_connect_light(kg, rng, sd, *hit_tp, state, L); + path_radiance_init(hit_L, kernel_data.film.use_light_pass); + kernel_path_surface_connect_light(kg, rng, sd, *hit_tp, state, hit_L); if(kernel_path_surface_bounce(kg, rng, sd, hit_tp, hit_state, - L, + hit_L, hit_ray)) { #ifdef __LAMP_MIS__ hit_state->ray_t = 0.0f; #endif -#ifdef __SUBSURFACE_DELAYED_INDIRECT__ ss_indirect->num_rays++; -#else -# ifdef __VOLUME__ - if(ss_indirect->need_update_volume_stack) { - Ray volume_ray = *ray; - - /* Setup ray from previous surface point to the new one. */ - volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, - &volume_ray.t); - - kernel_volume_stack_update_for_subsurface(kg, - &volume_ray, - hit_state->volume_stack); - } -# endif /* __VOLUME__ */ - - kernel_path_indirect(kg, - rng, - hit_ray, - *hit_tp, - hit_state->num_samples, - hit_state, - L); - - /* For render passes, sum and reset indirect light pass variables - * for the next samples. - */ - path_radiance_sum_indirect(L); - path_radiance_reset_indirect(L); -#endif + } + else { + path_radiance_accum_sample(L, hit_L, 1); } } return true; @@ -555,23 +522,38 @@ ccl_device bool kernel_path_subsurface_scatter( return false; } -#ifdef __SUBSURFACE_DELAYED_INDIRECT__ +ccl_device void kernel_path_subsurface_accum_indirect( + SubsurfaceIndirectRays *ss_indirect, + PathRadiance *L) +{ + if(ss_indirect->tracing) { + path_radiance_sum_indirect(L); + path_radiance_accum_sample(&ss_indirect->direct_L, L, 1); + if(ss_indirect->num_rays == 0) { + *L = ss_indirect->direct_L; + } + } +} + ccl_device void kernel_path_subsurface_setup_indirect( KernelGlobals *kg, SubsurfaceIndirectRays *ss_indirect, - PathRadiance *L, + const Ray *orig_ray, PathState *state, - Ray *orig_ray, Ray *ray, + PathRadiance *L, float3 *throughput) { + if(!ss_indirect->tracing) { + ss_indirect->direct_L = *L; + } + ss_indirect->tracing = true; + /* Setup state, ray and throughput for indirect SSS rays. */ ss_indirect->num_rays--; Ray *indirect_ray = &ss_indirect->rays[ss_indirect->num_rays]; - - *state = ss_indirect->state; - *throughput = ss_indirect->throughputs[ss_indirect->num_rays]; + PathRadiance *indirect_L = &ss_indirect->L[ss_indirect->num_rays]; #ifdef __VOLUME__ if(ss_indirect->need_update_volume_stack) { @@ -587,17 +569,15 @@ ccl_device void kernel_path_subsurface_setup_indirect( } #endif /* __VOLUME__ */ + *state = ss_indirect->state[ss_indirect->num_rays]; *ray = *indirect_ray; + *L = *indirect_L; + *throughput = ss_indirect->throughputs[ss_indirect->num_rays]; - /* For render passes, sum and reset indirect light pass variables - * for the next samples. - */ - path_radiance_sum_indirect(L); - path_radiance_reset_indirect(L); + state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM; } -#endif /* __SUBSURFACE_DELAYED_INDIRECT__ */ -#endif +#endif /* __SUBSURFACE__ */ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer) { @@ -618,9 +598,9 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, #ifdef __SUBSURFACE__ SubsurfaceIndirectRays ss_indirect; + ss_indirect.tracing = false; ss_indirect.num_rays = 0; -# ifdef __SUBSURFACE_DELAYED_INDIRECT__ /* TODO(sergey): Avoid having explicit copy of the pre-subsurface scatter * ray by storing an updated version of state in the ss_indirect which will * be updated to the new volume stack. @@ -628,7 +608,6 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ss_orig_ray; for(;;) { -# endif /* __SUBSURFACE_DELAYED_INDIRECT__ */ #endif /* path iteration */ @@ -877,9 +856,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, &throughput, &ss_indirect)) { -# ifdef __SUBSURFACE_DELAYED_INDIRECT__ ss_orig_ray = ray; -# endif /* __SUBSURFACE_DELAYED_INDIRECT__ */ break; } } @@ -893,24 +870,26 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, break; } -#ifdef __SUBSURFACE_DELAYED_INDIRECT__ +#ifdef __SUBSURFACE__ + kernel_path_subsurface_accum_indirect(&ss_indirect, &L); + /* Trace indirect subsurface rays by restarting the loop. this uses less * stack memory than invoking kernel_path_indirect. */ if(ss_indirect.num_rays) { kernel_path_subsurface_setup_indirect(kg, &ss_indirect, - &L, - &state, &ss_orig_ray, + &state, &ray, + &L, &throughput); } else { break; } } -#endif /* __SUBSURFACE_DELAYED_INDIRECT__ */ +#endif /* __SUBSURFACE__ */ float3 L_sum = path_radiance_clamp_and_sum(kg, &L); |