Fix T93106: Cycles SSS not working with normals pointing inside

This commit is contained in:
Brecht Van Lommel 2021-11-16 19:34:13 +01:00
parent 1572c4d3d3
commit 7293c1b357
Notes: blender-bot 2023-02-14 08:08:54 +01:00
Referenced by issue #93106, Cycles: Christensen-Burley subsurface scattering with inverted normals turns object black
3 changed files with 18 additions and 9 deletions

View File

@ -71,6 +71,10 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
}
# endif
if (sd->flag & SD_BACKFACING) {
path_flag |= PATH_RAY_SUBSURFACE_BACKFACING;
}
INTEGRATOR_STATE_WRITE(state, path, throughput) *= weight;
INTEGRATOR_STATE_WRITE(state, path, flag) = path_flag;

View File

@ -47,6 +47,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
const float time = INTEGRATOR_STATE(state, ray, time);
const float3 Ng = INTEGRATOR_STATE(state, subsurface, Ng);
const int object = INTEGRATOR_STATE(state, isect, object);
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
/* Read subsurface scattering parameters. */
const float3 radius = INTEGRATOR_STATE(state, subsurface, radius);
@ -123,6 +124,9 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
const int object = ss_isect.hits[hit].object;
const int object_flag = kernel_tex_fetch(__object_flag, object);
float3 hit_Ng = ss_isect.Ng[hit];
if (path_flag & PATH_RAY_SUBSURFACE_BACKFACING) {
hit_Ng = -hit_Ng;
}
if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
hit_Ng = -hit_Ng;
}

View File

@ -279,33 +279,34 @@ enum PathRayFlag {
PATH_RAY_SUBSURFACE_RANDOM_WALK = (1U << 20U),
PATH_RAY_SUBSURFACE_DISK = (1U << 21U),
PATH_RAY_SUBSURFACE_USE_FRESNEL = (1U << 22U),
PATH_RAY_SUBSURFACE_BACKFACING = (1U << 23U),
PATH_RAY_SUBSURFACE = (PATH_RAY_SUBSURFACE_RANDOM_WALK | PATH_RAY_SUBSURFACE_DISK |
PATH_RAY_SUBSURFACE_USE_FRESNEL),
PATH_RAY_SUBSURFACE_USE_FRESNEL | PATH_RAY_SUBSURFACE_BACKFACING),
/* Contribute to denoising features. */
PATH_RAY_DENOISING_FEATURES = (1U << 23U),
PATH_RAY_DENOISING_FEATURES = (1U << 24U),
/* Render pass categories. */
PATH_RAY_SURFACE_PASS = (1U << 24U),
PATH_RAY_VOLUME_PASS = (1U << 25U),
PATH_RAY_SURFACE_PASS = (1U << 25U),
PATH_RAY_VOLUME_PASS = (1U << 26U),
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 << 26U),
PATH_RAY_SHADOW_FOR_AO = (1U << 27U),
PATH_RAY_SHADOW_FOR_LIGHT = (1U << 27U),
PATH_RAY_SHADOW_FOR_AO = (1U << 28U),
/* A shadow catcher object was hit and the path was split into two. */
PATH_RAY_SHADOW_CATCHER_HIT = (1U << 28U),
PATH_RAY_SHADOW_CATCHER_HIT = (1U << 29U),
/* 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 << 29U),
PATH_RAY_SHADOW_CATCHER_PASS = (1U << 30U),
/* Path is evaluating background for an approximate shadow catcher with non-transparent film. */
PATH_RAY_SHADOW_CATCHER_BACKGROUND = (1U << 30U),
PATH_RAY_SHADOW_CATCHER_BACKGROUND = (1U << 31U),
};
/* Configure ray visibility bits for rays and objects respectively,