diff options
Diffstat (limited to 'intern/cycles/kernel/film')
-rw-r--r-- | intern/cycles/kernel/film/accumulate.h | 114 |
1 files changed, 67 insertions, 47 deletions
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h index d6a385a4bff..4c4165f3640 100644 --- a/intern/cycles/kernel/film/accumulate.h +++ b/intern/cycles/kernel/film/accumulate.h @@ -320,12 +320,13 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, } /* Write background or emission to appropriate pass. */ -ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg, - ConstIntegratorState state, - float3 contribution, - ccl_global float *ccl_restrict - buffer, - const int pass) +ccl_device_inline void kernel_accum_emission_or_background_pass( + KernelGlobals kg, + ConstIntegratorState state, + float3 contribution, + ccl_global float *ccl_restrict buffer, + const int pass, + const int lightgroup = LIGHTGROUP_NONE) { if (!(kernel_data.film.light_pass_flag & PASS_ANY)) { return; @@ -351,52 +352,59 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg /* Directly visible, write to emission or background pass. */ pass_offset = pass; } - else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { + else { /* Don't write any light passes for shadow catcher, for easier * compositing back together of the combined pass. */ if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) { return; } - if (path_flag & PATH_RAY_SURFACE_PASS) { - /* Indirectly visible through reflection. */ - const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); - const float3 glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight); - - /* Glossy */ - const int glossy_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_glossy_direct : - kernel_data.film.pass_glossy_indirect); - if (glossy_pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution); - } + if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { + kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); + } - /* Transmission */ - const int transmission_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_transmission_direct : - kernel_data.film.pass_transmission_indirect); - - if (transmission_pass_offset != PASS_UNUSED) { - /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save - * GPU memory. */ - const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight; - kernel_write_pass_float3(buffer + transmission_pass_offset, - transmission_weight * contribution); - } + if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { + if (path_flag & PATH_RAY_SURFACE_PASS) { + /* Indirectly visible through reflection. */ + const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); + const float3 glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight); - /* Reconstruct diffuse subset of throughput. */ - pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_diffuse_direct : - kernel_data.film.pass_diffuse_indirect; - if (pass_offset != PASS_UNUSED) { - contribution *= diffuse_weight; + /* Glossy */ + const int glossy_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ? + kernel_data.film.pass_glossy_direct : + kernel_data.film.pass_glossy_indirect); + if (glossy_pass_offset != PASS_UNUSED) { + kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution); + } + + /* Transmission */ + const int transmission_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ? + kernel_data.film.pass_transmission_direct : + kernel_data.film.pass_transmission_indirect); + + if (transmission_pass_offset != PASS_UNUSED) { + /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save + * GPU memory. */ + const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight; + kernel_write_pass_float3(buffer + transmission_pass_offset, + transmission_weight * contribution); + } + + /* Reconstruct diffuse subset of throughput. */ + pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ? + kernel_data.film.pass_diffuse_direct : + kernel_data.film.pass_diffuse_indirect; + if (pass_offset != PASS_UNUSED) { + contribution *= diffuse_weight; + } + } + else if (path_flag & PATH_RAY_VOLUME_PASS) { + /* Indirectly visible through volume. */ + pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ? + kernel_data.film.pass_volume_direct : + kernel_data.film.pass_volume_indirect; } - } - else if (path_flag & PATH_RAY_VOLUME_PASS) { - /* Indirectly visible through volume. */ - pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_volume_direct : - kernel_data.film.pass_volume_indirect; } } @@ -449,6 +457,13 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, return; } + /* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */ + const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1; + if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { + kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); + } + if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { int pass_offset = PASS_UNUSED; @@ -566,15 +581,20 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg, kernel_accum_combined_transparent_pass( kg, path_flag, sample, contribution, transparent, buffer); } - kernel_accum_emission_or_background_pass( - kg, state, contribution, buffer, kernel_data.film.pass_background); + kernel_accum_emission_or_background_pass(kg, + state, + contribution, + buffer, + kernel_data.film.pass_background, + kernel_data.background.lightgroup); } /* Write emission to render buffer. */ ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, const float3 L, - ccl_global float *ccl_restrict render_buffer) + ccl_global float *ccl_restrict render_buffer, + const int lightgroup = LIGHTGROUP_NONE) { float3 contribution = L; kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1); @@ -585,7 +605,7 @@ ccl_device_inline void kernel_accum_emission(KernelGlobals kg, kernel_accum_combined_pass(kg, path_flag, sample, contribution, buffer); kernel_accum_emission_or_background_pass( - kg, state, contribution, buffer, kernel_data.film.pass_emission); + kg, state, contribution, buffer, kernel_data.film.pass_emission, lightgroup); } CCL_NAMESPACE_END |