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, ¶m1_offset, ¶m2_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, ¶metrization);
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