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
This commit is contained in:
Brecht Van Lommel
2025-06-19 20:04:49 +02:00
committed by Brecht Van Lommel
parent 8eb94f7c6f
commit 17bda2cf3f
13 changed files with 31 additions and 28 deletions

View File

@@ -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;
}

View File

@@ -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;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.