Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/svm/svm_closure.h
| Show First 20 Lines • Show All 51 Lines • ▼ Show 20 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); | ||||
| } | } | ||||
| } | } | ||||
| ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, | template<uint node_feature_mask, ShaderType shader_type> | ||||
| ShaderData *sd, | ccl_device_noinline int svm_node_closure_bsdf( | ||||
| float *stack, | const KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int offset) | ||||
| uint4 node, | |||||
| ShaderType shader_type, | |||||
| 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); | ||||
| /* note we read this extra node before weight check, so offset is added */ | /* note we read this extra node before weight check, so offset is added */ | ||||
| uint4 data_node = read_node(kg, offset); | uint4 data_node = read_node(kg, &offset); | ||||
| /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */ | /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */ | ||||
| if (mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) { | if ((!KERNEL_NODES_FEATURE(BSDF) || shader_type != SHADER_TYPE_SURFACE) || mix_weight == 0.0f) { | ||||
| if (type == CLOSURE_BSDF_PRINCIPLED_ID) { | if (type == CLOSURE_BSDF_PRINCIPLED_ID) { | ||||
| /* Read all principled BSDF extra data to get the right offset. */ | /* Read all principled BSDF extra data to get the right offset. */ | ||||
| read_node(kg, offset); | read_node(kg, &offset); | ||||
| read_node(kg, offset); | read_node(kg, &offset); | ||||
| read_node(kg, offset); | read_node(kg, &offset); | ||||
| read_node(kg, offset); | read_node(kg, &offset); | ||||
| } | } | ||||
| return; | return offset; | ||||
| } | } | ||||
| float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N; | float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N; | ||||
| float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) : | float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) : | ||||
| __uint_as_float(node.z); | __uint_as_float(node.z); | ||||
| float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) : | float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) : | ||||
| __uint_as_float(node.w); | __uint_as_float(node.w); | ||||
| switch (type) { | switch (type) { | ||||
| #ifdef __PRINCIPLED__ | #ifdef __PRINCIPLED__ | ||||
| case CLOSURE_BSDF_PRINCIPLED_ID: { | case CLOSURE_BSDF_PRINCIPLED_ID: { | ||||
| uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, | uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, | ||||
| sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, | sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, | ||||
| eta_offset, transmission_offset, anisotropic_rotation_offset, | eta_offset, transmission_offset, anisotropic_rotation_offset, | ||||
| transmission_roughness_offset; | transmission_roughness_offset; | ||||
| uint4 data_node2 = read_node(kg, offset); | uint4 data_node2 = read_node(kg, &offset); | ||||
| float3 T = stack_load_float3(stack, data_node.y); | float3 T = stack_load_float3(stack, data_node.y); | ||||
| svm_unpack_node_uchar4(data_node.z, | svm_unpack_node_uchar4(data_node.z, | ||||
| &specular_offset, | &specular_offset, | ||||
| &roughness_offset, | &roughness_offset, | ||||
| &specular_tint_offset, | &specular_tint_offset, | ||||
| &anisotropic_offset); | &anisotropic_offset); | ||||
| svm_unpack_node_uchar4(data_node.w, | svm_unpack_node_uchar4(data_node.w, | ||||
| Show All 39 Lines | case CLOSURE_BSDF_PRINCIPLED_ID: { | ||||
| // calculate weights of the diffuse and specular part | // calculate weights of the diffuse and specular part | ||||
| float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission)); | float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission)); | ||||
| float final_transmission = saturate(transmission) * (1.0f - saturate(metallic)); | float final_transmission = saturate(transmission) * (1.0f - saturate(metallic)); | ||||
| float specular_weight = (1.0f - final_transmission); | float specular_weight = (1.0f - final_transmission); | ||||
| // get the base color | // get the base color | ||||
| uint4 data_base_color = read_node(kg, offset); | uint4 data_base_color = read_node(kg, &offset); | ||||
| float3 base_color = stack_valid(data_base_color.x) ? | float3 base_color = stack_valid(data_base_color.x) ? | ||||
| stack_load_float3(stack, data_base_color.x) : | stack_load_float3(stack, data_base_color.x) : | ||||
| make_float3(__uint_as_float(data_base_color.y), | make_float3(__uint_as_float(data_base_color.y), | ||||
| __uint_as_float(data_base_color.z), | __uint_as_float(data_base_color.z), | ||||
| __uint_as_float(data_base_color.w)); | __uint_as_float(data_base_color.w)); | ||||
| // get the additional clearcoat normal and subsurface scattering radius | // get the additional clearcoat normal and subsurface scattering radius | ||||
| uint4 data_cn_ssr = read_node(kg, offset); | uint4 data_cn_ssr = read_node(kg, &offset); | ||||
| float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? | float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? | ||||
| stack_load_float3(stack, data_cn_ssr.x) : | stack_load_float3(stack, data_cn_ssr.x) : | ||||
| sd->N; | sd->N; | ||||
| float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? | float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? | ||||
| stack_load_float3(stack, data_cn_ssr.y) : | stack_load_float3(stack, data_cn_ssr.y) : | ||||
| make_float3(1.0f, 1.0f, 1.0f); | make_float3(1.0f, 1.0f, 1.0f); | ||||
| float subsurface_ior = stack_valid(data_cn_ssr.z) ? stack_load_float(stack, data_cn_ssr.z) : | |||||
| 1.4f; | |||||
| float subsurface_anisotropy = stack_valid(data_cn_ssr.w) ? | |||||
| stack_load_float(stack, data_cn_ssr.w) : | |||||
| 0.0f; | |||||
| // get the subsurface color | // get the subsurface color | ||||
| uint4 data_subsurface_color = read_node(kg, offset); | uint4 data_subsurface_color = read_node(kg, &offset); | ||||
| float3 subsurface_color = stack_valid(data_subsurface_color.x) ? | float3 subsurface_color = stack_valid(data_subsurface_color.x) ? | ||||
| stack_load_float3(stack, data_subsurface_color.x) : | stack_load_float3(stack, data_subsurface_color.x) : | ||||
| make_float3(__uint_as_float(data_subsurface_color.y), | make_float3(__uint_as_float(data_subsurface_color.y), | ||||
| __uint_as_float(data_subsurface_color.z), | __uint_as_float(data_subsurface_color.z), | ||||
| __uint_as_float(data_subsurface_color.w)); | __uint_as_float(data_subsurface_color.w)); | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| Show All 30 Lines | # ifdef __SUBSURFACE__ | ||||
| sd->flag |= bsdf_principled_diffuse_setup(bsdf); | sd->flag |= bsdf_principled_diffuse_setup(bsdf); | ||||
| } | } | ||||
| } | } | ||||
| else if (subsurface > CLOSURE_WEIGHT_CUTOFF) { | else if (subsurface > CLOSURE_WEIGHT_CUTOFF) { | ||||
| Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); | Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); | ||||
| if (bssrdf) { | if (bssrdf) { | ||||
| bssrdf->radius = subsurface_radius * subsurface; | bssrdf->radius = subsurface_radius * subsurface; | ||||
| bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID) ? | bssrdf->albedo = mixed_ss_base_color; | ||||
| subsurface_color : | |||||
| mixed_ss_base_color; | |||||
| bssrdf->texture_blur = 0.0f; | |||||
| bssrdf->sharpness = 0.0f; | |||||
| bssrdf->N = N; | bssrdf->N = N; | ||||
| bssrdf->roughness = roughness; | bssrdf->roughness = roughness; | ||||
| /* Clamps protecting against bad/extreme and non physical values. */ | |||||
| subsurface_ior = clamp(subsurface_ior, 1.01f, 3.8f); | |||||
| bssrdf->anisotropy = clamp(subsurface_anisotropy, 0.0f, 0.9f); | |||||
| /* setup bsdf */ | /* setup bsdf */ | ||||
| sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method); | 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; | ||||
| ▲ Show 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | case CLOSURE_BSDF_DIFFUSE_TOON_ID: { | ||||
| sd->flag |= bsdf_diffuse_toon_setup(bsdf); | sd->flag |= bsdf_diffuse_toon_setup(bsdf); | ||||
| else | else | ||||
| sd->flag |= bsdf_glossy_toon_setup(bsdf); | sd->flag |= bsdf_glossy_toon_setup(bsdf); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| #ifdef __HAIR__ | #ifdef __HAIR__ | ||||
| case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { | case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { | ||||
| uint4 data_node2 = read_node(kg, offset); | uint4 data_node2 = read_node(kg, &offset); | ||||
| uint4 data_node3 = read_node(kg, offset); | uint4 data_node3 = read_node(kg, &offset); | ||||
| uint4 data_node4 = read_node(kg, offset); | uint4 data_node4 = read_node(kg, &offset); | ||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| uint offset_ofs, ior_ofs, color_ofs, parametrization; | uint offset_ofs, ior_ofs, color_ofs, parametrization; | ||||
| svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); | svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); | ||||
| float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); | float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); | ||||
| float ior = stack_load_float_default(stack, ior_ofs, data_node.w); | float ior = stack_load_float_default(stack, ior_ofs, data_node.w); | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| #endif /* __HAIR__ */ | #endif /* __HAIR__ */ | ||||
| #ifdef __SUBSURFACE__ | #ifdef __SUBSURFACE__ | ||||
| case CLOSURE_BSSRDF_CUBIC_ID: | case CLOSURE_BSSRDF_RANDOM_WALK_ID: | ||||
| case CLOSURE_BSSRDF_GAUSSIAN_ID: | case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: { | ||||
| case CLOSURE_BSSRDF_BURLEY_ID: | |||||
| case CLOSURE_BSSRDF_RANDOM_WALK_ID: { | |||||
| float3 weight = sd->svm_closure_weight * mix_weight; | float3 weight = sd->svm_closure_weight * mix_weight; | ||||
| Bssrdf *bssrdf = bssrdf_alloc(sd, weight); | 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; | ||||
| bssrdf->radius = stack_load_float3(stack, data_node.z) * param1; | bssrdf->radius = stack_load_float3(stack, data_node.z) * param1; | ||||
| bssrdf->albedo = sd->svm_closure_weight; | bssrdf->albedo = sd->svm_closure_weight; | ||||
| bssrdf->texture_blur = param2; | |||||
| bssrdf->sharpness = stack_load_float(stack, data_node.w); | |||||
| bssrdf->N = N; | bssrdf->N = N; | ||||
| bssrdf->roughness = 0.0f; | bssrdf->roughness = FLT_MAX; | ||||
| sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type); | |||||
| const float subsurface_ior = clamp(param2, 1.01f, 3.8f); | |||||
| const float subsurface_anisotropy = stack_load_float(stack, data_node.w); | |||||
| bssrdf->anisotropy = clamp(subsurface_anisotropy, 0.0f, 0.9f); | |||||
| sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, subsurface_ior); | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| #endif | #endif | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| return offset; | |||||
| } | } | ||||
| ccl_device void svm_node_closure_volume( | template<ShaderType shader_type> | ||||
| KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type) | ccl_device_noinline void svm_node_closure_volume(const KernelGlobals *kg, | ||||
| ShaderData *sd, | |||||
| float *stack, | |||||
| 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; | ||||
| } | } | ||||
| uint type, density_offset, anisotropy_offset; | uint type, density_offset, anisotropy_offset; | ||||
| Show All 34 Lines | if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) { | ||||
| } | } | ||||
| } | } | ||||
| /* Sum total extinction weight. */ | /* Sum total extinction weight. */ | ||||
| volume_extinction_setup(sd, weight); | volume_extinction_setup(sd, weight); | ||||
| #endif | #endif | ||||
| } | } | ||||
| ccl_device void svm_node_principled_volume(KernelGlobals *kg, | template<ShaderType shader_type> | ||||
| ShaderData *sd, | ccl_device_noinline int svm_node_principled_volume( | ||||
| float *stack, | const KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int offset) | ||||
| uint4 node, | |||||
| ShaderType shader_type, | |||||
| 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; | return offset; | ||||
| } | } | ||||
| uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset; | uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset; | ||||
| svm_unpack_node_uchar4( | svm_unpack_node_uchar4( | ||||
| node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset); | node.y, &density_offset, &anisotropy_offset, &absorption_color_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); | ||||
| if (mix_weight == 0.0f) { | if (mix_weight == 0.0f) { | ||||
| return; | return offset; | ||||
| } | } | ||||
| /* Compute density. */ | /* Compute density. */ | ||||
| float primitive_density = 1.0f; | float primitive_density = 1.0f; | ||||
| float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) : | float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) : | ||||
| __uint_as_float(value_node.x); | __uint_as_float(value_node.x); | ||||
| density = mix_weight * fmaxf(density, 0.0f); | density = mix_weight * fmaxf(density, 0.0f); | ||||
| Show All 32 Lines | if (density > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero); | float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero); | ||||
| float3 absorption = max(one - color, zero) * max(one - absorption_color, zero); | float3 absorption = max(one - color, zero) * max(one - absorption_color, zero); | ||||
| volume_extinction_setup(sd, (color + absorption) * density); | volume_extinction_setup(sd, (color + absorption) * density); | ||||
| } | } | ||||
| /* Compute emission. */ | /* Compute emission. */ | ||||
| if (path_flag & PATH_RAY_SHADOW) { | if (path_flag & PATH_RAY_SHADOW) { | ||||
| /* Don't need emission for shadows. */ | /* Don't need emission for shadows. */ | ||||
| return; | return offset; | ||||
| } | } | ||||
| uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset; | uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset; | ||||
| svm_unpack_node_uchar4( | svm_unpack_node_uchar4( | ||||
| node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset); | node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset); | ||||
| float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) : | float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) : | ||||
| __uint_as_float(value_node.z); | __uint_as_float(value_node.z); | ||||
| float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) : | float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) : | ||||
| Show All 23 Lines | if (blackbody > CLOSURE_WEIGHT_CUTOFF) { | ||||
| if (intensity > CLOSURE_WEIGHT_CUTOFF) { | if (intensity > CLOSURE_WEIGHT_CUTOFF) { | ||||
| float3 blackbody_tint = stack_load_float3(stack, node.w); | float3 blackbody_tint = stack_load_float3(stack, node.w); | ||||
| 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; | |||||
| } | } | ||||
| ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_emission(ShaderData *sd, 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 void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_background(ShaderData *sd, 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 void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_closure_holdout(ShaderData *sd, 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; | ||||
| Show All 18 Lines | |||||
| { | { | ||||
| 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(ShaderData *sd, 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 void svm_node_emission_weight(KernelGlobals *kg, | ccl_device_noinline void svm_node_emission_weight(const KernelGlobals *kg, | ||||
| ShaderData *sd, | ShaderData *sd, | ||||
| float *stack, | 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 void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node) | ccl_device_noinline void svm_node_mix_closure(ShaderData *sd, 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( | ||||
| KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) | const KernelGlobals *kg, ShaderData *sd, 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 | ||||