1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 CCL_NAMESPACE_BEGIN
18 
19 /* Closure Nodes */
20 
svm_node_glass_setup(ShaderData * sd,MicrofacetBsdf * bsdf,int type,float eta,float roughness,bool refract)21 ccl_device void svm_node_glass_setup(
22     ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract)
23 {
24   if (type == CLOSURE_BSDF_SHARP_GLASS_ID) {
25     if (refract) {
26       bsdf->alpha_y = 0.0f;
27       bsdf->alpha_x = 0.0f;
28       bsdf->ior = eta;
29       sd->flag |= bsdf_refraction_setup(bsdf);
30     }
31     else {
32       bsdf->alpha_y = 0.0f;
33       bsdf->alpha_x = 0.0f;
34       bsdf->ior = 0.0f;
35       sd->flag |= bsdf_reflection_setup(bsdf);
36     }
37   }
38   else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
39     bsdf->alpha_x = roughness;
40     bsdf->alpha_y = roughness;
41     bsdf->ior = eta;
42 
43     if (refract)
44       sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
45     else
46       sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
47   }
48   else {
49     bsdf->alpha_x = roughness;
50     bsdf->alpha_y = roughness;
51     bsdf->ior = eta;
52 
53     if (refract)
54       sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
55     else
56       sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
57   }
58 }
59 
svm_node_closure_bsdf(KernelGlobals * kg,ShaderData * sd,float * stack,uint4 node,ShaderType shader_type,int path_flag,int * offset)60 ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
61                                       ShaderData *sd,
62                                       float *stack,
63                                       uint4 node,
64                                       ShaderType shader_type,
65                                       int path_flag,
66                                       int *offset)
67 {
68   uint type, param1_offset, param2_offset;
69 
70   uint mix_weight_offset;
71   svm_unpack_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
72   float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
73                                                        1.0f);
74 
75   /* note we read this extra node before weight check, so offset is added */
76   uint4 data_node = read_node(kg, offset);
77 
78   /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
79   if (mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) {
80     if (type == CLOSURE_BSDF_PRINCIPLED_ID) {
81       /* Read all principled BSDF extra data to get the right offset. */
82       read_node(kg, offset);
83       read_node(kg, offset);
84       read_node(kg, offset);
85       read_node(kg, offset);
86     }
87 
88     return;
89   }
90 
91   float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
92 
93   float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
94                                                 __uint_as_float(node.z);
95   float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) :
96                                                 __uint_as_float(node.w);
97 
98   switch (type) {
99 #ifdef __PRINCIPLED__
100     case CLOSURE_BSDF_PRINCIPLED_ID: {
101       uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
102           sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset,
103           eta_offset, transmission_offset, anisotropic_rotation_offset,
104           transmission_roughness_offset;
105       uint4 data_node2 = read_node(kg, offset);
106 
107       float3 T = stack_load_float3(stack, data_node.y);
108       svm_unpack_node_uchar4(data_node.z,
109                              &specular_offset,
110                              &roughness_offset,
111                              &specular_tint_offset,
112                              &anisotropic_offset);
113       svm_unpack_node_uchar4(data_node.w,
114                              &sheen_offset,
115                              &sheen_tint_offset,
116                              &clearcoat_offset,
117                              &clearcoat_roughness_offset);
118       svm_unpack_node_uchar4(data_node2.x,
119                              &eta_offset,
120                              &transmission_offset,
121                              &anisotropic_rotation_offset,
122                              &transmission_roughness_offset);
123 
124       // get Disney principled parameters
125       float metallic = param1;
126       float subsurface = param2;
127       float specular = stack_load_float(stack, specular_offset);
128       float roughness = stack_load_float(stack, roughness_offset);
129       float specular_tint = stack_load_float(stack, specular_tint_offset);
130       float anisotropic = stack_load_float(stack, anisotropic_offset);
131       float sheen = stack_load_float(stack, sheen_offset);
132       float sheen_tint = stack_load_float(stack, sheen_tint_offset);
133       float clearcoat = stack_load_float(stack, clearcoat_offset);
134       float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
135       float transmission = stack_load_float(stack, transmission_offset);
136       float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
137       float transmission_roughness = stack_load_float(stack, transmission_roughness_offset);
138       float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
139 
140       ClosureType distribution = (ClosureType)data_node2.y;
141       ClosureType subsurface_method = (ClosureType)data_node2.z;
142 
143       /* rotate tangent */
144       if (anisotropic_rotation != 0.0f)
145         T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
146 
147       /* calculate ior */
148       float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
149 
150       // calculate fresnel for refraction
151       float cosNO = dot(N, sd->I);
152       float fresnel = fresnel_dielectric_cos(cosNO, ior);
153 
154       // calculate weights of the diffuse and specular part
155       float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission));
156 
157       float final_transmission = saturate(transmission) * (1.0f - saturate(metallic));
158       float specular_weight = (1.0f - final_transmission);
159 
160       // get the base color
161       uint4 data_base_color = read_node(kg, offset);
162       float3 base_color = stack_valid(data_base_color.x) ?
163                               stack_load_float3(stack, data_base_color.x) :
164                               make_float3(__uint_as_float(data_base_color.y),
165                                           __uint_as_float(data_base_color.z),
166                                           __uint_as_float(data_base_color.w));
167 
168       // get the additional clearcoat normal and subsurface scattering radius
169       uint4 data_cn_ssr = read_node(kg, offset);
170       float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ?
171                                     stack_load_float3(stack, data_cn_ssr.x) :
172                                     sd->N;
173       float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
174                                      stack_load_float3(stack, data_cn_ssr.y) :
175                                      make_float3(1.0f, 1.0f, 1.0f);
176 
177       // get the subsurface color
178       uint4 data_subsurface_color = read_node(kg, offset);
179       float3 subsurface_color = stack_valid(data_subsurface_color.x) ?
180                                     stack_load_float3(stack, data_subsurface_color.x) :
181                                     make_float3(__uint_as_float(data_subsurface_color.y),
182                                                 __uint_as_float(data_subsurface_color.z),
183                                                 __uint_as_float(data_subsurface_color.w));
184 
185       float3 weight = sd->svm_closure_weight * mix_weight;
186 
187 #  ifdef __SUBSURFACE__
188       float3 mixed_ss_base_color = subsurface_color * subsurface +
189                                    base_color * (1.0f - subsurface);
190       float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
191 
192       /* disable in case of diffuse ancestor, can't see it well then and
193        * adds considerably noise due to probabilities of continuing path
194        * getting lower and lower */
195       if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
196         subsurface = 0.0f;
197 
198         /* need to set the base color in this case such that the
199          * rays get the correctly mixed color after transmitting
200          * the object */
201         base_color = mixed_ss_base_color;
202       }
203 
204       /* diffuse */
205       if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
206         if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
207           float3 diff_weight = weight * base_color * diffuse_weight;
208 
209           PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
210               sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
211 
212           if (bsdf) {
213             bsdf->N = N;
214             bsdf->roughness = roughness;
215 
216             /* setup bsdf */
217             sd->flag |= bsdf_principled_diffuse_setup(bsdf);
218           }
219         }
220         else if (subsurface > CLOSURE_WEIGHT_CUTOFF) {
221           Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
222 
223           if (bssrdf) {
224             bssrdf->radius = subsurface_radius * subsurface;
225             bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID) ?
226                                  subsurface_color :
227                                  mixed_ss_base_color;
228             bssrdf->texture_blur = 0.0f;
229             bssrdf->sharpness = 0.0f;
230             bssrdf->N = N;
231             bssrdf->roughness = roughness;
232 
233             /* setup bsdf */
234             sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method);
235           }
236         }
237       }
238 #  else
239       /* diffuse */
240       if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
241         float3 diff_weight = weight * base_color * diffuse_weight;
242 
243         PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc(
244             sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
245 
246         if (bsdf) {
247           bsdf->N = N;
248           bsdf->roughness = roughness;
249 
250           /* setup bsdf */
251           sd->flag |= bsdf_principled_diffuse_setup(bsdf);
252         }
253       }
254 #  endif
255 
256       /* sheen */
257       if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
258         float m_cdlum = linear_rgb_to_gray(kg, base_color);
259         float3 m_ctint = m_cdlum > 0.0f ?
260                              base_color / m_cdlum :
261                              make_float3(1.0f, 1.0f, 1.0f);  // normalize lum. to isolate hue+sat
262 
263         /* color of the sheen component */
264         float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) +
265                              m_ctint * sheen_tint;
266 
267         float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
268 
269         PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc(
270             sd, sizeof(PrincipledSheenBsdf), sheen_weight);
271 
272         if (bsdf) {
273           bsdf->N = N;
274 
275           /* setup bsdf */
276           sd->flag |= bsdf_principled_sheen_setup(sd, bsdf);
277         }
278       }
279 
280       /* specular reflection */
281 #  ifdef __CAUSTICS_TRICKS__
282       if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
283 #  endif
284         if (specular_weight > CLOSURE_WEIGHT_CUTOFF &&
285             (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
286           float3 spec_weight = weight * specular_weight;
287 
288           MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
289               sd, sizeof(MicrofacetBsdf), spec_weight);
290           MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
291                                                         sd, sizeof(MicrofacetExtra)) :
292                                                     NULL;
293 
294           if (bsdf && extra) {
295             bsdf->N = N;
296             bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
297             bsdf->T = T;
298             bsdf->extra = extra;
299 
300             float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
301             float r2 = roughness * roughness;
302 
303             bsdf->alpha_x = r2 / aspect;
304             bsdf->alpha_y = r2 * aspect;
305 
306             float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y +
307                             0.1f * base_color.z;  // luminance approx.
308             float3 m_ctint = m_cdlum > 0.0f ?
309                                  base_color / m_cdlum :
310                                  make_float3(
311                                      0.0f, 0.0f, 0.0f);  // normalize lum. to isolate hue+sat
312             float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) +
313                              m_ctint * specular_tint;
314 
315             bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) +
316                                   base_color * metallic;
317             bsdf->extra->color = base_color;
318             bsdf->extra->clearcoat = 0.0f;
319 
320             /* setup bsdf */
321             if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
322                 roughness <= 0.075f) /* use single-scatter GGX */
323               sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
324             else /* use multi-scatter GGX */
325               sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
326           }
327         }
328 #  ifdef __CAUSTICS_TRICKS__
329       }
330 #  endif
331 
332       /* BSDF */
333 #  ifdef __CAUSTICS_TRICKS__
334       if (kernel_data.integrator.caustics_reflective ||
335           kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
336 #  endif
337         if (final_transmission > CLOSURE_WEIGHT_CUTOFF) {
338           float3 glass_weight = weight * final_transmission;
339           float3 cspec0 = base_color * specular_tint +
340                           make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
341 
342           if (roughness <= 5e-2f ||
343               distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
344             float refl_roughness = roughness;
345 
346             /* reflection */
347 #  ifdef __CAUSTICS_TRICKS__
348             if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
349 #  endif
350             {
351               MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
352                   sd, sizeof(MicrofacetBsdf), glass_weight * fresnel);
353               MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
354                                                             sd, sizeof(MicrofacetExtra)) :
355                                                         NULL;
356 
357               if (bsdf && extra) {
358                 bsdf->N = N;
359                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
360                 bsdf->extra = extra;
361 
362                 bsdf->alpha_x = refl_roughness * refl_roughness;
363                 bsdf->alpha_y = refl_roughness * refl_roughness;
364                 bsdf->ior = ior;
365 
366                 bsdf->extra->color = base_color;
367                 bsdf->extra->cspec0 = cspec0;
368                 bsdf->extra->clearcoat = 0.0f;
369 
370                 /* setup bsdf */
371                 sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
372               }
373             }
374 
375             /* refraction */
376 #  ifdef __CAUSTICS_TRICKS__
377             if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
378 #  endif
379             {
380               MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
381                   sd, sizeof(MicrofacetBsdf), base_color * glass_weight * (1.0f - fresnel));
382               if (bsdf) {
383                 bsdf->N = N;
384                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
385                 bsdf->extra = NULL;
386 
387                 if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
388                   transmission_roughness = 1.0f - (1.0f - refl_roughness) *
389                                                       (1.0f - transmission_roughness);
390                 else
391                   transmission_roughness = refl_roughness;
392 
393                 bsdf->alpha_x = transmission_roughness * transmission_roughness;
394                 bsdf->alpha_y = transmission_roughness * transmission_roughness;
395                 bsdf->ior = ior;
396 
397                 /* setup bsdf */
398                 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
399               }
400             }
401           }
402           else { /* use multi-scatter GGX */
403             MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
404                 sd, sizeof(MicrofacetBsdf), glass_weight);
405             MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
406                                                           sd, sizeof(MicrofacetExtra)) :
407                                                       NULL;
408 
409             if (bsdf && extra) {
410               bsdf->N = N;
411               bsdf->extra = extra;
412               bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
413 
414               bsdf->alpha_x = roughness * roughness;
415               bsdf->alpha_y = roughness * roughness;
416               bsdf->ior = ior;
417 
418               bsdf->extra->color = base_color;
419               bsdf->extra->cspec0 = cspec0;
420               bsdf->extra->clearcoat = 0.0f;
421 
422               /* setup bsdf */
423               sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
424             }
425           }
426         }
427 #  ifdef __CAUSTICS_TRICKS__
428       }
429 #  endif
430 
431       /* clearcoat */
432 #  ifdef __CAUSTICS_TRICKS__
433       if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
434 #  endif
435         if (clearcoat > CLOSURE_WEIGHT_CUTOFF) {
436           MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
437           MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra(
438                                                         sd, sizeof(MicrofacetExtra)) :
439                                                     NULL;
440 
441           if (bsdf && extra) {
442             bsdf->N = clearcoat_normal;
443             bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
444             bsdf->ior = 1.5f;
445             bsdf->extra = extra;
446 
447             bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
448             bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
449 
450             bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
451             bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
452             bsdf->extra->clearcoat = clearcoat;
453 
454             /* setup bsdf */
455             sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
456           }
457         }
458 #  ifdef __CAUSTICS_TRICKS__
459       }
460 #  endif
461 
462       break;
463     }
464 #endif /* __PRINCIPLED__ */
465     case CLOSURE_BSDF_DIFFUSE_ID: {
466       float3 weight = sd->svm_closure_weight * mix_weight;
467       OrenNayarBsdf *bsdf = (OrenNayarBsdf *)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
468 
469       if (bsdf) {
470         bsdf->N = N;
471 
472         float roughness = param1;
473 
474         if (roughness == 0.0f) {
475           sd->flag |= bsdf_diffuse_setup((DiffuseBsdf *)bsdf);
476         }
477         else {
478           bsdf->roughness = roughness;
479           sd->flag |= bsdf_oren_nayar_setup(bsdf);
480         }
481       }
482       break;
483     }
484     case CLOSURE_BSDF_TRANSLUCENT_ID: {
485       float3 weight = sd->svm_closure_weight * mix_weight;
486       DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
487 
488       if (bsdf) {
489         bsdf->N = N;
490         sd->flag |= bsdf_translucent_setup(bsdf);
491       }
492       break;
493     }
494     case CLOSURE_BSDF_TRANSPARENT_ID: {
495       float3 weight = sd->svm_closure_weight * mix_weight;
496       bsdf_transparent_setup(sd, weight, path_flag);
497       break;
498     }
499     case CLOSURE_BSDF_REFLECTION_ID:
500     case CLOSURE_BSDF_MICROFACET_GGX_ID:
501     case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
502     case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
503     case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
504 #ifdef __CAUSTICS_TRICKS__
505       if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
506         break;
507 #endif
508       float3 weight = sd->svm_closure_weight * mix_weight;
509       MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
510 
511       if (!bsdf) {
512         break;
513       }
514 
515       float roughness = sqr(param1);
516 
517       bsdf->N = N;
518       bsdf->ior = 0.0f;
519       bsdf->extra = NULL;
520 
521       if (data_node.y == SVM_STACK_INVALID) {
522         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
523         bsdf->alpha_x = roughness;
524         bsdf->alpha_y = roughness;
525       }
526       else {
527         bsdf->T = stack_load_float3(stack, data_node.y);
528 
529         /* rotate tangent */
530         float rotation = stack_load_float(stack, data_node.z);
531         if (rotation != 0.0f)
532           bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
533 
534         /* compute roughness */
535         float anisotropy = clamp(param2, -0.99f, 0.99f);
536         if (anisotropy < 0.0f) {
537           bsdf->alpha_x = roughness / (1.0f + anisotropy);
538           bsdf->alpha_y = roughness * (1.0f + anisotropy);
539         }
540         else {
541           bsdf->alpha_x = roughness * (1.0f - anisotropy);
542           bsdf->alpha_y = roughness / (1.0f - anisotropy);
543         }
544       }
545 
546       /* setup bsdf */
547       if (type == CLOSURE_BSDF_REFLECTION_ID)
548         sd->flag |= bsdf_reflection_setup(bsdf);
549       else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
550         sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
551       else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID)
552         sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
553       else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
554         kernel_assert(stack_valid(data_node.w));
555         bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
556         if (bsdf->extra) {
557           bsdf->extra->color = stack_load_float3(stack, data_node.w);
558           bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
559           bsdf->extra->clearcoat = 0.0f;
560           sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
561         }
562       }
563       else {
564         sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
565       }
566 
567       break;
568     }
569     case CLOSURE_BSDF_REFRACTION_ID:
570     case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
571     case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
572 #ifdef __CAUSTICS_TRICKS__
573       if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
574         break;
575 #endif
576       float3 weight = sd->svm_closure_weight * mix_weight;
577       MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
578 
579       if (bsdf) {
580         bsdf->N = N;
581         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
582         bsdf->extra = NULL;
583 
584         float eta = fmaxf(param2, 1e-5f);
585         eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
586 
587         /* setup bsdf */
588         if (type == CLOSURE_BSDF_REFRACTION_ID) {
589           bsdf->alpha_x = 0.0f;
590           bsdf->alpha_y = 0.0f;
591           bsdf->ior = eta;
592 
593           sd->flag |= bsdf_refraction_setup(bsdf);
594         }
595         else {
596           float roughness = sqr(param1);
597           bsdf->alpha_x = roughness;
598           bsdf->alpha_y = roughness;
599           bsdf->ior = eta;
600 
601           if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
602             sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
603           else
604             sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
605         }
606       }
607 
608       break;
609     }
610     case CLOSURE_BSDF_SHARP_GLASS_ID:
611     case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
612     case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
613 #ifdef __CAUSTICS_TRICKS__
614       if (!kernel_data.integrator.caustics_reflective &&
615           !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) {
616         break;
617       }
618 #endif
619       float3 weight = sd->svm_closure_weight * mix_weight;
620 
621       /* index of refraction */
622       float eta = fmaxf(param2, 1e-5f);
623       eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
624 
625       /* fresnel */
626       float cosNO = dot(N, sd->I);
627       float fresnel = fresnel_dielectric_cos(cosNO, eta);
628       float roughness = sqr(param1);
629 
630       /* reflection */
631 #ifdef __CAUSTICS_TRICKS__
632       if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
633 #endif
634       {
635         MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
636             sd, sizeof(MicrofacetBsdf), weight * fresnel);
637 
638         if (bsdf) {
639           bsdf->N = N;
640           bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
641           bsdf->extra = NULL;
642           svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
643         }
644       }
645 
646       /* refraction */
647 #ifdef __CAUSTICS_TRICKS__
648       if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
649 #endif
650       {
651         MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(
652             sd, sizeof(MicrofacetBsdf), weight * (1.0f - fresnel));
653 
654         if (bsdf) {
655           bsdf->N = N;
656           bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
657           bsdf->extra = NULL;
658           svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
659         }
660       }
661 
662       break;
663     }
664     case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
665 #ifdef __CAUSTICS_TRICKS__
666       if (!kernel_data.integrator.caustics_reflective &&
667           !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
668         break;
669 #endif
670       float3 weight = sd->svm_closure_weight * mix_weight;
671       MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
672       if (!bsdf) {
673         break;
674       }
675 
676       MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
677       if (!extra) {
678         break;
679       }
680 
681       bsdf->N = N;
682       bsdf->extra = extra;
683       bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
684 
685       float roughness = sqr(param1);
686       bsdf->alpha_x = roughness;
687       bsdf->alpha_y = roughness;
688       float eta = fmaxf(param2, 1e-5f);
689       bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
690 
691       kernel_assert(stack_valid(data_node.z));
692       bsdf->extra->color = stack_load_float3(stack, data_node.z);
693       bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
694       bsdf->extra->clearcoat = 0.0f;
695 
696       /* setup bsdf */
697       sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
698       break;
699     }
700     case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
701       float3 weight = sd->svm_closure_weight * mix_weight;
702       VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
703 
704       if (bsdf) {
705         bsdf->N = N;
706 
707         bsdf->sigma = saturate(param1);
708         sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
709       }
710       break;
711     }
712     case CLOSURE_BSDF_GLOSSY_TOON_ID:
713 #ifdef __CAUSTICS_TRICKS__
714       if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
715         break;
716       ATTR_FALLTHROUGH;
717 #endif
718     case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
719       float3 weight = sd->svm_closure_weight * mix_weight;
720       ToonBsdf *bsdf = (ToonBsdf *)bsdf_alloc(sd, sizeof(ToonBsdf), weight);
721 
722       if (bsdf) {
723         bsdf->N = N;
724         bsdf->size = param1;
725         bsdf->smooth = param2;
726 
727         if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID)
728           sd->flag |= bsdf_diffuse_toon_setup(bsdf);
729         else
730           sd->flag |= bsdf_glossy_toon_setup(bsdf);
731       }
732       break;
733     }
734 #ifdef __HAIR__
735     case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: {
736       uint4 data_node2 = read_node(kg, offset);
737       uint4 data_node3 = read_node(kg, offset);
738       uint4 data_node4 = read_node(kg, offset);
739 
740       float3 weight = sd->svm_closure_weight * mix_weight;
741 
742       uint offset_ofs, ior_ofs, color_ofs, parametrization;
743       svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
744       float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
745       float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
746 
747       uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
748       svm_unpack_node_uchar4(data_node2.x,
749                              &coat_ofs,
750                              &melanin_ofs,
751                              &melanin_redness_ofs,
752                              &absorption_coefficient_ofs);
753 
754       uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs;
755       svm_unpack_node_uchar4(
756           data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs);
757 
758       const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y);
759       float random = 0.0f;
760       if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
761         random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
762       }
763       else {
764         random = stack_load_float_default(stack, random_ofs, data_node3.y);
765       }
766 
767       PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc(
768           sd, sizeof(PrincipledHairBSDF), weight);
769       if (bsdf) {
770         PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra(
771             sd, sizeof(PrincipledHairExtra));
772 
773         if (!extra)
774           break;
775 
776         /* Random factors range: [-randomization/2, +randomization/2]. */
777         float random_roughness = stack_load_float_default(
778             stack, random_roughness_ofs, data_node3.w);
779         float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
780         float roughness = param1 * factor_random_roughness;
781         float radial_roughness = param2 * factor_random_roughness;
782 
783         /* Remap Coat value to [0, 100]% of Roughness. */
784         float coat = stack_load_float_default(stack, coat_ofs, data_node2.y);
785         float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
786 
787         bsdf->N = N;
788         bsdf->v = roughness;
789         bsdf->s = radial_roughness;
790         bsdf->m0_roughness = m0_roughness;
791         bsdf->alpha = alpha;
792         bsdf->eta = ior;
793         bsdf->extra = extra;
794 
795         switch (parametrization) {
796           case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: {
797             float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
798             bsdf->sigma = absorption_coefficient;
799             break;
800           }
801           case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: {
802             float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
803             float melanin_redness = stack_load_float_default(
804                 stack, melanin_redness_ofs, data_node2.w);
805 
806             /* Randomize melanin.  */
807             float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
808             random_color = clamp(random_color, 0.0f, 1.0f);
809             float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
810             melanin *= factor_random_color;
811 
812             /* Map melanin 0..inf from more perceptually linear 0..1. */
813             melanin = -logf(fmaxf(1.0f - melanin, 0.0001f));
814 
815             /* Benedikt Bitterli's melanin ratio remapping. */
816             float eumelanin = melanin * (1.0f - melanin_redness);
817             float pheomelanin = melanin * melanin_redness;
818             float3 melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin,
819                                                                                  pheomelanin);
820 
821             /* Optional tint. */
822             float3 tint = stack_load_float3(stack, tint_ofs);
823             float3 tint_sigma = bsdf_principled_hair_sigma_from_reflectance(tint,
824                                                                             radial_roughness);
825 
826             bsdf->sigma = melanin_sigma + tint_sigma;
827             break;
828           }
829           case NODE_PRINCIPLED_HAIR_REFLECTANCE: {
830             float3 color = stack_load_float3(stack, color_ofs);
831             bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(color, radial_roughness);
832             break;
833           }
834           default: {
835             /* Fallback to brownish hair, same as defaults for melanin. */
836             kernel_assert(!"Invalid Principled Hair parametrization!");
837             bsdf->sigma = bsdf_principled_hair_sigma_from_concentration(0.0f, 0.8054375f);
838             break;
839           }
840         }
841 
842         sd->flag |= bsdf_principled_hair_setup(sd, bsdf);
843       }
844       break;
845     }
846     case CLOSURE_BSDF_HAIR_REFLECTION_ID:
847     case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
848       float3 weight = sd->svm_closure_weight * mix_weight;
849 
850       HairBsdf *bsdf = (HairBsdf *)bsdf_alloc(sd, sizeof(HairBsdf), weight);
851 
852       if (bsdf) {
853         bsdf->N = N;
854         bsdf->roughness1 = param1;
855         bsdf->roughness2 = param2;
856         bsdf->offset = -stack_load_float(stack, data_node.z);
857 
858         if (stack_valid(data_node.y)) {
859           bsdf->T = normalize(stack_load_float3(stack, data_node.y));
860         }
861         else if (!(sd->type & PRIMITIVE_ALL_CURVE)) {
862           bsdf->T = normalize(sd->dPdv);
863           bsdf->offset = 0.0f;
864         }
865         else
866           bsdf->T = normalize(sd->dPdu);
867 
868         if (type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
869           sd->flag |= bsdf_hair_reflection_setup(bsdf);
870         }
871         else {
872           sd->flag |= bsdf_hair_transmission_setup(bsdf);
873         }
874       }
875 
876       break;
877     }
878 #endif /* __HAIR__ */
879 
880 #ifdef __SUBSURFACE__
881     case CLOSURE_BSSRDF_CUBIC_ID:
882     case CLOSURE_BSSRDF_GAUSSIAN_ID:
883     case CLOSURE_BSSRDF_BURLEY_ID:
884     case CLOSURE_BSSRDF_RANDOM_WALK_ID: {
885       float3 weight = sd->svm_closure_weight * mix_weight;
886       Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
887 
888       if (bssrdf) {
889         /* disable in case of diffuse ancestor, can't see it well then and
890          * adds considerably noise due to probabilities of continuing path
891          * getting lower and lower */
892         if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
893           param1 = 0.0f;
894 
895         bssrdf->radius = stack_load_float3(stack, data_node.z) * param1;
896         bssrdf->albedo = sd->svm_closure_weight;
897         bssrdf->texture_blur = param2;
898         bssrdf->sharpness = stack_load_float(stack, data_node.w);
899         bssrdf->N = N;
900         bssrdf->roughness = 0.0f;
901         sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
902       }
903 
904       break;
905     }
906 #endif
907     default:
908       break;
909   }
910 }
911 
svm_node_closure_volume(KernelGlobals * kg,ShaderData * sd,float * stack,uint4 node,ShaderType shader_type)912 ccl_device void svm_node_closure_volume(
913     KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type)
914 {
915 #ifdef __VOLUME__
916   /* Only sum extinction for volumes, variable is shared with surface transparency. */
917   if (shader_type != SHADER_TYPE_VOLUME) {
918     return;
919   }
920 
921   uint type, density_offset, anisotropy_offset;
922 
923   uint mix_weight_offset;
924   svm_unpack_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset);
925   float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
926                                                        1.0f);
927 
928   if (mix_weight == 0.0f) {
929     return;
930   }
931 
932   float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
933                                                   __uint_as_float(node.z);
934   density = mix_weight * fmaxf(density, 0.0f);
935 
936   /* Compute scattering coefficient. */
937   float3 weight = sd->svm_closure_weight;
938 
939   if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
940     weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
941   }
942 
943   weight *= density;
944 
945   /* Add closure for volume scattering. */
946   if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
947     HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc(
948         sd, sizeof(HenyeyGreensteinVolume), weight);
949 
950     if (volume) {
951       float anisotropy = (stack_valid(anisotropy_offset)) ?
952                              stack_load_float(stack, anisotropy_offset) :
953                              __uint_as_float(node.w);
954       volume->g = anisotropy; /* g */
955       sd->flag |= volume_henyey_greenstein_setup(volume);
956     }
957   }
958 
959   /* Sum total extinction weight. */
960   volume_extinction_setup(sd, weight);
961 #endif
962 }
963 
svm_node_principled_volume(KernelGlobals * kg,ShaderData * sd,float * stack,uint4 node,ShaderType shader_type,int path_flag,int * offset)964 ccl_device void svm_node_principled_volume(KernelGlobals *kg,
965                                            ShaderData *sd,
966                                            float *stack,
967                                            uint4 node,
968                                            ShaderType shader_type,
969                                            int path_flag,
970                                            int *offset)
971 {
972 #ifdef __VOLUME__
973   uint4 value_node = read_node(kg, offset);
974   uint4 attr_node = read_node(kg, offset);
975 
976   /* Only sum extinction for volumes, variable is shared with surface transparency. */
977   if (shader_type != SHADER_TYPE_VOLUME) {
978     return;
979   }
980 
981   uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset;
982   svm_unpack_node_uchar4(
983       node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
984   float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
985                                                        1.0f);
986 
987   if (mix_weight == 0.0f) {
988     return;
989   }
990 
991   /* Compute density. */
992   float primitive_density = 1.0f;
993   float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
994                                                   __uint_as_float(value_node.x);
995   density = mix_weight * fmaxf(density, 0.0f);
996 
997   if (density > CLOSURE_WEIGHT_CUTOFF) {
998     /* Density and color attribute lookup if available. */
999     const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x);
1000     if (attr_density.offset != ATTR_STD_NOT_FOUND) {
1001       primitive_density = primitive_volume_attribute_float(kg, sd, attr_density);
1002       density = fmaxf(density * primitive_density, 0.0f);
1003     }
1004   }
1005 
1006   if (density > CLOSURE_WEIGHT_CUTOFF) {
1007     /* Compute scattering color. */
1008     float3 color = sd->svm_closure_weight;
1009 
1010     const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
1011     if (attr_color.offset != ATTR_STD_NOT_FOUND) {
1012       color *= primitive_volume_attribute_float3(kg, sd, attr_color);
1013     }
1014 
1015     /* Add closure for volume scattering. */
1016     HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc(
1017         sd, sizeof(HenyeyGreensteinVolume), color * density);
1018     if (volume) {
1019       float anisotropy = (stack_valid(anisotropy_offset)) ?
1020                              stack_load_float(stack, anisotropy_offset) :
1021                              __uint_as_float(value_node.y);
1022       volume->g = anisotropy;
1023       sd->flag |= volume_henyey_greenstein_setup(volume);
1024     }
1025 
1026     /* Add extinction weight. */
1027     float3 zero = make_float3(0.0f, 0.0f, 0.0f);
1028     float3 one = make_float3(1.0f, 1.0f, 1.0f);
1029     float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero);
1030     float3 absorption = max(one - color, zero) * max(one - absorption_color, zero);
1031     volume_extinction_setup(sd, (color + absorption) * density);
1032   }
1033 
1034   /* Compute emission. */
1035   if (path_flag & PATH_RAY_SHADOW) {
1036     /* Don't need emission for shadows. */
1037     return;
1038   }
1039 
1040   uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset;
1041   svm_unpack_node_uchar4(
1042       node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
1043   float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) :
1044                                                     __uint_as_float(value_node.z);
1045   float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) :
1046                                                       __uint_as_float(value_node.w);
1047 
1048   if (emission > CLOSURE_WEIGHT_CUTOFF) {
1049     float3 emission_color = stack_load_float3(stack, emission_color_offset);
1050     emission_setup(sd, emission * emission_color);
1051   }
1052 
1053   if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
1054     float T = stack_load_float(stack, temperature_offset);
1055 
1056     /* Add flame temperature from attribute if available. */
1057     const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
1058     if (attr_temperature.offset != ATTR_STD_NOT_FOUND) {
1059       float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature);
1060       T *= fmaxf(temperature, 0.0f);
1061     }
1062 
1063     T = fmaxf(T, 0.0f);
1064 
1065     /* Stefan-Boltzmann law. */
1066     float T4 = sqr(sqr(T));
1067     float sigma = 5.670373e-8f * 1e-6f / M_PI_F;
1068     float intensity = sigma * mix(1.0f, T4, blackbody);
1069 
1070     if (intensity > CLOSURE_WEIGHT_CUTOFF) {
1071       float3 blackbody_tint = stack_load_float3(stack, node.w);
1072       float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T);
1073       emission_setup(sd, bb);
1074     }
1075   }
1076 #endif
1077 }
1078 
svm_node_closure_emission(ShaderData * sd,float * stack,uint4 node)1079 ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
1080 {
1081   uint mix_weight_offset = node.y;
1082   float3 weight = sd->svm_closure_weight;
1083 
1084   if (stack_valid(mix_weight_offset)) {
1085     float mix_weight = stack_load_float(stack, mix_weight_offset);
1086 
1087     if (mix_weight == 0.0f)
1088       return;
1089 
1090     weight *= mix_weight;
1091   }
1092 
1093   emission_setup(sd, weight);
1094 }
1095 
svm_node_closure_background(ShaderData * sd,float * stack,uint4 node)1096 ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
1097 {
1098   uint mix_weight_offset = node.y;
1099   float3 weight = sd->svm_closure_weight;
1100 
1101   if (stack_valid(mix_weight_offset)) {
1102     float mix_weight = stack_load_float(stack, mix_weight_offset);
1103 
1104     if (mix_weight == 0.0f)
1105       return;
1106 
1107     weight *= mix_weight;
1108   }
1109 
1110   background_setup(sd, weight);
1111 }
1112 
svm_node_closure_holdout(ShaderData * sd,float * stack,uint4 node)1113 ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
1114 {
1115   uint mix_weight_offset = node.y;
1116 
1117   if (stack_valid(mix_weight_offset)) {
1118     float mix_weight = stack_load_float(stack, mix_weight_offset);
1119 
1120     if (mix_weight == 0.0f)
1121       return;
1122 
1123     closure_alloc(
1124         sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
1125   }
1126   else
1127     closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
1128 
1129   sd->flag |= SD_HOLDOUT;
1130 }
1131 
1132 /* Closure Nodes */
1133 
svm_node_closure_store_weight(ShaderData * sd,float3 weight)1134 ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
1135 {
1136   sd->svm_closure_weight = weight;
1137 }
1138 
svm_node_closure_set_weight(ShaderData * sd,uint r,uint g,uint b)1139 ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
1140 {
1141   float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
1142   svm_node_closure_store_weight(sd, weight);
1143 }
1144 
svm_node_closure_weight(ShaderData * sd,float * stack,uint weight_offset)1145 ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
1146 {
1147   float3 weight = stack_load_float3(stack, weight_offset);
1148 
1149   svm_node_closure_store_weight(sd, weight);
1150 }
1151 
svm_node_emission_weight(KernelGlobals * kg,ShaderData * sd,float * stack,uint4 node)1152 ccl_device void svm_node_emission_weight(KernelGlobals *kg,
1153                                          ShaderData *sd,
1154                                          float *stack,
1155                                          uint4 node)
1156 {
1157   uint color_offset = node.y;
1158   uint strength_offset = node.z;
1159 
1160   float strength = stack_load_float(stack, strength_offset);
1161   float3 weight = stack_load_float3(stack, color_offset) * strength;
1162 
1163   svm_node_closure_store_weight(sd, weight);
1164 }
1165 
svm_node_mix_closure(ShaderData * sd,float * stack,uint4 node)1166 ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
1167 {
1168   /* fetch weight from blend input, previous mix closures,
1169    * and write to stack to be used by closure nodes later */
1170   uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
1171   svm_unpack_node_uchar4(
1172       node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
1173 
1174   float weight = stack_load_float(stack, weight_offset);
1175   weight = saturate(weight);
1176 
1177   float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) :
1178                                                       1.0f;
1179 
1180   if (stack_valid(weight1_offset))
1181     stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight));
1182   if (stack_valid(weight2_offset))
1183     stack_store_float(stack, weight2_offset, in_weight * weight);
1184 }
1185 
1186 /* (Bump) normal */
1187 
svm_node_set_normal(KernelGlobals * kg,ShaderData * sd,float * stack,uint in_direction,uint out_normal)1188 ccl_device void svm_node_set_normal(
1189     KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
1190 {
1191   float3 normal = stack_load_float3(stack, in_direction);
1192   sd->N = normal;
1193   stack_store_float3(stack, out_normal, normal);
1194 }
1195 
1196 CCL_NAMESPACE_END
1197