Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/closure/bssrdf.h
| Show First 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight) | ||||
| float sample_weight = fabsf(average(weight)); | float sample_weight = fabsf(average(weight)); | ||||
| bssrdf->sample_weight = sample_weight; | bssrdf->sample_weight = sample_weight; | ||||
| return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL; | return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL; | ||||
| } | } | ||||
| ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type, const float ior) | ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type, const float ior) | ||||
| { | { | ||||
| int flag = 0; | int flag = 0; | ||||
| /* Add retro-reflection component as separate diffuse BSDF. */ | |||||
| if (bssrdf->roughness != FLT_MAX) { | |||||
| PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | |||||
| sd, sizeof(PrincipledDiffuseBsdf), bssrdf->weight); | |||||
| if (bsdf) { | |||||
| bsdf->N = bssrdf->N; | |||||
| bsdf->roughness = bssrdf->roughness; | |||||
| flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_RETRO_REFLECTION); | |||||
| /* Ad-hoc weight adjusment to avoid retro-reflection taking away half the | |||||
| * samples from BSSRDF. */ | |||||
| bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->I); | |||||
| } | |||||
| } | |||||
| /* Verify if the radii are large enough to sample without precision issues. */ | |||||
| int bssrdf_channels = 3; | int bssrdf_channels = 3; | ||||
| float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f); | float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f); | ||||
| /* Verify if the radii are large enough to sample without precision issues. */ | |||||
| if (bssrdf->radius.x < BSSRDF_MIN_RADIUS) { | if (bssrdf->radius.x < BSSRDF_MIN_RADIUS) { | ||||
| diffuse_weight.x = bssrdf->weight.x; | diffuse_weight.x = bssrdf->weight.x; | ||||
| bssrdf->weight.x = 0.0f; | bssrdf->weight.x = 0.0f; | ||||
| bssrdf->radius.x = 0.0f; | bssrdf->radius.x = 0.0f; | ||||
| bssrdf_channels--; | bssrdf_channels--; | ||||
| } | } | ||||
| if (bssrdf->radius.y < BSSRDF_MIN_RADIUS) { | if (bssrdf->radius.y < BSSRDF_MIN_RADIUS) { | ||||
| diffuse_weight.y = bssrdf->weight.y; | diffuse_weight.y = bssrdf->weight.y; | ||||
| bssrdf->weight.y = 0.0f; | bssrdf->weight.y = 0.0f; | ||||
| bssrdf->radius.y = 0.0f; | bssrdf->radius.y = 0.0f; | ||||
| bssrdf_channels--; | bssrdf_channels--; | ||||
| } | } | ||||
| if (bssrdf->radius.z < BSSRDF_MIN_RADIUS) { | if (bssrdf->radius.z < BSSRDF_MIN_RADIUS) { | ||||
| diffuse_weight.z = bssrdf->weight.z; | diffuse_weight.z = bssrdf->weight.z; | ||||
| bssrdf->weight.z = 0.0f; | bssrdf->weight.z = 0.0f; | ||||
| bssrdf->radius.z = 0.0f; | bssrdf->radius.z = 0.0f; | ||||
| bssrdf_channels--; | bssrdf_channels--; | ||||
| } | } | ||||
| if (bssrdf_channels < 3) { | if (bssrdf_channels < 3) { | ||||
| /* Add diffuse BSDF if any radius too small. */ | /* Add diffuse BSDF if any radius too small. */ | ||||
| #ifdef __PRINCIPLED__ | #ifdef __PRINCIPLED__ | ||||
| if (bssrdf->roughness != FLT_MAX) { | if (bssrdf->roughness != FLT_MAX) { | ||||
| float roughness = bssrdf->roughness; | |||||
| float3 N = bssrdf->N; | |||||
| PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | ||||
| sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight); | sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID; | bsdf->N = bssrdf->N; | ||||
| bsdf->N = N; | bsdf->roughness = bssrdf->roughness; | ||||
| bsdf->roughness = roughness; | flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_LAMBERT); | ||||
| flag |= bsdf_principled_diffuse_setup(bsdf); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| #endif /* __PRINCIPLED__ */ | #endif /* __PRINCIPLED__ */ | ||||
| { | { | ||||
| DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), diffuse_weight); | DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), diffuse_weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->type = CLOSURE_BSDF_BSSRDF_ID; | |||||
| bsdf->N = bssrdf->N; | bsdf->N = bssrdf->N; | ||||
| flag |= bsdf_diffuse_setup(bsdf); | flag |= bsdf_diffuse_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Setup BSSRDF if radius is large enough. */ | /* Setup BSSRDF if radius is large enough. */ | ||||
| if (bssrdf_channels > 0) { | if (bssrdf_channels > 0) { | ||||
| Show All 16 Lines | |||||