Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_path.h
| Show First 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) { | ||||
| path_radiance_accum_emission(L, | path_radiance_accum_emission(L, | ||||
| throughput, | throughput, | ||||
| emission, | emission, | ||||
| state->bounce); | state->bounce); | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* shader data memory used for both volumes and surfaces, saves stack space */ | |||||
| ShaderData sd; | |||||
| ShaderClosure sd_closure[MAX_MAIN_CLOSURE]; | |||||
| sd.closure = sd_closure; | |||||
| sd.max_closure = MAX_MAIN_CLOSURE; | |||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| /* volume attenuation, emission, scatter */ | /* volume attenuation, emission, scatter */ | ||||
| if(state->volume_stack[0].shader != SHADER_NONE) { | if(state->volume_stack[0].shader != SHADER_NONE) { | ||||
| Ray volume_ray = *ray; | Ray volume_ray = *ray; | ||||
| volume_ray.t = (hit)? isect.t: FLT_MAX; | volume_ray.t = (hit)? isect.t: FLT_MAX; | ||||
| bool heterogeneous = | bool heterogeneous = | ||||
| volume_stack_is_heterogeneous(kg, | volume_stack_is_heterogeneous(kg, | ||||
| state->volume_stack); | state->volume_stack); | ||||
| # ifdef __VOLUME_DECOUPLED__ | # ifdef __VOLUME_DECOUPLED__ | ||||
| int sampling_method = | int sampling_method = | ||||
| volume_stack_sampling_method(kg, | volume_stack_sampling_method(kg, | ||||
| state->volume_stack); | state->volume_stack); | ||||
| bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, false, sampling_method); | bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, false, sampling_method); | ||||
| if(decoupled) { | if(decoupled) { | ||||
| /* cache steps along volume for repeated sampling */ | /* cache steps along volume for repeated sampling */ | ||||
| VolumeSegment volume_segment; | VolumeSegment volume_segment; | ||||
| ShaderData volume_sd; | |||||
| shader_setup_from_volume(kg, | shader_setup_from_volume(kg, | ||||
| &volume_sd, | &sd, | ||||
| &volume_ray); | &volume_ray); | ||||
| kernel_volume_decoupled_record(kg, | kernel_volume_decoupled_record(kg, | ||||
| state, | state, | ||||
| &volume_ray, | &volume_ray, | ||||
| &volume_sd, | &sd, | ||||
| &volume_segment, | &volume_segment, | ||||
| heterogeneous); | heterogeneous); | ||||
| volume_segment.sampling_method = sampling_method; | volume_segment.sampling_method = sampling_method; | ||||
| /* emission */ | /* emission */ | ||||
| if(volume_segment.closure_flag & SD_EMISSION) { | if(volume_segment.closure_flag & SD_EMISSION) { | ||||
| path_radiance_accum_emission(L, | path_radiance_accum_emission(L, | ||||
| throughput, | throughput, | ||||
| volume_segment.accum_emission, | volume_segment.accum_emission, | ||||
| state->bounce); | state->bounce); | ||||
| } | } | ||||
| /* scattering */ | /* scattering */ | ||||
| VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; | VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; | ||||
| if(volume_segment.closure_flag & SD_SCATTER) { | if(volume_segment.closure_flag & SD_SCATTER) { | ||||
| int all = kernel_data.integrator.sample_all_lights_indirect; | int all = kernel_data.integrator.sample_all_lights_indirect; | ||||
| /* direct light sampling */ | /* direct light sampling */ | ||||
| kernel_branched_path_volume_connect_light(kg, | kernel_branched_path_volume_connect_light(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| throughput, | throughput, | ||||
| state, | state, | ||||
| L, | L, | ||||
| all, | all, | ||||
| &volume_ray, | &volume_ray, | ||||
| &volume_segment); | &volume_segment); | ||||
| /* indirect sample. if we use distance sampling and take just | /* indirect sample. if we use distance sampling and take just | ||||
| * one sample for direct and indirect light, we could share | * one sample for direct and indirect light, we could share | ||||
| * this computation, but makes code a bit complex */ | * this computation, but makes code a bit complex */ | ||||
| float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); | float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); | ||||
| float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); | float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); | ||||
| result = kernel_volume_decoupled_scatter(kg, | result = kernel_volume_decoupled_scatter(kg, | ||||
| state, | state, | ||||
| &volume_ray, | &volume_ray, | ||||
| &volume_sd, | &sd, | ||||
| &throughput, | &throughput, | ||||
| rphase, | rphase, | ||||
| rscatter, | rscatter, | ||||
| &volume_segment, | &volume_segment, | ||||
| NULL, | NULL, | ||||
| true); | true); | ||||
| } | } | ||||
| /* free cached steps */ | /* free cached steps */ | ||||
| kernel_volume_decoupled_free(kg, &volume_segment); | kernel_volume_decoupled_free(kg, &volume_segment); | ||||
| if(result == VOLUME_PATH_SCATTERED) { | if(result == VOLUME_PATH_SCATTERED) { | ||||
| if(kernel_path_volume_bounce(kg, | if(kernel_path_volume_bounce(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| &throughput, | &throughput, | ||||
| state, | state, | ||||
| L, | L, | ||||
| ray)) | ray)) | ||||
| { | { | ||||
| continue; | continue; | ||||
| } | } | ||||
| else { | else { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| throughput *= volume_segment.accum_transmittance; | throughput *= volume_segment.accum_transmittance; | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| # endif | # endif | ||||
| { | { | ||||
| /* integrate along volume segment with distance sampling */ | /* integrate along volume segment with distance sampling */ | ||||
| ShaderData volume_sd; | |||||
| VolumeIntegrateResult result = kernel_volume_integrate( | 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__ | # ifdef __VOLUME_SCATTER__ | ||||
| if(result == VOLUME_PATH_SCATTERED) { | if(result == VOLUME_PATH_SCATTERED) { | ||||
| /* direct lighting */ | /* direct lighting */ | ||||
| kernel_path_volume_connect_light(kg, | kernel_path_volume_connect_light(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| throughput, | throughput, | ||||
| state, | state, | ||||
| L); | L); | ||||
| /* indirect light bounce */ | /* indirect light bounce */ | ||||
| if(kernel_path_volume_bounce(kg, | if(kernel_path_volume_bounce(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| &throughput, | &throughput, | ||||
| state, | state, | ||||
| L, | L, | ||||
| ray)) | ray)) | ||||
| { | { | ||||
| continue; | continue; | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 14 Lines | #ifdef __BACKGROUND__ | ||||
| L_background, | L_background, | ||||
| state->bounce); | state->bounce); | ||||
| #endif | #endif | ||||
| break; | break; | ||||
| } | } | ||||
| /* setup shading */ | /* setup shading */ | ||||
| ShaderData sd; | |||||
| shader_setup_from_ray(kg, | shader_setup_from_ray(kg, | ||||
| &sd, | &sd, | ||||
| &isect, | &isect, | ||||
| ray); | ray); | ||||
| float rbsdf = path_state_rng_1D_for_decision(kg, rng, state, PRNG_BSDF); | 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); | |||||
| #endif | |||||
| /* blurring of bsdf after bounces, for rays that have a small likelihood | /* blurring of bsdf after bounces, for rays that have a small likelihood | ||||
| * of following this particular path (diffuse, rough glossy) */ | * of following this particular path (diffuse, rough glossy) */ | ||||
| if(kernel_data.integrator.filter_glossy != FLT_MAX) { | if(kernel_data.integrator.filter_glossy != FLT_MAX) { | ||||
| float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf; | float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf; | ||||
| if(blur_pdf < 1.0f) { | if(blur_pdf < 1.0f) { | ||||
| float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; | float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; | ||||
| ▲ Show 20 Lines • Show All 402 Lines • ▼ Show 20 Lines | if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) { | ||||
| /* intersect with lamp */ | /* intersect with lamp */ | ||||
| float3 emission; | float3 emission; | ||||
| if(indirect_lamp_emission(kg, &state, &light_ray, &emission)) | if(indirect_lamp_emission(kg, &state, &light_ray, &emission)) | ||||
| path_radiance_accum_emission(&L, throughput, emission, state.bounce); | path_radiance_accum_emission(&L, throughput, emission, state.bounce); | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* shader data memory used for both volumes and surfaces, saves stack space */ | |||||
| ShaderData sd; | |||||
| ShaderClosure sd_closure[MAX_MAIN_CLOSURE]; | |||||
| sd.closure = sd_closure; | |||||
| sd.max_closure = MAX_MAIN_CLOSURE; | |||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| /* volume attenuation, emission, scatter */ | /* volume attenuation, emission, scatter */ | ||||
| if(state.volume_stack[0].shader != SHADER_NONE) { | if(state.volume_stack[0].shader != SHADER_NONE) { | ||||
| Ray volume_ray = ray; | Ray volume_ray = ray; | ||||
| volume_ray.t = (hit)? isect.t: FLT_MAX; | volume_ray.t = (hit)? isect.t: FLT_MAX; | ||||
| bool heterogeneous = volume_stack_is_heterogeneous(kg, state.volume_stack); | bool heterogeneous = volume_stack_is_heterogeneous(kg, state.volume_stack); | ||||
| # ifdef __VOLUME_DECOUPLED__ | # ifdef __VOLUME_DECOUPLED__ | ||||
| int sampling_method = volume_stack_sampling_method(kg, state.volume_stack); | int sampling_method = volume_stack_sampling_method(kg, state.volume_stack); | ||||
| bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, true, sampling_method); | bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, true, sampling_method); | ||||
| if(decoupled) { | if(decoupled) { | ||||
| /* cache steps along volume for repeated sampling */ | /* cache steps along volume for repeated sampling */ | ||||
| VolumeSegment volume_segment; | 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, | 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; | volume_segment.sampling_method = sampling_method; | ||||
| /* emission */ | /* emission */ | ||||
| if(volume_segment.closure_flag & SD_EMISSION) | if(volume_segment.closure_flag & SD_EMISSION) | ||||
| path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state.bounce); | path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state.bounce); | ||||
| /* scattering */ | /* scattering */ | ||||
| VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; | VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED; | ||||
| if(volume_segment.closure_flag & SD_SCATTER) { | if(volume_segment.closure_flag & SD_SCATTER) { | ||||
| int all = false; | int all = false; | ||||
| /* direct light sampling */ | /* direct light sampling */ | ||||
| kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, | kernel_branched_path_volume_connect_light(kg, rng, &sd, | ||||
| throughput, &state, &L, all, &volume_ray, &volume_segment); | throughput, &state, &L, all, &volume_ray, &volume_segment); | ||||
| /* indirect sample. if we use distance sampling and take just | /* indirect sample. if we use distance sampling and take just | ||||
| * one sample for direct and indirect light, we could share | * one sample for direct and indirect light, we could share | ||||
| * this computation, but makes code a bit complex */ | * this computation, but makes code a bit complex */ | ||||
| float rphase = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_PHASE); | float rphase = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_PHASE); | ||||
| float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); | float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); | ||||
| result = kernel_volume_decoupled_scatter(kg, | result = kernel_volume_decoupled_scatter(kg, | ||||
| &state, &volume_ray, &volume_sd, &throughput, | &state, &volume_ray, &sd, &throughput, | ||||
| rphase, rscatter, &volume_segment, NULL, true); | rphase, rscatter, &volume_segment, NULL, true); | ||||
| } | } | ||||
| /* free cached steps */ | /* free cached steps */ | ||||
| kernel_volume_decoupled_free(kg, &volume_segment); | kernel_volume_decoupled_free(kg, &volume_segment); | ||||
| if(result == VOLUME_PATH_SCATTERED) { | 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; | continue; | ||||
| else | else | ||||
| break; | break; | ||||
| } | } | ||||
| else { | else { | ||||
| throughput *= volume_segment.accum_transmittance; | throughput *= volume_segment.accum_transmittance; | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| # endif | # endif | ||||
| { | { | ||||
| /* integrate along volume segment with distance sampling */ | /* integrate along volume segment with distance sampling */ | ||||
| ShaderData volume_sd; | |||||
| VolumeIntegrateResult result = kernel_volume_integrate( | 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__ | # ifdef __VOLUME_SCATTER__ | ||||
| if(result == VOLUME_PATH_SCATTERED) { | if(result == VOLUME_PATH_SCATTERED) { | ||||
| /* direct lighting */ | /* direct lighting */ | ||||
| kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L); | kernel_path_volume_connect_light(kg, rng, &sd, throughput, &state, &L); | ||||
| /* indirect light bounce */ | /* 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; | continue; | ||||
| else | else | ||||
| break; | break; | ||||
| } | } | ||||
| # endif | # endif | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| Show All 14 Lines | #ifdef __BACKGROUND__ | ||||
| float3 L_background = indirect_background(kg, &state, &ray); | float3 L_background = indirect_background(kg, &state, &ray); | ||||
| path_radiance_accum_background(&L, throughput, L_background, state.bounce); | path_radiance_accum_background(&L, throughput, L_background, state.bounce); | ||||
| #endif | #endif | ||||
| break; | break; | ||||
| } | } | ||||
| /* setup shading */ | /* setup shading */ | ||||
| ShaderData sd; | |||||
| shader_setup_from_ray(kg, &sd, &isect, &ray); | shader_setup_from_ray(kg, &sd, &isect, &ray); | ||||
| float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); | 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); | shader_eval_surface(kg, &sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); | ||||
| /* holdout */ | /* holdout */ | ||||
| #ifdef __HOLDOUT__ | #ifdef __HOLDOUT__ | ||||
| if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) { | if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) { | ||||
| if(kernel_data.background.transparent) { | if(kernel_data.background.transparent) { | ||||
| ▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines | |||||