diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-11-12 18:43:43 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-11-12 22:03:46 +0300 |
commit | b4d9b8b7f8d69165bec0c0006cbc1cd03e769081 (patch) | |
tree | 1aee76caaac483c2b103a8a1cb092965c4458f03 /intern/cycles | |
parent | ef0b8d6306e5e1cddf1d7a2087e5589adcf74172 (diff) |
Fix T91893, T92455: wrong transmission pass with hair and multiscatter glass
We need to increase GPU memory usage a bit. Unfortunately we can't get away
with writing either reflection or transmission passes because these BSDFs may
scatter in either direction but still must be in a fixed reflection or
transmission category to match up with the color passes.
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/film/accumulate.h | 183 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/path_state.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_surface.h | 18 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shade_volume.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shader_eval.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/shadow_state_template.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/state_template.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/subsurface.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/types.h | 18 | ||||
-rw-r--r-- | intern/cycles/scene/film.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/scene/osl.cpp | 33 |
11 files changed, 175 insertions, 131 deletions
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h index 33f913a6746..ce338936376 100644 --- a/intern/cycles/kernel/film/accumulate.h +++ b/intern/cycles/kernel/film/accumulate.h @@ -33,62 +33,72 @@ CCL_NAMESPACE_BEGIN * them separately. */ ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval, - const bool is_diffuse, + const ClosureType closure_type, float3 value) { eval->diffuse = zero_float3(); eval->glossy = zero_float3(); - if (is_diffuse) { + if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) { eval->diffuse = value; } - else { + else if (CLOSURE_IS_BSDF_GLOSSY(closure_type)) { eval->glossy = value; } + + eval->sum = value; } ccl_device_inline void bsdf_eval_accum(ccl_private BsdfEval *eval, - const bool is_diffuse, - float3 value, - float mis_weight) + const ClosureType closure_type, + float3 value) { - value *= mis_weight; - - if (is_diffuse) { + if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) { eval->diffuse += value; } - else { + else if (CLOSURE_IS_BSDF_GLOSSY(closure_type)) { eval->glossy += value; } + + eval->sum += value; } ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval) { - return is_zero(eval->diffuse) && is_zero(eval->glossy); + return is_zero(eval->sum); } ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value) { eval->diffuse *= value; eval->glossy *= value; + eval->sum *= value; } ccl_device_inline void bsdf_eval_mul3(ccl_private BsdfEval *eval, float3 value) { eval->diffuse *= value; eval->glossy *= value; + eval->sum *= value; } ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval) { - return eval->diffuse + eval->glossy; + return eval->sum; } -ccl_device_inline float3 bsdf_eval_diffuse_glossy_ratio(ccl_private const BsdfEval *eval) +ccl_device_inline float3 bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval) { - /* Ratio of diffuse and glossy to recover proportions for writing to render pass. + /* Ratio of diffuse weight to recover proportions for writing to render pass. * We assume reflection, transmission and volume scatter to be exclusive. */ - return safe_divide_float3_float3(eval->diffuse, eval->diffuse + eval->glossy); + return safe_divide_float3_float3(eval->diffuse, eval->sum); +} + +ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval) +{ + /* Ratio of glossy weight to recover proportions for writing to render pass. + * We assume reflection, transmission and volume scatter to be exclusive. */ + return safe_divide_float3_float3(eval->glossy, eval->sum); } /* -------------------------------------------------------------------- @@ -351,37 +361,47 @@ 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 (path_flag & (PATH_RAY_REFLECT_PASS | PATH_RAY_TRANSMISSION_PASS)) { - /* Indirectly visible through reflection. */ - const int glossy_pass_offset = (path_flag & PATH_RAY_REFLECT_PASS) ? - ((INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_glossy_direct : - kernel_data.film.pass_glossy_indirect) : - ((INTEGRATOR_STATE(state, path, bounce) == 1) ? - kernel_data.film.pass_transmission_direct : - kernel_data.film.pass_transmission_indirect); - - if (glossy_pass_offset != PASS_UNUSED) { - /* Glossy is a subset of the throughput, reconstruct it here using the - * diffuse-glossy ratio. */ - const float3 ratio = INTEGRATOR_STATE(state, path, diffuse_glossy_ratio); - const float3 glossy_contribution = (one_float3() - ratio) * contribution; - kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_contribution); - } + else 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); + + /* 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 *= INTEGRATOR_STATE(state, path, diffuse_glossy_ratio); + /* 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; } /* Single write call for GPU coherence. */ @@ -426,45 +446,56 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, #ifdef __PASSES__ if (kernel_data.film.light_pass_flag & PASS_ANY) { const uint32_t path_flag = INTEGRATOR_STATE(state, shadow_path, flag); - int pass_offset = PASS_UNUSED; - if (path_flag & (PATH_RAY_REFLECT_PASS | PATH_RAY_TRANSMISSION_PASS)) { - /* Indirectly visible through reflection. */ - const int glossy_pass_offset = (path_flag & PATH_RAY_REFLECT_PASS) ? - ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? - kernel_data.film.pass_glossy_direct : - kernel_data.film.pass_glossy_indirect) : - ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? - kernel_data.film.pass_transmission_direct : - kernel_data.film.pass_transmission_indirect); + if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { + int pass_offset = PASS_UNUSED; - if (glossy_pass_offset != PASS_UNUSED) { - /* Glossy is a subset of the throughput, reconstruct it here using the - * diffuse-glossy ratio. */ - const float3 ratio = INTEGRATOR_STATE(state, shadow_path, diffuse_glossy_ratio); - const float3 glossy_contribution = (one_float3() - ratio) * contribution; - kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_contribution); + if (path_flag & PATH_RAY_SURFACE_PASS) { + /* Indirectly visible through reflection. */ + const float3 diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight); + const float3 glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight); + + /* Glossy */ + const int glossy_pass_offset = ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? + 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, shadow_path, bounce) == 0) ? + 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, shadow_path, bounce) == 0) ? + 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, shadow_path, bounce) == 0) ? + kernel_data.film.pass_volume_direct : + kernel_data.film.pass_volume_indirect; } - /* Reconstruct diffuse subset of throughput. */ - pass_offset = (INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? - kernel_data.film.pass_diffuse_direct : - kernel_data.film.pass_diffuse_indirect; + /* Single write call for GPU coherence. */ if (pass_offset != PASS_UNUSED) { - contribution *= INTEGRATOR_STATE(state, shadow_path, diffuse_glossy_ratio); + kernel_write_pass_float3(buffer + pass_offset, contribution); } } - else if (path_flag & PATH_RAY_VOLUME_PASS) { - /* Indirectly visible through volume. */ - pass_offset = (INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? - kernel_data.film.pass_volume_direct : - kernel_data.film.pass_volume_indirect; - } - - /* Single write call for GPU coherence. */ - if (pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + pass_offset, contribution); - } /* Write shadow pass. */ if (kernel_data.film.pass_shadow != PASS_UNUSED && (path_flag & PATH_RAY_SHADOW_FOR_LIGHT) && diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h index c325d829b5c..de6c3ae8161 100644 --- a/intern/cycles/kernel/integrator/path_state.h +++ b/intern/cycles/kernel/integrator/path_state.h @@ -185,7 +185,7 @@ ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, /* Render pass categories. */ if (bounce == 1) { - flag |= (label & LABEL_TRANSMIT) ? PATH_RAY_TRANSMISSION_PASS : PATH_RAY_REFLECT_PASS; + flag |= PATH_RAY_SURFACE_PASS; } } diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 16a61c15f58..2793dd3e218 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -191,14 +191,18 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce); uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; - shadow_flag |= (is_transmission) ? PATH_RAY_TRANSMISSION_PASS : PATH_RAY_REFLECT_PASS; + shadow_flag |= PATH_RAY_SURFACE_PASS; const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - const float3 diffuse_glossy_ratio = (bounce == 0) ? - bsdf_eval_diffuse_glossy_ratio(&bsdf_eval) : - INTEGRATOR_STATE(state, path, diffuse_glossy_ratio); - INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_glossy_ratio) = diffuse_glossy_ratio; + const float3 pass_diffuse_weight = (bounce == 0) ? + bsdf_eval_pass_diffuse_weight(&bsdf_eval) : + INTEGRATOR_STATE(state, path, pass_diffuse_weight); + const float3 pass_glossy_weight = (bounce == 0) ? + bsdf_eval_pass_glossy_weight(&bsdf_eval) : + INTEGRATOR_STATE(state, path, pass_glossy_weight); + INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight; + INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight; } INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE( @@ -283,7 +287,9 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { if (INTEGRATOR_STATE(state, path, bounce) == 0) { - INTEGRATOR_STATE_WRITE(state, path, diffuse_glossy_ratio) = bsdf_eval_diffuse_glossy_ratio( + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = bsdf_eval_pass_diffuse_weight( + &bsdf_eval); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = bsdf_eval_pass_glossy_weight( &bsdf_eval); } } diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index b4d02b1b664..f42614cc87f 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -794,10 +794,11 @@ ccl_device_forceinline void integrate_volume_direct_light( const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - const float3 diffuse_glossy_ratio = (bounce == 0) ? - one_float3() : - INTEGRATOR_STATE(state, path, diffuse_glossy_ratio); - INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_glossy_ratio) = diffuse_glossy_ratio; + const float3 pass_diffuse_weight = (bounce == 0) ? + one_float3() : + INTEGRATOR_STATE(state, path, pass_diffuse_weight); + INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight; + INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = zero_float3(); } INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE( @@ -876,7 +877,8 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase; if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - INTEGRATOR_STATE_WRITE(state, path, diffuse_glossy_ratio) = one_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3(); } /* Update path state */ diff --git a/intern/cycles/kernel/integrator/shader_eval.h b/intern/cycles/kernel/integrator/shader_eval.h index 2560b71dc32..169a01d0797 100644 --- a/intern/cycles/kernel/integrator/shader_eval.h +++ b/intern/cycles/kernel/integrator/shader_eval.h @@ -246,8 +246,7 @@ ccl_device_inline float _shader_bsdf_multi_eval(KernelGlobals kg, float3 eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf); if (bsdf_pdf != 0.0f) { - const bool is_diffuse = CLOSURE_IS_BSDF_DIFFUSE(sc->type); - bsdf_eval_accum(result_eval, is_diffuse, eval * sc->weight, 1.0f); + bsdf_eval_accum(result_eval, sc->type, eval * sc->weight); sum_pdf += bsdf_pdf * sc->sample_weight; } } @@ -272,7 +271,7 @@ ccl_device_inline ccl_private BsdfEval *bsdf_eval, const uint light_shader_flags) { - bsdf_eval_init(bsdf_eval, false, zero_float3()); + bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_float3()); return _shader_bsdf_multi_eval( kg, sd, omega_in, is_transmission, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags); @@ -365,8 +364,7 @@ ccl_device int shader_bsdf_sample_closure(KernelGlobals kg, label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if (*pdf != 0.0f) { - const bool is_diffuse = CLOSURE_IS_BSDF_DIFFUSE(sc->type); - bsdf_eval_init(bsdf_eval, is_diffuse, eval * sc->weight); + bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight); if (sd->num_closure > 1) { const bool is_transmission = shader_bsdf_is_transmission(sd, *omega_in); @@ -692,7 +690,7 @@ ccl_device_inline float _shader_volume_phase_multi_eval( float3 eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf); if (phase_pdf != 0.0f) { - bsdf_eval_accum(result_eval, false, eval, 1.0f); + bsdf_eval_accum(result_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); sum_pdf += phase_pdf * svc->sample_weight; } @@ -708,7 +706,7 @@ ccl_device float shader_volume_phase_eval(KernelGlobals kg, const float3 omega_in, ccl_private BsdfEval *phase_eval) { - bsdf_eval_init(phase_eval, false, zero_float3()); + bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_float3()); return _shader_volume_phase_multi_eval(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f); } @@ -766,7 +764,7 @@ ccl_device int shader_volume_phase_sample(KernelGlobals kg, label = volume_phase_sample(sd, svc, randu, randv, &eval, omega_in, domega_in, pdf); if (*pdf != 0.0f) { - bsdf_eval_init(phase_eval, false, eval); + bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); } return label; @@ -789,7 +787,7 @@ ccl_device int shader_phase_sample_closure(KernelGlobals kg, label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if (*pdf != 0.0f) - bsdf_eval_init(phase_eval, false, eval); + bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); return label; } diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h index da25e58ff1b..667ab88c8c4 100644 --- a/intern/cycles/kernel/integrator/shadow_state_template.h +++ b/intern/cycles/kernel/integrator/shadow_state_template.h @@ -46,8 +46,9 @@ KERNEL_STRUCT_MEMBER(shadow_path, float3, unshadowed_throughput, KERNEL_FEATURE_SHADOW_PASS | KERNEL_FEATURE_AO_ADDITIVE) -/* Ratio of throughput to distinguish diffuse and glossy render passes. */ -KERNEL_STRUCT_MEMBER(shadow_path, float3, diffuse_glossy_ratio, KERNEL_FEATURE_LIGHT_PASSES) +/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */ +KERNEL_STRUCT_MEMBER(shadow_path, float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(shadow_path, float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) /* Number of intersections found by ray-tracing. */ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING) KERNEL_STRUCT_END(shadow_path) diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h index 25475883915..3299f973713 100644 --- a/intern/cycles/kernel/integrator/state_template.h +++ b/intern/cycles/kernel/integrator/state_template.h @@ -60,8 +60,9 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING) KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING) /* Throughput. */ KERNEL_STRUCT_MEMBER(path, float3, throughput, KERNEL_FEATURE_PATH_TRACING) -/* Ratio of throughput to distinguish diffuse and glossy render passes. */ -KERNEL_STRUCT_MEMBER(path, float3, diffuse_glossy_ratio, KERNEL_FEATURE_LIGHT_PASSES) +/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */ +KERNEL_STRUCT_MEMBER(path, float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(path, float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) /* Denoising. */ KERNEL_STRUCT_MEMBER(path, float3, denoising_feature_throughput, KERNEL_FEATURE_DENOISING) /* Shader sorting. */ diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h index 49466112387..9010318257f 100644 --- a/intern/cycles/kernel/integrator/subsurface.h +++ b/intern/cycles/kernel/integrator/subsurface.h @@ -79,7 +79,8 @@ ccl_device int subsurface_bounce(KernelGlobals kg, if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { if (INTEGRATOR_STATE(state, path, bounce) == 0) { - INTEGRATOR_STATE_WRITE(state, path, diffuse_glossy_ratio) = one_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3(); } } diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 4d4246d2a74..01700add22b 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -286,27 +286,26 @@ enum PathRayFlag { PATH_RAY_DENOISING_FEATURES = (1U << 23U), /* Render pass categories. */ - PATH_RAY_REFLECT_PASS = (1U << 24U), - PATH_RAY_TRANSMISSION_PASS = (1U << 25U), - PATH_RAY_VOLUME_PASS = (1U << 26U), - PATH_RAY_ANY_PASS = (PATH_RAY_REFLECT_PASS | PATH_RAY_TRANSMISSION_PASS | PATH_RAY_VOLUME_PASS), + PATH_RAY_SURFACE_PASS = (1U << 24U), + PATH_RAY_VOLUME_PASS = (1U << 25U), + PATH_RAY_ANY_PASS = (PATH_RAY_SURFACE_PASS | PATH_RAY_VOLUME_PASS), /* Shadow ray is for a light or surface, or AO. */ - PATH_RAY_SHADOW_FOR_LIGHT = (1U << 27U), - PATH_RAY_SHADOW_FOR_AO = (1U << 28U), + PATH_RAY_SHADOW_FOR_LIGHT = (1U << 26U), + PATH_RAY_SHADOW_FOR_AO = (1U << 27U), /* A shadow catcher object was hit and the path was split into two. */ - PATH_RAY_SHADOW_CATCHER_HIT = (1U << 29U), + PATH_RAY_SHADOW_CATCHER_HIT = (1U << 28U), /* A shadow catcher object was hit and this path traces only shadow catchers, writing them into * their dedicated pass for later division. * * NOTE: Is not covered with `PATH_RAY_ANY_PASS` because shadow catcher does special handling * which is separate from the light passes. */ - PATH_RAY_SHADOW_CATCHER_PASS = (1U << 30U), + PATH_RAY_SHADOW_CATCHER_PASS = (1U << 29U), /* Path is evaluating background for an approximate shadow catcher with non-transparent film. */ - PATH_RAY_SHADOW_CATCHER_BACKGROUND = (1U << 31U), + PATH_RAY_SHADOW_CATCHER_BACKGROUND = (1U << 30U), }; /* Configure ray visibility bits for rays and objects respectively, @@ -428,6 +427,7 @@ typedef enum CryptomatteType { typedef struct BsdfEval { float3 diffuse; float3 glossy; + float3 sum; } BsdfEval; /* Closure Filter */ diff --git a/intern/cycles/scene/film.cpp b/intern/cycles/scene/film.cpp index 591f309384e..cdaaea6be2f 100644 --- a/intern/cycles/scene/film.cpp +++ b/intern/cycles/scene/film.cpp @@ -187,8 +187,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) kfilm->pass_transmission_indirect = PASS_UNUSED; kfilm->pass_volume_direct = PASS_UNUSED; kfilm->pass_volume_indirect = PASS_UNUSED; - kfilm->pass_volume_direct = PASS_UNUSED; - kfilm->pass_volume_indirect = PASS_UNUSED; kfilm->pass_shadow = PASS_UNUSED; /* Mark passes as unused so that the kernel knows the pass is inaccessible. */ @@ -673,13 +671,12 @@ uint Film::get_kernel_features(const Scene *scene) const kernel_features |= KERNEL_FEATURE_DENOISING; } - if (pass_type != PASS_NONE && pass_type != PASS_COMBINED && - pass_type <= PASS_CATEGORY_LIGHT_END) { + if (pass_type >= PASS_DIFFUSE && pass_type <= PASS_VOLUME_INDIRECT) { kernel_features |= KERNEL_FEATURE_LIGHT_PASSES; + } - if (pass_type == PASS_SHADOW) { - kernel_features |= KERNEL_FEATURE_SHADOW_PASS; - } + if (pass_type == PASS_SHADOW) { + kernel_features |= KERNEL_FEATURE_SHADOW_PASS; } if (pass_type == PASS_AO) { diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index c5f38d4f270..0844bff7d4a 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -274,19 +274,26 @@ void OSLShaderManager::shading_system_init() "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */ - "__unused__", /* PATH_RAY_SINGLE_PASS_DONE */ - "__unused__", /* PATH_RAY_TRANSPARENT_BACKGROUND */ - "__unused__", /* PATH_RAY_TERMINATE_IMMEDIATE */ - "__unused__", /* PATH_RAY_TERMINATE_AFTER_TRANSPARENT */ - "__unused__", /* PATH_RAY_EMISSION */ - "__unused__", /* PATH_RAY_SUBSURFACE */ - "__unused__", /* PATH_RAY_DENOISING_FEATURES */ - "__unused__", /* PATH_RAY_REFLECT_PASS */ - "__unused__", /* PATH_RAY_TRANSMISSION_PASS */ - "__unused__", /* PATH_RAY_VOLUME_PASS */ - "__unused__", /* PATH_RAY_SHADOW_FOR_LIGHT */ - "__unused__", /* PATH_RAY_SHADOW_CATCHER_HIT */ - "__unused__", /* PATH_RAY_SHADOW_CATCHER_PASS */ + /* Remaining irrelevant bits up to 32. */ + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", + "__unused__", }; const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]); |