diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_path.h')
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 109 |
1 files changed, 59 insertions, 50 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c136c85df59..0dded397ffa 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -53,6 +53,8 @@ CCL_NAMESPACE_BEGIN ccl_device void kernel_path_indirect(KernelGlobals *kg, + ShaderData *sd, + ShaderData *emission_sd, RNG *rng, Ray *ray, float3 throughput, @@ -87,7 +89,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* intersect with lamp */ float3 emission; - if(indirect_lamp_emission(kg, state, &light_ray, &emission)) { + if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission)) { path_radiance_accum_emission(L, throughput, emission, @@ -115,15 +117,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(decoupled) { /* cache steps along volume for repeated sampling */ VolumeSegment volume_segment; - ShaderData volume_sd; shader_setup_from_volume(kg, - &volume_sd, + sd, &volume_ray); kernel_volume_decoupled_record(kg, state, &volume_ray, - &volume_sd, + sd, &volume_segment, heterogeneous); @@ -146,7 +147,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* direct light sampling */ kernel_branched_path_volume_connect_light(kg, rng, - &volume_sd, + sd, + emission_sd, throughput, state, L, @@ -163,7 +165,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, result = kernel_volume_decoupled_scatter(kg, state, &volume_ray, - &volume_sd, + sd, &throughput, rphase, rscatter, @@ -178,7 +180,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(result == VOLUME_PATH_SCATTERED) { if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + sd, &throughput, state, L, @@ -198,16 +200,16 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, # endif { /* integrate along volume segment with distance sampling */ - ShaderData volume_sd; VolumeIntegrateResult result = kernel_volume_integrate( - kg, state, &volume_sd, &volume_ray, L, &throughput, rng, heterogeneous); + kg, state, sd, &volume_ray, L, &throughput, rng, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ kernel_path_volume_connect_light(kg, rng, - &volume_sd, + sd, + emission_sd, throughput, state, L); @@ -215,7 +217,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* indirect light bounce */ if(kernel_path_volume_bounce(kg, rng, - &volume_sd, + sd, &throughput, state, L, @@ -235,7 +237,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(!hit) { #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, state, ray); + float3 L_background = indirect_background(kg, emission_sd, state, ray); path_radiance_accum_background(L, throughput, L_background, @@ -246,15 +248,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } /* setup shading */ - ShaderData sd; shader_setup_from_ray(kg, - &sd, + sd, &isect, ray); float rbsdf = path_state_rng_1D_for_decision(kg, rng, state, PRNG_BSDF); - shader_eval_surface(kg, &sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); + shader_eval_surface(kg, sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); #ifdef __BRANCHED_PATH__ - shader_merge_closures(&sd); + shader_merge_closures(sd); #endif /* blurring of bsdf after bounces, for rays that have a small likelihood @@ -264,15 +265,15 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, if(blur_pdf < 1.0f) { float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; - shader_bsdf_blur(kg, &sd, blur_roughness); + shader_bsdf_blur(kg, sd, blur_roughness); } } #ifdef __EMISSION__ /* emission */ - if(sd.flag & SD_EMISSION) { + if(sd->flag & SD_EMISSION) { float3 emission = indirect_primitive_emission(kg, - &sd, + sd, isect.t, state->flag, state->ray_pdf); @@ -302,33 +303,33 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ - if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { + if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) { float bsdf_u, bsdf_v; path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; - float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); + float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); float3 ao_D; float ao_pdf; float3 ao_alpha = make_float3(0.0f, 0.0f, 0.0f); sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); - if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; float3 ao_shadow; - light_ray.P = ray_offset(sd.P, sd.Ng); + light_ray.P = ray_offset(sd->P, sd->Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; # ifdef __OBJECT_MOTION__ - light_ray.time = sd.time; + light_ray.time = sd->time; # endif - light_ray.dP = sd.dP; + light_ray.dP = sd->dP; light_ray.dD = differential3_zero(); - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) { + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) { path_radiance_accum_ao(L, throughput, ao_alpha, @@ -343,9 +344,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #ifdef __SUBSURFACE__ /* bssrdf scatter to a different location on the same object, replacing * the closures with a diffuse BSDF */ - if(sd.flag & SD_BSSRDF) { + if(sd->flag & SD_BSSRDF) { float bssrdf_probability; - ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability); + ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability); /* modify throughput for picking bssrdf or bsdf */ throughput *= bssrdf_probability; @@ -361,7 +362,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); subsurface_scatter_step(kg, - &sd, + sd, state, state->flag, sc, @@ -377,7 +378,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, int all = kernel_data.integrator.sample_all_lights_indirect; kernel_branched_path_surface_connect_light(kg, rng, - &sd, + sd, + emission_sd, state, throughput, 1.0f, @@ -386,13 +388,14 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, } #endif - if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, state, L, ray)) + if(!kernel_path_surface_bounce(kg, rng, sd, &throughput, state, L, ray)) break; } } ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, + ShaderData *emission_sd, PathRadiance *L, PathState *state, RNG *rng, @@ -425,7 +428,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, light_ray.dP = ccl_fetch(sd, dP); light_ray.dD = differential3_zero(); - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce); } } @@ -435,6 +438,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, ccl_device bool kernel_path_subsurface_scatter( KernelGlobals *kg, ShaderData *sd, + ShaderData *emission_sd, PathRadiance *L, PathState *state, RNG *rng, @@ -503,7 +507,7 @@ ccl_device bool kernel_path_subsurface_scatter( hit_L->direct_throughput = L->direct_throughput; path_radiance_copy_indirect(hit_L, L); - kernel_path_surface_connect_light(kg, rng, sd, *hit_tp, state, hit_L); + kernel_path_surface_connect_light(kg, rng, sd, emission_sd, *hit_tp, state, hit_L); if(kernel_path_surface_bounce(kg, rng, @@ -526,6 +530,7 @@ ccl_device bool kernel_path_subsurface_scatter( kernel_volume_stack_update_for_subsurface( kg, + emission_sd, &volume_ray, hit_state->volume_stack); } @@ -604,8 +609,13 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, path_radiance_init(&L, kernel_data.film.use_light_pass); + /* shader data memory used for both volumes and surfaces, saves stack space */ + ShaderData sd; + /* shader data used by emission, shadows, volume stacks */ + ShaderData emission_sd; + PathState state; - path_state_init(kg, &state, rng, sample, &ray); + path_state_init(kg, &emission_sd, &state, rng, sample, &ray); #ifdef __KERNEL_DEBUG__ DebugData debug_data; @@ -669,7 +679,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, /* intersect with lamp */ float3 emission; - if(indirect_lamp_emission(kg, &state, &light_ray, &emission)) + if(indirect_lamp_emission(kg, &emission_sd, &state, &light_ray, &emission)) path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -689,11 +699,10 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, if(decoupled) { /* cache steps along volume for repeated sampling */ VolumeSegment volume_segment; - ShaderData volume_sd; - shader_setup_from_volume(kg, &volume_sd, &volume_ray); + shader_setup_from_volume(kg, &sd, &volume_ray); kernel_volume_decoupled_record(kg, &state, - &volume_ray, &volume_sd, &volume_segment, heterogeneous); + &volume_ray, &sd, &volume_segment, heterogeneous); volume_segment.sampling_method = sampling_method; @@ -708,8 +717,9 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, int all = false; /* direct light sampling */ - kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, - throughput, &state, &L, all, &volume_ray, &volume_segment); + kernel_branched_path_volume_connect_light(kg, rng, &sd, + &emission_sd, throughput, &state, &L, all, + &volume_ray, &volume_segment); /* indirect sample. if we use distance sampling and take just * one sample for direct and indirect light, we could share @@ -718,7 +728,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); result = kernel_volume_decoupled_scatter(kg, - &state, &volume_ray, &volume_sd, &throughput, + &state, &volume_ray, &sd, &throughput, rphase, rscatter, &volume_segment, NULL, true); } @@ -726,7 +736,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, kernel_volume_decoupled_free(kg, &volume_segment); if(result == VOLUME_PATH_SCATTERED) { - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray)) + if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) continue; else break; @@ -739,17 +749,16 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, # endif { /* integrate along volume segment with distance sampling */ - ShaderData volume_sd; VolumeIntegrateResult result = kernel_volume_integrate( - kg, &state, &volume_sd, &volume_ray, &L, &throughput, rng, heterogeneous); + kg, &state, &sd, &volume_ray, &L, &throughput, rng, heterogeneous); # ifdef __VOLUME_SCATTER__ if(result == VOLUME_PATH_SCATTERED) { /* direct lighting */ - kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L); + kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, &L); /* indirect light bounce */ - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray)) + if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) continue; else break; @@ -772,7 +781,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #ifdef __BACKGROUND__ /* sample background shader */ - float3 L_background = indirect_background(kg, &state, &ray); + float3 L_background = indirect_background(kg, &emission_sd, &state, &ray); path_radiance_accum_background(&L, throughput, L_background, state.bounce); #endif @@ -780,7 +789,6 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, } /* setup shading */ - ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); shader_eval_surface(kg, &sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); @@ -848,7 +856,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_path_ao(kg, &sd, &L, &state, rng, throughput); + kernel_path_ao(kg, &sd, &emission_sd, &L, &state, rng, throughput); } #endif @@ -858,6 +866,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, if(sd.flag & SD_BSSRDF) { if(kernel_path_subsurface_scatter(kg, &sd, + &emission_sd, &L, &state, rng, @@ -871,7 +880,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #endif /* __SUBSURFACE__ */ /* direct lighting */ - kernel_path_surface_connect_light(kg, rng, &sd, throughput, &state, &L); + kernel_path_surface_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, &L); /* compute direct lighting and next bounce */ if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, &state, &L, &ray)) |