Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/svm/svm_closure.h
| Show All 12 Lines | |||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| /* Closure Nodes */ | /* Closure Nodes */ | ||||
| ccl_device void svm_node_glass_setup( | ccl_device void svm_node_glass_setup(ccl_private ShaderData *sd, | ||||
| ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract) | ccl_private MicrofacetBsdf *bsdf, | ||||
| int type, | |||||
| float eta, | |||||
| float roughness, | |||||
| bool refract) | |||||
| { | { | ||||
| if (type == CLOSURE_BSDF_SHARP_GLASS_ID) { | if (type == CLOSURE_BSDF_SHARP_GLASS_ID) { | ||||
| if (refract) { | if (refract) { | ||||
| bsdf->alpha_y = 0.0f; | bsdf->alpha_y = 0.0f; | ||||
| bsdf->alpha_x = 0.0f; | bsdf->alpha_x = 0.0f; | ||||
| bsdf->ior = eta; | bsdf->ior = eta; | ||||
| sd->flag |= bsdf_refraction_setup(bsdf); | sd->flag |= bsdf_refraction_setup(bsdf); | ||||
| } | } | ||||
| Show All 22 Lines | else { | ||||
| if (refract) | if (refract) | ||||
| sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); | sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); | ||||
| else | else | ||||
| sd->flag |= bsdf_microfacet_ggx_setup(bsdf); | sd->flag |= bsdf_microfacet_ggx_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| template<uint node_feature_mask, ShaderType shader_type> | template<uint node_feature_mask, ShaderType shader_type> | ||||
| ccl_device_noinline int svm_node_closure_bsdf( | ccl_device_noinline int svm_node_closure_bsdf(ccl_global const KernelGlobals *kg, | ||||
| const KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int offset) | ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node, | |||||
| int path_flag, | |||||
| int offset) | |||||
| { | { | ||||
| uint type, param1_offset, param2_offset; | uint type, param1_offset, param2_offset; | ||||
| uint mix_weight_offset; | uint mix_weight_offset; | ||||
| svm_unpack_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | svm_unpack_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | ||||
| float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) : | float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) : | ||||
| 1.0f); | 1.0f); | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | # ifdef __SUBSURFACE__ | ||||
| base_color = mixed_ss_base_color; | base_color = mixed_ss_base_color; | ||||
| } | } | ||||
| /* diffuse */ | /* diffuse */ | ||||
| if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { | if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { | ||||
| if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { | if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 diff_weight = weight * base_color * diffuse_weight; | float3 diff_weight = weight * base_color * diffuse_weight; | ||||
| PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *) | ||||
| sd, sizeof(PrincipledDiffuseBsdf), diff_weight); | bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->roughness = roughness; | bsdf->roughness = roughness; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL); | sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL); | ||||
| } | } | ||||
| } | } | ||||
| else if (subsurface > CLOSURE_WEIGHT_CUTOFF) { | else if (subsurface > CLOSURE_WEIGHT_CUTOFF) { | ||||
| Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); | ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); | ||||
| if (bssrdf) { | if (bssrdf) { | ||||
| bssrdf->radius = subsurface_radius * subsurface; | bssrdf->radius = subsurface_radius * subsurface; | ||||
| bssrdf->albedo = mixed_ss_base_color; | bssrdf->albedo = mixed_ss_base_color; | ||||
| bssrdf->N = N; | bssrdf->N = N; | ||||
| bssrdf->roughness = roughness; | bssrdf->roughness = roughness; | ||||
| /* Clamps protecting against bad/extreme and non physical values. */ | /* Clamps protecting against bad/extreme and non physical values. */ | ||||
| subsurface_ior = clamp(subsurface_ior, 1.01f, 3.8f); | subsurface_ior = clamp(subsurface_ior, 1.01f, 3.8f); | ||||
| bssrdf->anisotropy = clamp(subsurface_anisotropy, 0.0f, 0.9f); | bssrdf->anisotropy = clamp(subsurface_anisotropy, 0.0f, 0.9f); | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method, subsurface_ior); | sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method, subsurface_ior); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| # else | # else | ||||
| /* diffuse */ | /* diffuse */ | ||||
| if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { | if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 diff_weight = weight * base_color * diffuse_weight; | float3 diff_weight = weight * base_color * diffuse_weight; | ||||
| PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( | ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc( | ||||
| sd, sizeof(PrincipledDiffuseBsdf), diff_weight); | sd, sizeof(PrincipledDiffuseBsdf), diff_weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->roughness = roughness; | bsdf->roughness = roughness; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL); | sd->flag |= bsdf_principled_diffuse_setup(bsdf, PRINCIPLED_DIFFUSE_FULL); | ||||
| Show All 9 Lines | # endif | ||||
| make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat | make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat | ||||
| /* color of the sheen component */ | /* color of the sheen component */ | ||||
| float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + | float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + | ||||
| m_ctint * sheen_tint; | m_ctint * sheen_tint; | ||||
| float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight; | float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight; | ||||
| PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc( | ccl_private PrincipledSheenBsdf *bsdf = (ccl_private PrincipledSheenBsdf *)bsdf_alloc( | ||||
| sd, sizeof(PrincipledSheenBsdf), sheen_weight); | sd, sizeof(PrincipledSheenBsdf), sheen_weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_principled_sheen_setup(sd, bsdf); | sd->flag |= bsdf_principled_sheen_setup(sd, bsdf); | ||||
| } | } | ||||
| } | } | ||||
| /* specular reflection */ | /* specular reflection */ | ||||
| # ifdef __CAUSTICS_TRICKS__ | # ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { | if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { | ||||
| # endif | # endif | ||||
| if (specular_weight > CLOSURE_WEIGHT_CUTOFF && | if (specular_weight > CLOSURE_WEIGHT_CUTOFF && | ||||
| (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { | (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { | ||||
| float3 spec_weight = weight * specular_weight; | float3 spec_weight = weight * specular_weight; | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), spec_weight); | sd, sizeof(MicrofacetBsdf), spec_weight); | ||||
| MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( | ccl_private MicrofacetExtra *extra = | ||||
| sd, sizeof(MicrofacetExtra)) : | (bsdf != NULL) ? | ||||
| (ccl_private MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) : | |||||
| NULL; | NULL; | ||||
| if (bsdf && extra) { | if (bsdf && extra) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f; | bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f; | ||||
| bsdf->T = T; | bsdf->T = T; | ||||
| bsdf->extra = extra; | bsdf->extra = extra; | ||||
| float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f); | float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f); | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | # endif | ||||
| distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */ | distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */ | ||||
| float refl_roughness = roughness; | float refl_roughness = roughness; | ||||
| /* reflection */ | /* reflection */ | ||||
| # ifdef __CAUSTICS_TRICKS__ | # ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | ||||
| # endif | # endif | ||||
| { | { | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), glass_weight * fresnel); | sd, sizeof(MicrofacetBsdf), glass_weight * fresnel); | ||||
| MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( | ccl_private MicrofacetExtra *extra = | ||||
| (bsdf != NULL) ? (ccl_private MicrofacetExtra *)closure_alloc_extra( | |||||
| sd, sizeof(MicrofacetExtra)) : | sd, sizeof(MicrofacetExtra)) : | ||||
| NULL; | NULL; | ||||
| if (bsdf && extra) { | if (bsdf && extra) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra = extra; | bsdf->extra = extra; | ||||
| bsdf->alpha_x = refl_roughness * refl_roughness; | bsdf->alpha_x = refl_roughness * refl_roughness; | ||||
| bsdf->alpha_y = refl_roughness * refl_roughness; | bsdf->alpha_y = refl_roughness * refl_roughness; | ||||
| bsdf->ior = ior; | bsdf->ior = ior; | ||||
| bsdf->extra->color = base_color; | bsdf->extra->color = base_color; | ||||
| bsdf->extra->cspec0 = cspec0; | bsdf->extra->cspec0 = cspec0; | ||||
| bsdf->extra->clearcoat = 0.0f; | bsdf->extra->clearcoat = 0.0f; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); | sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); | ||||
| } | } | ||||
| } | } | ||||
| /* refraction */ | /* refraction */ | ||||
| # ifdef __CAUSTICS_TRICKS__ | # ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) | if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) | ||||
| # endif | # endif | ||||
| { | { | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), base_color * glass_weight * (1.0f - fresnel)); | sd, sizeof(MicrofacetBsdf), base_color * glass_weight * (1.0f - fresnel)); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra = NULL; | bsdf->extra = NULL; | ||||
| if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) | if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) | ||||
| transmission_roughness = 1.0f - (1.0f - refl_roughness) * | transmission_roughness = 1.0f - (1.0f - refl_roughness) * | ||||
| (1.0f - transmission_roughness); | (1.0f - transmission_roughness); | ||||
| else | else | ||||
| transmission_roughness = refl_roughness; | transmission_roughness = refl_roughness; | ||||
| bsdf->alpha_x = transmission_roughness * transmission_roughness; | bsdf->alpha_x = transmission_roughness * transmission_roughness; | ||||
| bsdf->alpha_y = transmission_roughness * transmission_roughness; | bsdf->alpha_y = transmission_roughness * transmission_roughness; | ||||
| bsdf->ior = ior; | bsdf->ior = ior; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); | sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { /* use multi-scatter GGX */ | else { /* use multi-scatter GGX */ | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), glass_weight); | sd, sizeof(MicrofacetBsdf), glass_weight); | ||||
| MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( | ccl_private MicrofacetExtra *extra = | ||||
| (bsdf != NULL) ? (ccl_private MicrofacetExtra *)closure_alloc_extra( | |||||
| sd, sizeof(MicrofacetExtra)) : | sd, sizeof(MicrofacetExtra)) : | ||||
| NULL; | NULL; | ||||
| if (bsdf && extra) { | if (bsdf && extra) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->extra = extra; | bsdf->extra = extra; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->alpha_x = roughness * roughness; | bsdf->alpha_x = roughness * roughness; | ||||
| bsdf->alpha_y = roughness * roughness; | bsdf->alpha_y = roughness * roughness; | ||||
| Show All 12 Lines | # ifdef __CAUSTICS_TRICKS__ | ||||
| } | } | ||||
| # endif | # endif | ||||
| /* clearcoat */ | /* clearcoat */ | ||||
| # ifdef __CAUSTICS_TRICKS__ | # ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { | if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { | ||||
| # endif | # endif | ||||
| if (clearcoat > CLOSURE_WEIGHT_CUTOFF) { | if (clearcoat > CLOSURE_WEIGHT_CUTOFF) { | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( | sd, sizeof(MicrofacetBsdf), weight); | ||||
| sd, sizeof(MicrofacetExtra)) : | ccl_private MicrofacetExtra *extra = | ||||
| (bsdf != NULL) ? | |||||
| (ccl_private MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) : | |||||
| NULL; | NULL; | ||||
| if (bsdf && extra) { | if (bsdf && extra) { | ||||
| bsdf->N = clearcoat_normal; | bsdf->N = clearcoat_normal; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->ior = 1.5f; | bsdf->ior = 1.5f; | ||||
| bsdf->extra = extra; | bsdf->extra = extra; | ||||
| bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; | bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; | ||||
| Show All 11 Lines | # ifdef __CAUSTICS_TRICKS__ | ||||
| } | } | ||||
| # endif | # endif | ||||
| break; | break; | ||||
| } | } | ||||
| #endif /* __PRINCIPLED__ */ | #endif /* __PRINCIPLED__ */ | ||||
| case CLOSURE_BSDF_DIFFUSE_ID: { | case CLOSURE_BSDF_DIFFUSE_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| OrenNayarBsdf *bsdf = (OrenNayarBsdf *)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight); | ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc( | ||||
| sd, sizeof(OrenNayarBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| float roughness = param1; | float roughness = param1; | ||||
| if (roughness == 0.0f) { | if (roughness == 0.0f) { | ||||
| sd->flag |= bsdf_diffuse_setup((DiffuseBsdf *)bsdf); | sd->flag |= bsdf_diffuse_setup((ccl_private DiffuseBsdf *)bsdf); | ||||
| } | } | ||||
| else { | else { | ||||
| bsdf->roughness = roughness; | bsdf->roughness = roughness; | ||||
| sd->flag |= bsdf_oren_nayar_setup(bsdf); | sd->flag |= bsdf_oren_nayar_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_TRANSLUCENT_ID: { | case CLOSURE_BSDF_TRANSLUCENT_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight); | ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( | ||||
| sd, sizeof(DiffuseBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| sd->flag |= bsdf_translucent_setup(bsdf); | sd->flag |= bsdf_translucent_setup(bsdf); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_TRANSPARENT_ID: { | case CLOSURE_BSDF_TRANSPARENT_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| bsdf_transparent_setup(sd, weight, path_flag); | bsdf_transparent_setup(sd, weight, path_flag); | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_REFLECTION_ID: | case CLOSURE_BSDF_REFLECTION_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_GGX_ID: | case CLOSURE_BSDF_MICROFACET_GGX_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: | case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: | ||||
| case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: | case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: { | case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: { | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), weight); | |||||
| if (!bsdf) { | if (!bsdf) { | ||||
| break; | break; | ||||
| } | } | ||||
| float roughness = sqr(param1); | float roughness = sqr(param1); | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| Show All 29 Lines | #endif | ||||
| if (type == CLOSURE_BSDF_REFLECTION_ID) | if (type == CLOSURE_BSDF_REFLECTION_ID) | ||||
| sd->flag |= bsdf_reflection_setup(bsdf); | sd->flag |= bsdf_reflection_setup(bsdf); | ||||
| else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) | else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) | ||||
| sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); | sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); | ||||
| else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID) | else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID) | ||||
| sd->flag |= bsdf_microfacet_ggx_setup(bsdf); | sd->flag |= bsdf_microfacet_ggx_setup(bsdf); | ||||
| else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { | else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { | ||||
| kernel_assert(stack_valid(data_node.w)); | kernel_assert(stack_valid(data_node.w)); | ||||
| bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); | bsdf->extra = (ccl_private MicrofacetExtra *)closure_alloc_extra(sd, | ||||
| sizeof(MicrofacetExtra)); | |||||
| if (bsdf->extra) { | if (bsdf->extra) { | ||||
| bsdf->extra->color = stack_load_float3(stack, data_node.w); | bsdf->extra->color = stack_load_float3(stack, data_node.w); | ||||
| bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); | bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra->clearcoat = 0.0f; | bsdf->extra->clearcoat = 0.0f; | ||||
| sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); | sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); | sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_REFRACTION_ID: | case CLOSURE_BSDF_REFRACTION_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: | case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { | case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra = NULL; | bsdf->extra = NULL; | ||||
| float eta = fmaxf(param2, 1e-5f); | float eta = fmaxf(param2, 1e-5f); | ||||
| eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; | eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | #endif | ||||
| float fresnel = fresnel_dielectric_cos(cosNO, eta); | float fresnel = fresnel_dielectric_cos(cosNO, eta); | ||||
| float roughness = sqr(param1); | float roughness = sqr(param1); | ||||
| /* reflection */ | /* reflection */ | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | ||||
| #endif | #endif | ||||
| { | { | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), weight * fresnel); | sd, sizeof(MicrofacetBsdf), weight * fresnel); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra = NULL; | bsdf->extra = NULL; | ||||
| svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); | svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); | ||||
| } | } | ||||
| } | } | ||||
| /* refraction */ | /* refraction */ | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) | if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) | ||||
| #endif | #endif | ||||
| { | { | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), weight * (1.0f - fresnel)); | sd, sizeof(MicrofacetBsdf), weight * (1.0f - fresnel)); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| bsdf->extra = NULL; | bsdf->extra = NULL; | ||||
| svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); | svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { | case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (!kernel_data.integrator.caustics_reflective && | if (!kernel_data.integrator.caustics_reflective && | ||||
| !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); | ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(MicrofacetBsdf), weight); | |||||
| if (!bsdf) { | if (!bsdf) { | ||||
| break; | break; | ||||
| } | } | ||||
| MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); | ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( | ||||
| sd, sizeof(MicrofacetExtra)); | |||||
| if (!extra) { | if (!extra) { | ||||
| break; | break; | ||||
| } | } | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->extra = extra; | bsdf->extra = extra; | ||||
| bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | bsdf->T = make_float3(0.0f, 0.0f, 0.0f); | ||||
| Show All 9 Lines | #endif | ||||
| bsdf->extra->clearcoat = 0.0f; | bsdf->extra->clearcoat = 0.0f; | ||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); | sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { | case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight); | ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc( | ||||
| sd, sizeof(VelvetBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->sigma = saturate(param1); | bsdf->sigma = saturate(param1); | ||||
| sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); | sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_GLOSSY_TOON_ID: | case CLOSURE_BSDF_GLOSSY_TOON_ID: | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| #endif | #endif | ||||
| case CLOSURE_BSDF_DIFFUSE_TOON_ID: { | case CLOSURE_BSDF_DIFFUSE_TOON_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| ToonBsdf *bsdf = (ToonBsdf *)bsdf_alloc(sd, sizeof(ToonBsdf), weight); | ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( | ||||
| sd, sizeof(ToonBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->size = param1; | bsdf->size = param1; | ||||
| bsdf->smooth = param2; | bsdf->smooth = param2; | ||||
| if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID) | if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID) | ||||
| sd->flag |= bsdf_diffuse_toon_setup(bsdf); | sd->flag |= bsdf_diffuse_toon_setup(bsdf); | ||||
| Show All 30 Lines | case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { | ||||
| float random = 0.0f; | float random = 0.0f; | ||||
| if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) { | if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) { | ||||
| random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL); | random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL); | ||||
| } | } | ||||
| else { | else { | ||||
| random = stack_load_float_default(stack, random_ofs, data_node3.y); | random = stack_load_float_default(stack, random_ofs, data_node3.y); | ||||
| } | } | ||||
| PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc( | ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)bsdf_alloc( | ||||
| sd, sizeof(PrincipledHairBSDF), weight); | sd, sizeof(PrincipledHairBSDF), weight); | ||||
| if (bsdf) { | if (bsdf) { | ||||
| PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra( | ccl_private PrincipledHairExtra *extra = (ccl_private PrincipledHairExtra *) | ||||
| sd, sizeof(PrincipledHairExtra)); | closure_alloc_extra(sd, sizeof(PrincipledHairExtra)); | ||||
| if (!extra) | if (!extra) | ||||
| break; | break; | ||||
| /* Random factors range: [-randomization/2, +randomization/2]. */ | /* Random factors range: [-randomization/2, +randomization/2]. */ | ||||
| float random_roughness = stack_load_float_default( | float random_roughness = stack_load_float_default( | ||||
| stack, random_roughness_ofs, data_node3.w); | stack, random_roughness_ofs, data_node3.w); | ||||
| float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness; | float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness; | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { | ||||
| sd->flag |= bsdf_principled_hair_setup(sd, bsdf); | sd->flag |= bsdf_principled_hair_setup(sd, bsdf); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_HAIR_REFLECTION_ID: | case CLOSURE_BSDF_HAIR_REFLECTION_ID: | ||||
| case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { | case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| HairBsdf *bsdf = (HairBsdf *)bsdf_alloc(sd, sizeof(HairBsdf), weight); | ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( | ||||
| sd, sizeof(HairBsdf), weight); | |||||
| if (bsdf) { | if (bsdf) { | ||||
| bsdf->N = N; | bsdf->N = N; | ||||
| bsdf->roughness1 = param1; | bsdf->roughness1 = param1; | ||||
| bsdf->roughness2 = param2; | bsdf->roughness2 = param2; | ||||
| bsdf->offset = -stack_load_float(stack, data_node.z); | bsdf->offset = -stack_load_float(stack, data_node.z); | ||||
| if (stack_valid(data_node.y)) { | if (stack_valid(data_node.y)) { | ||||
| Show All 18 Lines | #ifdef __HAIR__ | ||||
| } | } | ||||
| #endif /* __HAIR__ */ | #endif /* __HAIR__ */ | ||||
| #ifdef __SUBSURFACE__ | #ifdef __SUBSURFACE__ | ||||
| case CLOSURE_BSSRDF_BURLEY_ID: | case CLOSURE_BSSRDF_BURLEY_ID: | ||||
| case CLOSURE_BSSRDF_RANDOM_WALK_ID: | case CLOSURE_BSSRDF_RANDOM_WALK_ID: | ||||
| case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: { | case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: { | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| Bssrdf *bssrdf = bssrdf_alloc(sd, weight); | ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight); | ||||
| if (bssrdf) { | if (bssrdf) { | ||||
| /* disable in case of diffuse ancestor, can't see it well then and | /* disable in case of diffuse ancestor, can't see it well then and | ||||
| * adds considerably noise due to probabilities of continuing path | * adds considerably noise due to probabilities of continuing path | ||||
| * getting lower and lower */ | * getting lower and lower */ | ||||
| if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) | if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) | ||||
| param1 = 0.0f; | param1 = 0.0f; | ||||
| Show All 15 Lines | #endif | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| return offset; | return offset; | ||||
| } | } | ||||
| template<ShaderType shader_type> | template<ShaderType shader_type> | ||||
| ccl_device_noinline void svm_node_closure_volume(const KernelGlobals *kg, | ccl_device_noinline void svm_node_closure_volume(ccl_global const KernelGlobals *kg, | ||||
| ShaderData *sd, | ccl_private ShaderData *sd, | ||||
| float *stack, | ccl_private float *stack, | ||||
| uint4 node) | uint4 node) | ||||
| { | { | ||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| /* Only sum extinction for volumes, variable is shared with surface transparency. */ | /* Only sum extinction for volumes, variable is shared with surface transparency. */ | ||||
| if (shader_type != SHADER_TYPE_VOLUME) { | if (shader_type != SHADER_TYPE_VOLUME) { | ||||
| return; | return; | ||||
| } | } | ||||
| Show All 18 Lines | #ifdef __VOLUME__ | ||||
| if (type == CLOSURE_VOLUME_ABSORPTION_ID) { | if (type == CLOSURE_VOLUME_ABSORPTION_ID) { | ||||
| weight = make_float3(1.0f, 1.0f, 1.0f) - weight; | weight = make_float3(1.0f, 1.0f, 1.0f) - weight; | ||||
| } | } | ||||
| weight *= density; | weight *= density; | ||||
| /* Add closure for volume scattering. */ | /* Add closure for volume scattering. */ | ||||
| if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) { | if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) { | ||||
| HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc( | ccl_private HenyeyGreensteinVolume *volume = (ccl_private HenyeyGreensteinVolume *)bsdf_alloc( | ||||
| sd, sizeof(HenyeyGreensteinVolume), weight); | sd, sizeof(HenyeyGreensteinVolume), weight); | ||||
| if (volume) { | if (volume) { | ||||
| float anisotropy = (stack_valid(anisotropy_offset)) ? | float anisotropy = (stack_valid(anisotropy_offset)) ? | ||||
| stack_load_float(stack, anisotropy_offset) : | stack_load_float(stack, anisotropy_offset) : | ||||
| __uint_as_float(node.w); | __uint_as_float(node.w); | ||||
| volume->g = anisotropy; /* g */ | volume->g = anisotropy; /* g */ | ||||
| sd->flag |= volume_henyey_greenstein_setup(volume); | sd->flag |= volume_henyey_greenstein_setup(volume); | ||||
| } | } | ||||
| } | } | ||||
| /* Sum total extinction weight. */ | /* Sum total extinction weight. */ | ||||
| volume_extinction_setup(sd, weight); | volume_extinction_setup(sd, weight); | ||||
| #endif | #endif | ||||
| } | } | ||||
| template<ShaderType shader_type> | template<ShaderType shader_type> | ||||
| ccl_device_noinline int svm_node_principled_volume( | ccl_device_noinline int svm_node_principled_volume(ccl_global const KernelGlobals *kg, | ||||
| const KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int offset) | ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node, | |||||
| int path_flag, | |||||
| int offset) | |||||
| { | { | ||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| uint4 value_node = read_node(kg, &offset); | uint4 value_node = read_node(kg, &offset); | ||||
| uint4 attr_node = read_node(kg, &offset); | uint4 attr_node = read_node(kg, &offset); | ||||
| /* Only sum extinction for volumes, variable is shared with surface transparency. */ | /* Only sum extinction for volumes, variable is shared with surface transparency. */ | ||||
| if (shader_type != SHADER_TYPE_VOLUME) { | if (shader_type != SHADER_TYPE_VOLUME) { | ||||
| return offset; | return offset; | ||||
| Show All 29 Lines | if (density > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 color = sd->svm_closure_weight; | float3 color = sd->svm_closure_weight; | ||||
| const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y); | const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y); | ||||
| if (attr_color.offset != ATTR_STD_NOT_FOUND) { | if (attr_color.offset != ATTR_STD_NOT_FOUND) { | ||||
| color *= primitive_volume_attribute_float3(kg, sd, attr_color); | color *= primitive_volume_attribute_float3(kg, sd, attr_color); | ||||
| } | } | ||||
| /* Add closure for volume scattering. */ | /* Add closure for volume scattering. */ | ||||
| HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc( | ccl_private HenyeyGreensteinVolume *volume = (ccl_private HenyeyGreensteinVolume *)bsdf_alloc( | ||||
| sd, sizeof(HenyeyGreensteinVolume), color * density); | sd, sizeof(HenyeyGreensteinVolume), color * density); | ||||
| if (volume) { | if (volume) { | ||||
| float anisotropy = (stack_valid(anisotropy_offset)) ? | float anisotropy = (stack_valid(anisotropy_offset)) ? | ||||
| stack_load_float(stack, anisotropy_offset) : | stack_load_float(stack, anisotropy_offset) : | ||||
| __uint_as_float(value_node.y); | __uint_as_float(value_node.y); | ||||
| volume->g = anisotropy; | volume->g = anisotropy; | ||||
| sd->flag |= volume_henyey_greenstein_setup(volume); | sd->flag |= volume_henyey_greenstein_setup(volume); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (intensity > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T); | float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T); | ||||
| emission_setup(sd, bb); | emission_setup(sd, bb); | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| return offset; | return offset; | ||||
| } | } | ||||
| ccl_device_noinline void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node) | |||||
| { | { | ||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float3 weight = sd->svm_closure_weight; | float3 weight = sd->svm_closure_weight; | ||||
| if (stack_valid(mix_weight_offset)) { | if (stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if (mix_weight == 0.0f) | if (mix_weight == 0.0f) | ||||
| return; | return; | ||||
| weight *= mix_weight; | weight *= mix_weight; | ||||
| } | } | ||||
| emission_setup(sd, weight); | emission_setup(sd, weight); | ||||
| } | } | ||||
| ccl_device_noinline void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node) | |||||
| { | { | ||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float3 weight = sd->svm_closure_weight; | float3 weight = sd->svm_closure_weight; | ||||
| if (stack_valid(mix_weight_offset)) { | if (stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if (mix_weight == 0.0f) | if (mix_weight == 0.0f) | ||||
| return; | return; | ||||
| weight *= mix_weight; | weight *= mix_weight; | ||||
| } | } | ||||
| background_setup(sd, weight); | background_setup(sd, weight); | ||||
| } | } | ||||
| ccl_device_noinline void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node) | |||||
| { | { | ||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| if (stack_valid(mix_weight_offset)) { | if (stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if (mix_weight == 0.0f) | if (mix_weight == 0.0f) | ||||
| return; | return; | ||||
| closure_alloc( | closure_alloc( | ||||
| sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight); | sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight); | ||||
| } | } | ||||
| else | else | ||||
| closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight); | closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight); | ||||
| sd->flag |= SD_HOLDOUT; | sd->flag |= SD_HOLDOUT; | ||||
| } | } | ||||
| /* Closure Nodes */ | /* Closure Nodes */ | ||||
| ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight) | ccl_device_inline void svm_node_closure_store_weight(ccl_private ShaderData *sd, float3 weight) | ||||
| { | { | ||||
| sd->svm_closure_weight = weight; | sd->svm_closure_weight = weight; | ||||
| } | } | ||||
| ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b) | ccl_device void svm_node_closure_set_weight(ccl_private ShaderData *sd, uint r, uint g, uint b) | ||||
| { | { | ||||
| float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); | float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); | ||||
| svm_node_closure_store_weight(sd, weight); | svm_node_closure_store_weight(sd, weight); | ||||
| } | } | ||||
| ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset) | ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint weight_offset) | |||||
| { | { | ||||
| float3 weight = stack_load_float3(stack, weight_offset); | float3 weight = stack_load_float3(stack, weight_offset); | ||||
| svm_node_closure_store_weight(sd, weight); | svm_node_closure_store_weight(sd, weight); | ||||
| } | } | ||||
| ccl_device_noinline void svm_node_emission_weight(const KernelGlobals *kg, | ccl_device_noinline void svm_node_emission_weight(ccl_global const KernelGlobals *kg, | ||||
| ShaderData *sd, | ccl_private ShaderData *sd, | ||||
| float *stack, | ccl_private float *stack, | ||||
| uint4 node) | uint4 node) | ||||
| { | { | ||||
| uint color_offset = node.y; | uint color_offset = node.y; | ||||
| uint strength_offset = node.z; | uint strength_offset = node.z; | ||||
| float strength = stack_load_float(stack, strength_offset); | float strength = stack_load_float(stack, strength_offset); | ||||
| float3 weight = stack_load_float3(stack, color_offset) * strength; | float3 weight = stack_load_float3(stack, color_offset) * strength; | ||||
| svm_node_closure_store_weight(sd, weight); | svm_node_closure_store_weight(sd, weight); | ||||
| } | } | ||||
| ccl_device_noinline void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_mix_closure(ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint4 node) | |||||
| { | { | ||||
| /* fetch weight from blend input, previous mix closures, | /* fetch weight from blend input, previous mix closures, | ||||
| * and write to stack to be used by closure nodes later */ | * and write to stack to be used by closure nodes later */ | ||||
| uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; | uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; | ||||
| svm_unpack_node_uchar4( | svm_unpack_node_uchar4( | ||||
| node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); | node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); | ||||
| float weight = stack_load_float(stack, weight_offset); | float weight = stack_load_float(stack, weight_offset); | ||||
| weight = saturate(weight); | weight = saturate(weight); | ||||
| float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) : | float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) : | ||||
| 1.0f; | 1.0f; | ||||
| if (stack_valid(weight1_offset)) | if (stack_valid(weight1_offset)) | ||||
| stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight)); | stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight)); | ||||
| if (stack_valid(weight2_offset)) | if (stack_valid(weight2_offset)) | ||||
| stack_store_float(stack, weight2_offset, in_weight * weight); | stack_store_float(stack, weight2_offset, in_weight * weight); | ||||
| } | } | ||||
| /* (Bump) normal */ | /* (Bump) normal */ | ||||
| ccl_device void svm_node_set_normal( | ccl_device void svm_node_set_normal(ccl_global const KernelGlobals *kg, | ||||
| const KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) | ccl_private ShaderData *sd, | ||||
| ccl_private float *stack, | |||||
| uint in_direction, | |||||
| uint out_normal) | |||||
| { | { | ||||
| float3 normal = stack_load_float3(stack, in_direction); | float3 normal = stack_load_float3(stack, in_direction); | ||||
| sd->N = normal; | sd->N = normal; | ||||
| stack_store_float3(stack, out_normal, normal); | stack_store_float3(stack, out_normal, normal); | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||