Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/integrator_subsurface.h
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | ccl_device int subsurface_bounce(INTEGRATOR_STATE_ARGS, ShaderData *sd, const ShaderClosure *sc) | ||||
| * be converted to a diffuse BSDF to avoid this. */ | * be converted to a diffuse BSDF to avoid this. */ | ||||
| kernel_assert(!(INTEGRATOR_STATE(path, flag) & PATH_RAY_DIFFUSE_ANCESTOR)); | kernel_assert(!(INTEGRATOR_STATE(path, flag) & PATH_RAY_DIFFUSE_ANCESTOR)); | ||||
| /* Setup path state for intersect_subsurface kernel. */ | /* Setup path state for intersect_subsurface kernel. */ | ||||
| const Bssrdf *bssrdf = (const Bssrdf *)sc; | const Bssrdf *bssrdf = (const Bssrdf *)sc; | ||||
| /* Setup ray into surface. */ | /* Setup ray into surface. */ | ||||
| INTEGRATOR_STATE_WRITE(ray, P) = sd->P; | INTEGRATOR_STATE_WRITE(ray, P) = sd->P; | ||||
| INTEGRATOR_STATE_WRITE(ray, D) = sd->N; | INTEGRATOR_STATE_WRITE(ray, D) = bssrdf->N; | ||||
| INTEGRATOR_STATE_WRITE(ray, t) = FLT_MAX; | INTEGRATOR_STATE_WRITE(ray, t) = FLT_MAX; | ||||
| INTEGRATOR_STATE_WRITE(ray, dP) = differential_make_compact(sd->dP); | INTEGRATOR_STATE_WRITE(ray, dP) = differential_make_compact(sd->dP); | ||||
| INTEGRATOR_STATE_WRITE(ray, dD) = differential_zero_compact(); | INTEGRATOR_STATE_WRITE(ray, dD) = differential_zero_compact(); | ||||
| /* Pass along object info, reusing isect to save memory. */ | /* Pass along object info, reusing isect to save memory. */ | ||||
| INTEGRATOR_STATE_WRITE(isect, Ng) = sd->Ng; | INTEGRATOR_STATE_WRITE(isect, Ng) = sd->Ng; | ||||
| INTEGRATOR_STATE_WRITE(isect, object) = sd->object; | INTEGRATOR_STATE_WRITE(isect, object) = sd->object; | ||||
| /* Pass BSSRDF parameters. */ | uint32_t path_flag = (INTEGRATOR_STATE(path, flag) & ~PATH_RAY_CAMERA) | | ||||
| const uint32_t path_flag = INTEGRATOR_STATE_WRITE(path, flag); | ((sc->type == CLOSURE_BSSRDF_BURLEY_ID) ? PATH_RAY_SUBSURFACE_DISK : | ||||
| INTEGRATOR_STATE_WRITE(path, flag) = (path_flag & ~PATH_RAY_CAMERA) | | |||||
| ((sc->type == CLOSURE_BSSRDF_BURLEY_ID) ? | |||||
| PATH_RAY_SUBSURFACE_DISK : | |||||
| PATH_RAY_SUBSURFACE_RANDOM_WALK); | PATH_RAY_SUBSURFACE_RANDOM_WALK); | ||||
| INTEGRATOR_STATE_WRITE(path, throughput) *= shader_bssrdf_sample_weight(sd, sc); | |||||
| /* Compute weight, optionally including Fresnel from entry point. */ | |||||
| float3 weight = shader_bssrdf_sample_weight(sd, sc); | |||||
| # ifdef __PRINCIPLED__ | |||||
| if (bssrdf->roughness != FLT_MAX) { | |||||
| path_flag |= PATH_RAY_SUBSURFACE_USE_FRESNEL; | |||||
| } | |||||
| # endif | |||||
| INTEGRATOR_STATE_WRITE(path, throughput) *= weight; | |||||
| INTEGRATOR_STATE_WRITE(path, flag) = path_flag; | |||||
| /* Advance random number offset for bounce. */ | /* Advance random number offset for bounce. */ | ||||
| INTEGRATOR_STATE_WRITE(path, rng_offset) += PRNG_BOUNCE_NUM; | INTEGRATOR_STATE_WRITE(path, rng_offset) += PRNG_BOUNCE_NUM; | ||||
| if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { | if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { | ||||
| if (INTEGRATOR_STATE(path, bounce) == 0) { | if (INTEGRATOR_STATE(path, bounce) == 0) { | ||||
| INTEGRATOR_STATE_WRITE(path, diffuse_glossy_ratio) = one_float3(); | INTEGRATOR_STATE_WRITE(path, diffuse_glossy_ratio) = one_float3(); | ||||
| } | } | ||||
| } | } | ||||
| /* Pass BSSRDF parameters. */ | |||||
| INTEGRATOR_STATE_WRITE(subsurface, albedo) = bssrdf->albedo; | INTEGRATOR_STATE_WRITE(subsurface, albedo) = bssrdf->albedo; | ||||
| INTEGRATOR_STATE_WRITE(subsurface, radius) = bssrdf->radius; | INTEGRATOR_STATE_WRITE(subsurface, radius) = bssrdf->radius; | ||||
| INTEGRATOR_STATE_WRITE(subsurface, roughness) = bssrdf->roughness; | |||||
| INTEGRATOR_STATE_WRITE(subsurface, anisotropy) = bssrdf->anisotropy; | INTEGRATOR_STATE_WRITE(subsurface, anisotropy) = bssrdf->anisotropy; | ||||
| return LABEL_SUBSURFACE_SCATTER; | return LABEL_SUBSURFACE_SCATTER; | ||||
| } | } | ||||
| ccl_device void subsurface_shader_data_setup(INTEGRATOR_STATE_ARGS, ShaderData *sd) | ccl_device void subsurface_shader_data_setup(INTEGRATOR_STATE_ARGS, | ||||
| ShaderData *sd, | |||||
| const uint32_t path_flag) | |||||
| { | { | ||||
| /* Get bump mapped normal from shader evaluation at exit point. */ | /* Get bump mapped normal from shader evaluation at exit point. */ | ||||
| float3 N = sd->N; | float3 N = sd->N; | ||||
| if (sd->flag & SD_HAS_BSSRDF_BUMP) { | if (sd->flag & SD_HAS_BSSRDF_BUMP) { | ||||
| N = shader_bssrdf_normal(sd); | N = shader_bssrdf_normal(sd); | ||||
| } | } | ||||
| /* Setup diffuse BSDF at the exit point. This replaces shader_eval_surface. */ | /* Setup diffuse BSDF at the exit point. This replaces shader_eval_surface. */ | ||||
| sd->flag &= ~SD_CLOSURE_FLAGS; | sd->flag &= ~SD_CLOSURE_FLAGS; | ||||
| sd->num_closure = 0; | sd->num_closure = 0; | ||||
| sd->num_closure_left = kernel_data.max_closures; | sd->num_closure_left = kernel_data.max_closures; | ||||
| const float3 weight = one_float3(); | const float3 weight = one_float3(); | ||||
| const float roughness = INTEGRATOR_STATE(subsurface, roughness); | |||||
| # ifdef __PRINCIPLED__ | # ifdef __PRINCIPLED__ | ||||
| if (roughness != FLT_MAX) { | if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) { | ||||
| PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | ||||
| sd, sizeof(PrincipledDiffuseBsdf), weight); | sd, sizeof(PrincipledDiffuseBsdf), weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->roughness = roughness; | bsdf->roughness = FLT_MAX; | ||||
| sd->flag |= bsdf_principled_diffuse_setup(bsdf); | sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT_EXIT); | ||||
| /* replace CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID with this special ID so render passes | |||||
| * can recognize it as not being a regular Disney principled diffuse closure */ | |||||
| bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID; | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| # endif /* __PRINCIPLED__ */ | # endif /* __PRINCIPLED__ */ | ||||
| { | { | ||||
| DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight); | DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| sd->flag |= bsdf_diffuse_setup(bsdf); | sd->flag |= bsdf_diffuse_setup(bsdf); | ||||
| /* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes | |||||
| * can recognize it as not being a regular diffuse closure */ | |||||
| bsdf->type = CLOSURE_BSDF_BSSRDF_ID; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ccl_device_inline bool subsurface_scatter(INTEGRATOR_STATE_ARGS) | ccl_device_inline bool subsurface_scatter(INTEGRATOR_STATE_ARGS) | ||||
| { | { | ||||
| RNGState rng_state; | RNGState rng_state; | ||||
| path_state_rng_load(INTEGRATOR_STATE_PASS, &rng_state); | path_state_rng_load(INTEGRATOR_STATE_PASS, &rng_state); | ||||
| ▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines | |||||