From 17bda2cf3f818b13caf72ca8120a11b3c28cdff5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jun 2025 20:04:49 +0200 Subject: [PATCH] Cycles: Enable multi-bounce random walk subsurface scattering Multi-bounce was mainly disabled for disk sampling where the probability of hitting something is relatively low even with high albedo, but this is not so much an issue with random walk. This reduces darkening artifacts at the cost of some extra render time. The difference is mainly visible when using a high radius. Pull Request: https://projects.blender.org/blender/blender/pulls/140665 --- intern/cycles/kernel/closure/bssrdf.h | 8 +++++--- intern/cycles/kernel/integrator/subsurface.h | 7 ++++--- .../cycles_renders/light_path_is_reflection_ray.png | 4 ++-- tests/files/render/light/all_light_types_in_volume.blend | 4 ++-- .../light/cycles_renders/all_light_types_in_volume.png | 4 ++-- .../cycles_renders/principled_bsdf_subsurface.png | 4 ++-- .../reports/cycles_renders/sss_and_volume_39823.png | 4 ++-- .../files/render/sss/cycles_renders/sss_concave_clamp.png | 4 ++-- .../render/sss/cycles_renders/sss_diffuse_mix_clamp.png | 4 ++-- .../files/render/sss/cycles_renders/subsurface_cubic.png | 4 ++-- .../render/sss/cycles_renders/subsurface_gaussian.png | 4 ++-- .../render/sss/cycles_renders/subsurface_random_walk.png | 4 ++-- .../sss/cycles_renders/subsurface_random_walk_thin.png | 4 ++-- 13 files changed, 31 insertions(+), 28 deletions(-) diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index 2c791f0e526..7f3355ca73a 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -305,9 +305,11 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd, int bssrdf_channels = SPECTRUM_CHANNELS; Spectrum diffuse_weight = zero_spectrum(); - if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - /* Always fall back to diffuse after a diffuse ancestor. Can't see it that well and it adds - * considerable noise due to probabilities of continuing the path getting lower and lower. */ + if (type == CLOSURE_BSSRDF_BURLEY_ID && (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)) { + /* Fall back to diffuse after a diffuse ancestor for Christensen-Burley. Can't see it that + * well and it adds considerable noise due to probabilities of continuing the path getting + * lower and lower. The disk sampling must probe in directions where most of the time + * nothing will be hit. */ bssrdf_channels = 0; diffuse_weight = bssrdf->weight; } diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h index cd0bb6252cd..42f68a08d93 100644 --- a/intern/cycles/kernel/integrator/subsurface.h +++ b/intern/cycles/kernel/integrator/subsurface.h @@ -79,9 +79,6 @@ ccl_device int subsurface_bounce(KernelGlobals kg, ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc) { - /* We should never have two consecutive BSSRDF bounces, the second one should - * be converted to a diffuse BSDF to avoid this. */ - kernel_assert(!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_DIFFUSE_ANCESTOR)); /* Setup path state for intersect_subsurface kernel. */ const ccl_private Bssrdf *bssrdf = (const ccl_private Bssrdf *)sc; @@ -102,6 +99,10 @@ ccl_device int subsurface_bounce(KernelGlobals kg, uint32_t path_flag = (INTEGRATOR_STATE(state, path, flag) & ~PATH_RAY_CAMERA); if (sc->type == CLOSURE_BSSRDF_BURLEY_ID) { + /* We should never have two consecutive BSSRDF bounces, the second one should + * be converted to a diffuse BSDF to avoid this. */ + kernel_assert(!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_DIFFUSE_ANCESTOR)); + path_flag |= PATH_RAY_SUBSURFACE_DISK; INTEGRATOR_STATE_WRITE(state, subsurface, N) = sd->Ng; } diff --git a/tests/files/render/integrator/cycles_renders/light_path_is_reflection_ray.png b/tests/files/render/integrator/cycles_renders/light_path_is_reflection_ray.png index 2ccf345b2a9..5ef8873f240 100644 --- a/tests/files/render/integrator/cycles_renders/light_path_is_reflection_ray.png +++ b/tests/files/render/integrator/cycles_renders/light_path_is_reflection_ray.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cff274530e8f66995a672736da85899d4b272dcef757e0acbf20fa0e4394a935 -size 43478 +oid sha256:3f05ef3374278b49b0004f16e65da91f13c39fbd6abbbc326c5951b95e1b06d6 +size 43615 diff --git a/tests/files/render/light/all_light_types_in_volume.blend b/tests/files/render/light/all_light_types_in_volume.blend index 3d84732077f..fa2a4d8d4bd 100644 --- a/tests/files/render/light/all_light_types_in_volume.blend +++ b/tests/files/render/light/all_light_types_in_volume.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f4214fdd4eac6324b8d4f405b0c6eff436e28a05207da3790a2c7f60e9f27b9 -size 131402 +oid sha256:b1f61061daa62ec7105c8eb3392869c22b127cd53316b88956e30bdadfee92c0 +size 133089 diff --git a/tests/files/render/light/cycles_renders/all_light_types_in_volume.png b/tests/files/render/light/cycles_renders/all_light_types_in_volume.png index d26b85930a3..f2a283915d5 100644 --- a/tests/files/render/light/cycles_renders/all_light_types_in_volume.png +++ b/tests/files/render/light/cycles_renders/all_light_types_in_volume.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cc6efeeb061ba20fb911d3fcad9220f1a13d90ae3a71caca910c322a47b5f8d -size 39780 +oid sha256:445f015288694296d0b2eed47746d8a24b2e205be48d40a05b16308d71fda480 +size 39778 diff --git a/tests/files/render/principled_bsdf/cycles_renders/principled_bsdf_subsurface.png b/tests/files/render/principled_bsdf/cycles_renders/principled_bsdf_subsurface.png index 6bc8159b861..b0abcfb06ad 100644 --- a/tests/files/render/principled_bsdf/cycles_renders/principled_bsdf_subsurface.png +++ b/tests/files/render/principled_bsdf/cycles_renders/principled_bsdf_subsurface.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2859e4915c799bfffbaac02723ad0091ec437da454173503a2970502de412032 -size 31721 +oid sha256:ad15031ed1651e25ecec194459a2cf48af371e8815219a95e09ad6aba98e8f19 +size 33026 diff --git a/tests/files/render/reports/cycles_renders/sss_and_volume_39823.png b/tests/files/render/reports/cycles_renders/sss_and_volume_39823.png index 85858a48ec7..086b5ec7882 100644 --- a/tests/files/render/reports/cycles_renders/sss_and_volume_39823.png +++ b/tests/files/render/reports/cycles_renders/sss_and_volume_39823.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10680e6180b6151b2b97126a8370aa5b1f1f91fb8642a24a10cbb63065727a98 -size 28877 +oid sha256:512c436f8f544927f8bcb73a4b88ef065710ddca5d56cbeb81b4f1da7dfcd042 +size 28956 diff --git a/tests/files/render/sss/cycles_renders/sss_concave_clamp.png b/tests/files/render/sss/cycles_renders/sss_concave_clamp.png index 8222d717dc7..e99fed55843 100644 --- a/tests/files/render/sss/cycles_renders/sss_concave_clamp.png +++ b/tests/files/render/sss/cycles_renders/sss_concave_clamp.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d10e921cb78452be115f70131b4b7479d372b7ceff5fd76f40fb82d7c668dd43 -size 31049 +oid sha256:8956306820650dd24731ad37d8e3f65056bd8c90cb1cebc07196be31696d9239 +size 31331 diff --git a/tests/files/render/sss/cycles_renders/sss_diffuse_mix_clamp.png b/tests/files/render/sss/cycles_renders/sss_diffuse_mix_clamp.png index a562ea6a620..d813480bd57 100644 --- a/tests/files/render/sss/cycles_renders/sss_diffuse_mix_clamp.png +++ b/tests/files/render/sss/cycles_renders/sss_diffuse_mix_clamp.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7fe62c5e8f77ab81c17b5a96cdf978540eb9f28faa460a1b293a8d5b585bcd5 -size 27125 +oid sha256:75ce9a9b8e56ba2a8eac6a1c5e2dec52a13b513c8bf162e6b77c8781454e57e2 +size 27142 diff --git a/tests/files/render/sss/cycles_renders/subsurface_cubic.png b/tests/files/render/sss/cycles_renders/subsurface_cubic.png index 04c8b2e0bbf..14045cb52d7 100644 --- a/tests/files/render/sss/cycles_renders/subsurface_cubic.png +++ b/tests/files/render/sss/cycles_renders/subsurface_cubic.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:47e4415a3d940c72bb60eb3b91081b98c73000f777c372b7e42b468d14ad3a72 -size 31606 +oid sha256:517bc408dcbeed633b445f5c53d980a96ba49ed1ebcdd9f562d369a3a2ba9c39 +size 32359 diff --git a/tests/files/render/sss/cycles_renders/subsurface_gaussian.png b/tests/files/render/sss/cycles_renders/subsurface_gaussian.png index 9206bb181e0..c719d989a44 100644 --- a/tests/files/render/sss/cycles_renders/subsurface_gaussian.png +++ b/tests/files/render/sss/cycles_renders/subsurface_gaussian.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cfe5daeebfcba9a905b32704629db91301d5b8e68835a0d4f74950f2c233b21 -size 31609 +oid sha256:04dc60d6ff9868453e348f143750f3ecfc314d3ce7d297bcff34ad2c176d740b +size 32362 diff --git a/tests/files/render/sss/cycles_renders/subsurface_random_walk.png b/tests/files/render/sss/cycles_renders/subsurface_random_walk.png index 7e6b23d6df7..9e0cea19027 100644 --- a/tests/files/render/sss/cycles_renders/subsurface_random_walk.png +++ b/tests/files/render/sss/cycles_renders/subsurface_random_walk.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5604c9d65b94da9343e6e00daf3711b3a6ce9bf7845039fd9250ddfb7d8802f -size 31612 +oid sha256:7265d80410c4423e1071c130e1ccca660453c64d87f5f1bc9d193a7a3d9fd108 +size 32365 diff --git a/tests/files/render/sss/cycles_renders/subsurface_random_walk_thin.png b/tests/files/render/sss/cycles_renders/subsurface_random_walk_thin.png index c80249a9b66..02ba2f68849 100644 --- a/tests/files/render/sss/cycles_renders/subsurface_random_walk_thin.png +++ b/tests/files/render/sss/cycles_renders/subsurface_random_walk_thin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cc0e944f25eebdf608d19af18e39a642c8f2a36235dd7b13d8a5f3f3eafc13a -size 29953 +oid sha256:a67e373415ac46ad7a3971e5ee3ffd99a3446d8b1335d0a18f3913f28f033682 +size 30374