Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_path_branched.h
| Show First 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | #ifdef __VOLUME__ | ||||
| Ray volume_ray = *ray; | Ray volume_ray = *ray; | ||||
| bool need_update_volume_stack = kernel_data.integrator.use_volumes && | bool need_update_volume_stack = kernel_data.integrator.use_volumes && | ||||
| ccl_fetch(sd, flag) & SD_OBJECT_INTERSECTS_VOLUME; | ccl_fetch(sd, flag) & SD_OBJECT_INTERSECTS_VOLUME; | ||||
| #endif | #endif | ||||
| /* compute lighting with the BSDF closure */ | /* compute lighting with the BSDF closure */ | ||||
| for(int hit = 0; hit < num_hits; hit++) { | for(int hit = 0; hit < num_hits; hit++) { | ||||
| ShaderData bssrdf_sd = *sd; | ShaderData bssrdf_sd = *sd; | ||||
| ShaderClosure bssrdf_sd_closure[MAX_BSSRDF_CLOSURE]; | |||||
| bssrdf_sd.closure = bssrdf_sd_closure; | |||||
| bssrdf_sd.max_closure = MAX_BSSRDF_CLOSURE; | |||||
| subsurface_scatter_multi_setup(kg, | subsurface_scatter_multi_setup(kg, | ||||
| &ss_isect, | &ss_isect, | ||||
| hit, | hit, | ||||
| &bssrdf_sd, | &bssrdf_sd, | ||||
| state, | state, | ||||
| state->flag, | state->flag, | ||||
| sc, | sc, | ||||
| true); | true); | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| #ifdef __KERNEL_DEBUG__ | #ifdef __KERNEL_DEBUG__ | ||||
| debug_data.num_bvh_traversal_steps += isect.num_traversal_steps; | debug_data.num_bvh_traversal_steps += isect.num_traversal_steps; | ||||
| debug_data.num_bvh_traversed_instances += isect.num_traversed_instances; | debug_data.num_bvh_traversed_instances += isect.num_traversed_instances; | ||||
| debug_data.num_ray_bounces++; | debug_data.num_ray_bounces++; | ||||
| #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__ | ||||
| /* decoupled ray marching only supported on CPU */ | /* decoupled ray marching only supported on CPU */ | ||||
| /* 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); | ||||
| /* direct light sampling */ | /* direct light sampling */ | ||||
| if(volume_segment.closure_flag & SD_SCATTER) { | if(volume_segment.closure_flag & SD_SCATTER) { | ||||
| volume_segment.sampling_method = volume_stack_sampling_method(kg, state.volume_stack); | volume_segment.sampling_method = volume_stack_sampling_method(kg, state.volume_stack); | ||||
| int all = kernel_data.integrator.sample_all_lights_direct; | int all = kernel_data.integrator.sample_all_lights_direct; | ||||
| 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 light sampling */ | /* indirect light sampling */ | ||||
| int num_samples = kernel_data.integrator.volume_samples; | int num_samples = kernel_data.integrator.volume_samples; | ||||
| float num_samples_inv = 1.0f/num_samples; | float num_samples_inv = 1.0f/num_samples; | ||||
| for(int j = 0; j < num_samples; j++) { | for(int j = 0; j < num_samples; j++) { | ||||
| /* workaround to fix correlation bug in T38710, can find better solution | /* workaround to fix correlation bug in T38710, can find better solution | ||||
| Show All 10 Lines | #ifdef __VOLUME_DECOUPLED__ | ||||
| /* scatter sample. if we use distance sampling and take just one | /* scatter sample. if we use distance sampling and take just one | ||||
| * sample for direct and indirect light, we could share this | * sample for direct and indirect light, we could share this | ||||
| * computation, but makes code a bit complex */ | * computation, but makes code a bit complex */ | ||||
| float rphase = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_PHASE); | float rphase = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_PHASE); | ||||
| float rscatter = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_SCATTER_DISTANCE); | float rscatter = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_SCATTER_DISTANCE); | ||||
| VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, | VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, | ||||
| &ps, &pray, &volume_sd, &tp, rphase, rscatter, &volume_segment, NULL, false); | &ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false); | ||||
| (void)result; | (void)result; | ||||
| kernel_assert(result == VOLUME_PATH_SCATTERED); | kernel_assert(result == VOLUME_PATH_SCATTERED); | ||||
| if(kernel_path_volume_bounce(kg, | if(kernel_path_volume_bounce(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| &tp, | &tp, | ||||
| &ps, | &ps, | ||||
| &L, | &L, | ||||
| &pray)) | &pray)) | ||||
| { | { | ||||
| kernel_path_indirect(kg, | kernel_path_indirect(kg, | ||||
| rng, | rng, | ||||
| &pray, | &pray, | ||||
| Show All 23 Lines | #else | ||||
| float num_samples_inv = 1.0f/num_samples; | float num_samples_inv = 1.0f/num_samples; | ||||
| /* todo: we should cache the shader evaluations from stepping | /* todo: we should cache the shader evaluations from stepping | ||||
| * through the volume, for now we redo them multiple times */ | * through the volume, for now we redo them multiple times */ | ||||
| for(int j = 0; j < num_samples; j++) { | for(int j = 0; j < num_samples; j++) { | ||||
| PathState ps = state; | PathState ps = state; | ||||
| Ray pray = ray; | Ray pray = ray; | ||||
| ShaderData volume_sd; | |||||
| float3 tp = throughput * num_samples_inv; | float3 tp = throughput * num_samples_inv; | ||||
| /* branch RNG state */ | /* branch RNG state */ | ||||
| path_state_branch(&ps, j, num_samples); | path_state_branch(&ps, j, num_samples); | ||||
| VolumeIntegrateResult result = kernel_volume_integrate( | VolumeIntegrateResult result = kernel_volume_integrate( | ||||
| kg, &ps, &volume_sd, &volume_ray, &L, &tp, rng, heterogeneous); | kg, &ps, &sd, &volume_ray, &L, &tp, rng, heterogeneous); | ||||
| #ifdef __VOLUME_SCATTER__ | #ifdef __VOLUME_SCATTER__ | ||||
| if(result == VOLUME_PATH_SCATTERED) { | if(result == VOLUME_PATH_SCATTERED) { | ||||
| /* todo: support equiangular, MIS and all light sampling. | /* todo: support equiangular, MIS and all light sampling. | ||||
| * alternatively get decoupled ray marching working on the GPU */ | * alternatively get decoupled ray marching working on the GPU */ | ||||
| kernel_path_volume_connect_light(kg, rng, &volume_sd, tp, &state, &L); | kernel_path_volume_connect_light(kg, rng, &sd, tp, &state, &L); | ||||
| if(kernel_path_volume_bounce(kg, | if(kernel_path_volume_bounce(kg, | ||||
| rng, | rng, | ||||
| &volume_sd, | &sd, | ||||
| &tp, | &tp, | ||||
| &ps, | &ps, | ||||
| &L, | &L, | ||||
| &pray)) | &pray)) | ||||
| { | { | ||||
| kernel_path_indirect(kg, | kernel_path_indirect(kg, | ||||
| rng, | rng, | ||||
| &pray, | &pray, | ||||
| Show All 33 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); | ||||
| shader_eval_surface(kg, &sd, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); | shader_eval_surface(kg, &sd, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); | ||||
| shader_merge_closures(&sd); | |||||
| /* holdout */ | /* holdout */ | ||||
| #ifdef __HOLDOUT__ | #ifdef __HOLDOUT__ | ||||
| if(sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) { | if(sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) { | ||||
| if(kernel_data.background.transparent) { | if(kernel_data.background.transparent) { | ||||
| float3 holdout_weight; | float3 holdout_weight; | ||||
| if(sd.flag & SD_HOLDOUT_MASK) | if(sd.flag & SD_HOLDOUT_MASK) | ||||
| ▲ Show 20 Lines • Show All 148 Lines • Show Last 20 Lines | |||||