Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/shade_background.h
| Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | ccl_device_inline void integrate_background(KernelGlobals kg, | ||||
| IntegratorState state, | IntegratorState state, | ||||
| ccl_global float *ccl_restrict render_buffer) | ccl_global float *ccl_restrict render_buffer) | ||||
| { | { | ||||
| /* Accumulate transparency for transparent background. We can skip background | /* Accumulate transparency for transparent background. We can skip background | ||||
| * shader evaluation unless a background pass is used. */ | * shader evaluation unless a background pass is used. */ | ||||
| bool eval_background = true; | bool eval_background = true; | ||||
| float transparent = 0.0f; | float transparent = 0.0f; | ||||
| int path_flag = INTEGRATOR_STATE(state, path, flag); | |||||
| const bool is_transparent_background_ray = kernel_data.background.transparent && | const bool is_transparent_background_ray = kernel_data.background.transparent && | ||||
| (INTEGRATOR_STATE(state, path, flag) & | (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND); | ||||
| PATH_RAY_TRANSPARENT_BACKGROUND); | |||||
| if (is_transparent_background_ray) { | if (is_transparent_background_ray) { | ||||
| transparent = average(INTEGRATOR_STATE(state, path, throughput)); | transparent = average(INTEGRATOR_STATE(state, path, throughput)); | ||||
| #ifdef __PASSES__ | #ifdef __PASSES__ | ||||
| eval_background = (kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND)); | eval_background = (kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND)); | ||||
| #else | #else | ||||
| eval_background = false; | eval_background = false; | ||||
| #endif | #endif | ||||
| } | } | ||||
| #ifdef __MNEE__ | #ifdef __MNEE__ | ||||
| if (INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_CULL_LIGHT_CONNECTION) { | if (INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_CULL_LIGHT_CONNECTION) { | ||||
| if (kernel_data.background.use_mis) { | if (kernel_data.background.use_mis) { | ||||
| for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) { | for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) { | ||||
| /* This path should have been resolved with mnee, it will | /* This path should have been resolved with mnee, it will | ||||
| * generate a firefly for small lights since it is improbable. */ | * generate a firefly for small lights since it is improbable. */ | ||||
| const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp); | const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp); | ||||
| if (klight->type == LIGHT_BACKGROUND && klight->use_caustics) { | if (klight->type == LIGHT_BACKGROUND && klight->use_caustics) { | ||||
| eval_background = false; | eval_background = false; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| Show All 13 Lines | if (path_state_ao_bounce(kg, state)) { | ||||
| L *= kernel_data.integrator.ao_bounces_factor; | L *= kernel_data.integrator.ao_bounces_factor; | ||||
| } | } | ||||
| /* Background MIS weights. */ | /* Background MIS weights. */ | ||||
| float mis_weight = 1.0f; | float mis_weight = 1.0f; | ||||
| /* Check if background light exists or if we should skip pdf. */ | /* Check if background light exists or if we should skip pdf. */ | ||||
| if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_MIS_SKIP) && | if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_MIS_SKIP) && | ||||
| kernel_data.background.use_mis) { | kernel_data.background.use_mis) { | ||||
| const float3 ray_P = INTEGRATOR_STATE(state, ray, P); | mis_weight = light_sample_mis_weight_forward_background(kg, state, path_flag); | ||||
| const float3 ray_D = INTEGRATOR_STATE(state, ray, D); | |||||
| const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); | |||||
| /* multiple importance sampling, get background light pdf for ray | |||||
| * direction, and compute weight with respect to BSDF pdf */ | |||||
| const float pdf = background_light_pdf(kg, ray_P, ray_D); | |||||
| mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf); | |||||
| } | } | ||||
| guiding_record_background(kg, state, L, mis_weight); | guiding_record_background(kg, state, L, mis_weight); | ||||
| L *= mis_weight; | L *= mis_weight; | ||||
| } | } | ||||
| /* Write to render buffer. */ | /* Write to render buffer. */ | ||||
| film_write_background(kg, state, L, transparent, is_transparent_background_ray, render_buffer); | film_write_background(kg, state, L, transparent, is_transparent_background_ray, render_buffer); | ||||
| } | } | ||||
| ccl_device_inline void integrate_distant_lights(KernelGlobals kg, | ccl_device_inline void integrate_distant_lights(KernelGlobals kg, | ||||
| IntegratorState state, | IntegratorState state, | ||||
| ccl_global float *ccl_restrict render_buffer) | ccl_global float *ccl_restrict render_buffer) | ||||
| { | { | ||||
| const float3 ray_D = INTEGRATOR_STATE(state, ray, D); | const float3 ray_D = INTEGRATOR_STATE(state, ray, D); | ||||
| const float ray_time = INTEGRATOR_STATE(state, ray, time); | const float ray_time = INTEGRATOR_STATE(state, ray, time); | ||||
| LightSample ls ccl_optional_struct_init; | LightSample ls ccl_optional_struct_init; | ||||
| for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) { | for (int lamp = 0; lamp < kernel_data.integrator.num_lights; lamp++) { | ||||
| if (light_sample_from_distant_ray(kg, ray_D, lamp, &ls)) { | if (distant_light_sample_from_intersection(kg, ray_D, lamp, &ls)) { | ||||
| /* Use visibility flag to skip lights. */ | /* Use visibility flag to skip lights. */ | ||||
| #ifdef __PASSES__ | #ifdef __PASSES__ | ||||
| const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); | ||||
| if (ls.shader & SHADER_EXCLUDE_ANY) { | if (ls.shader & SHADER_EXCLUDE_ANY) { | ||||
| if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) || | if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (path_flag & PATH_RAY_DIFFUSE)) || | ||||
| ((ls.shader & SHADER_EXCLUDE_GLOSSY) && | ((ls.shader & SHADER_EXCLUDE_GLOSSY) && | ||||
| ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) == | ((path_flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) == | ||||
| Show All 22 Lines | #endif /* __MNEE__ */ | ||||
| Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); | Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); | ||||
| if (is_zero(light_eval)) { | if (is_zero(light_eval)) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* MIS weighting. */ | /* MIS weighting. */ | ||||
| float mis_weight = 1.0f; | float mis_weight = 1.0f; | ||||
| if (!(path_flag & PATH_RAY_MIS_SKIP)) { | if (!(path_flag & PATH_RAY_MIS_SKIP)) { | ||||
| /* multiple importance sampling, get regular light pdf, | mis_weight = light_sample_mis_weight_forward_distant(kg, state, path_flag, &ls); | ||||
| * and compute weight with respect to BSDF pdf */ | |||||
| const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf); | |||||
| mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf); | |||||
| } | } | ||||
| /* Write to render buffer. */ | /* Write to render buffer. */ | ||||
| guiding_record_background(kg, state, light_eval, mis_weight); | guiding_record_background(kg, state, light_eval, mis_weight); | ||||
| film_write_surface_emission( | film_write_surface_emission( | ||||
| kg, state, light_eval, mis_weight, render_buffer, kernel_data.background.lightgroup); | kg, state, light_eval, mis_weight, render_buffer, kernel_data.background.lightgroup); | ||||
| } | } | ||||
| } | } | ||||
| Show All 27 Lines | |||||