Blender V4.3
closure.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
11
12#include "kernel/util/color.h"
13
15
16/* Closure Nodes */
17
19{
20 if (type == CLOSURE_BSDF_PRINCIPLED_ID) {
21 /* Read all principled BSDF extra data to get the right offset. */
22 read_node(kg, &offset);
23 read_node(kg, &offset);
24 read_node(kg, &offset);
25 read_node(kg, &offset);
26 }
27
28 return offset;
29}
30
31template<uint node_feature_mask, ShaderType shader_type>
32#ifndef __KERNEL_ONEAPI__
34#else
36#endif
37 int
40 ccl_private float *stack,
41 Spectrum closure_weight,
42 uint4 node,
43 uint32_t path_flag,
44 int offset)
45{
46 uint type, param1_offset, param2_offset;
47
48 uint mix_weight_offset;
49 svm_unpack_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
50 float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
51 1.0f);
52
53 /* note we read this extra node before weight check, so offset is added */
54 uint4 data_node = read_node(kg, &offset);
55
56 /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
58 {
59 if ((shader_type != SHADER_TYPE_SURFACE) || mix_weight == 0.0f) {
60 return svm_node_closure_bsdf_skip(kg, offset, type);
61 }
62 }
63 else IF_KERNEL_NODES_FEATURE(EMISSION) {
64 if (type != CLOSURE_BSDF_PRINCIPLED_ID) {
65 /* Only principled BSDF can have emission. */
66 return svm_node_closure_bsdf_skip(kg, offset, type);
67 }
68 }
69 else {
70 return svm_node_closure_bsdf_skip(kg, offset, type);
71 }
72
73 float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
74 N = safe_normalize_fallback(N, sd->N);
75
76 float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
77 __uint_as_float(node.z);
78 float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) :
79 __uint_as_float(node.w);
80
81 switch (type) {
83 uint specular_ior_level_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
84 sheen_weight_offset, sheen_tint_offset, sheen_roughness_offset, coat_weight_offset,
85 coat_roughness_offset, coat_ior_offset, eta_offset, transmission_weight_offset,
86 anisotropic_rotation_offset, coat_tint_offset, coat_normal_offset, alpha_offset,
87 emission_strength_offset, emission_offset, thinfilm_thickness_offset,
88 diffuse_roughness_offset;
89 uint4 data_node2 = read_node(kg, &offset);
90
91 float3 T = stack_load_float3(stack, data_node.y);
92 svm_unpack_node_uchar4(data_node.z,
93 &specular_ior_level_offset,
94 &roughness_offset,
95 &specular_tint_offset,
96 &anisotropic_offset);
97 svm_unpack_node_uchar4(data_node.w,
98 &sheen_weight_offset,
99 &sheen_tint_offset,
100 &sheen_roughness_offset,
101 &diffuse_roughness_offset);
102 svm_unpack_node_uchar4(data_node2.x,
103 &eta_offset,
104 &transmission_weight_offset,
105 &anisotropic_rotation_offset,
106 &coat_normal_offset);
107 svm_unpack_node_uchar4(data_node2.w,
108 &coat_weight_offset,
109 &coat_roughness_offset,
110 &coat_ior_offset,
111 &coat_tint_offset);
112
113 // get Disney principled parameters
114 float metallic = saturatef(param1);
115 float subsurface_weight = saturatef(param2);
116 float specular_ior_level = max(stack_load_float(stack, specular_ior_level_offset), 0.0f);
117 float roughness = saturatef(stack_load_float(stack, roughness_offset));
118 Spectrum specular_tint = rgb_to_spectrum(
119 max(stack_load_float3(stack, specular_tint_offset), zero_float3()));
120 float anisotropic = saturatef(stack_load_float(stack, anisotropic_offset));
121 float sheen_weight = max(stack_load_float(stack, sheen_weight_offset), 0.0f);
122 float3 sheen_tint = max(stack_load_float3(stack, sheen_tint_offset), zero_float3());
123 float sheen_roughness = saturatef(stack_load_float(stack, sheen_roughness_offset));
124 float coat_weight = fmaxf(stack_load_float(stack, coat_weight_offset), 0.0f);
125 float coat_roughness = saturatef(stack_load_float(stack, coat_roughness_offset));
126 float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f);
127 float3 coat_tint = max(stack_load_float3(stack, coat_tint_offset), zero_float3());
128 float transmission_weight = saturatef(stack_load_float(stack, transmission_weight_offset));
129 float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
130 float ior = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
131
132 ClosureType distribution = (ClosureType)data_node2.y;
133#ifdef __SUBSURFACE__
134 ClosureType subsurface_method = (ClosureType)data_node2.z;
135#endif
136
137 float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
138 float3 coat_normal = stack_valid(coat_normal_offset) ?
139 stack_load_float3(stack, coat_normal_offset) :
140 sd->N;
141 coat_normal = safe_normalize_fallback(coat_normal, sd->N);
142
143 // get the base color
144 uint4 data_base_color = read_node(kg, &offset);
145 float3 base_color = stack_valid(data_base_color.x) ?
146 stack_load_float3(stack, data_base_color.x) :
147 make_float3(__uint_as_float(data_base_color.y),
148 __uint_as_float(data_base_color.z),
149 __uint_as_float(data_base_color.w));
150 base_color = max(base_color, zero_float3());
151 const float3 clamped_base_color = min(base_color, one_float3());
152
153 // get the subsurface scattering data
154 uint4 data_subsurf = read_node(kg, &offset);
155
156 uint4 data_alpha_emission_thin = read_node(kg, &offset);
157 svm_unpack_node_uchar4(data_alpha_emission_thin.x,
158 &alpha_offset,
159 &emission_strength_offset,
160 &emission_offset,
161 &thinfilm_thickness_offset);
162 float alpha = stack_valid(alpha_offset) ? stack_load_float(stack, alpha_offset) :
163 __uint_as_float(data_alpha_emission_thin.y);
164 alpha = saturatef(alpha);
165
166 float emission_strength = stack_valid(emission_strength_offset) ?
167 stack_load_float(stack, emission_strength_offset) :
168 __uint_as_float(data_alpha_emission_thin.z);
169 float3 emission = stack_load_float3(stack, emission_offset) * emission_strength;
170
171 float thinfilm_thickness = fmaxf(stack_load_float(stack, thinfilm_thickness_offset), 1e-5f);
172 float thinfilm_ior = fmaxf(stack_load_float(stack, data_alpha_emission_thin.w), 1e-5f);
173
174 Spectrum weight = closure_weight * mix_weight;
175
176 float alpha_x = sqr(roughness), alpha_y = sqr(roughness);
177 if (anisotropic > 0.0f) {
178 float aspect = sqrtf(1.0f - anisotropic * 0.9f);
179 alpha_x /= aspect;
180 alpha_y *= aspect;
181 if (anisotropic_rotation != 0.0f)
182 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
183 }
184
185#ifdef __CAUSTICS_TRICKS__
186 const bool reflective_caustics = (kernel_data.integrator.caustics_reflective ||
187 (path_flag & PATH_RAY_DIFFUSE) == 0);
188 const bool refractive_caustics = (kernel_data.integrator.caustics_refractive ||
189 (path_flag & PATH_RAY_DIFFUSE) == 0);
190#else
191 const bool reflective_caustics = true;
192 const bool refractive_caustics = true;
193#endif
194
195 /* Before any actual shader components, apply transparency. */
196 if (alpha < 1.0f) {
197 bsdf_transparent_setup(sd, weight * (1.0f - alpha), path_flag);
198 weight *= alpha;
199 }
200
201 /* First layer: Sheen */
202 if (sheen_weight > CLOSURE_WEIGHT_CUTOFF) {
204 sd, sizeof(SheenBsdf), sheen_weight * rgb_to_spectrum(sheen_tint) * weight);
205
206 if (bsdf) {
207 bsdf->N = safe_normalize(mix(N, coat_normal, saturatef(coat_weight)));
208 bsdf->roughness = sheen_roughness;
209
210 /* setup bsdf */
211 const int sheen_flag = bsdf_sheen_setup(kg, sd, bsdf);
212
213 if (sheen_flag) {
214 sd->flag |= sheen_flag;
215
216 /* Attenuate lower layers */
217 Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
218 weight = closure_layering_weight(albedo, weight);
219 }
220 }
221 }
222
223 /* Second layer: Coat */
224 if (coat_weight > CLOSURE_WEIGHT_CUTOFF) {
225 coat_normal = maybe_ensure_valid_specular_reflection(sd, coat_normal);
226 if (reflective_caustics) {
228 sd, sizeof(MicrofacetBsdf), coat_weight * weight);
229
230 if (bsdf) {
231 bsdf->N = coat_normal;
232 bsdf->T = zero_float3();
233 bsdf->ior = coat_ior;
234
235 bsdf->alpha_x = bsdf->alpha_y = sqr(coat_roughness);
236
237 /* setup bsdf */
238 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
240
241 /* Attenuate lower layers */
242 Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
243 weight = closure_layering_weight(albedo, weight);
244 }
245 }
246
247 if (!isequal(coat_tint, one_float3())) {
248 /* Tint is normalized to perpendicular incidence.
249 * Therefore, if we define the coat thickness as length 1, the length along the ray is
250 * t = sqrt(1+tan^2(angle(N, I))) = sqrt(1+tan^2(acos(dotNI))) = 1 / dotNI.
251 * From Beer's law, we have T = exp(-sigma_e * t).
252 * Therefore, tint = exp(-sigma_e * 1) (per def.), so -sigma_e = log(tint).
253 * From this, T = exp(log(tint) * t) = exp(log(tint)) ^ t = tint ^ t;
254 *
255 * Note that this is only an approximation - it assumes that the outgoing ray
256 * follows the same angle, and that there aren't multiple internal bounces.
257 * In particular, things that could be improved:
258 * - For transmissive materials, there should not be an outgoing path at all if the path
259 * is transmitted.
260 * - For rough materials, we could blend towards a view-independent average path length
261 * (e.g. 2 for diffuse reflection) for the outgoing direction.
262 * However, there's also an argument to be made for keeping parameters independent of
263 * each other for more intuitive control, in particular main roughness not affecting the
264 * coat.
265 */
266 float cosNI = dot(sd->wi, coat_normal);
267 /* Refract incoming direction into coat material.
268 * TIR is no concern here since we're always coming from the outside. */
269 float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI)));
270 float optical_depth = 1.0f / cosNT;
271 weight *= mix(
272 one_spectrum(), power(rgb_to_spectrum(coat_tint), optical_depth), coat_weight);
273 }
274 }
275
276 /* Emission (attenuated by sheen and coat) */
277 if (!is_zero(emission)) {
278 emission_setup(sd, rgb_to_spectrum(emission) * weight);
279 }
280
281 /* Metallic component */
282 if (metallic > CLOSURE_WEIGHT_CUTOFF) {
283 if (reflective_caustics) {
285 sd, sizeof(MicrofacetBsdf), metallic * weight);
286 ccl_private FresnelF82Tint *fresnel =
287 (bsdf != NULL) ?
289 NULL;
290
291 if (bsdf && fresnel) {
292 bsdf->N = valid_reflection_N;
293 bsdf->ior = 1.0f;
294 bsdf->T = T;
295 bsdf->alpha_x = alpha_x;
296 bsdf->alpha_y = alpha_y;
297
298 fresnel->f0 = rgb_to_spectrum(clamped_base_color);
299 const Spectrum f82 = min(specular_tint, one_spectrum());
300
301 /* setup bsdf */
302 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
303 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
304 bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
305 }
306 }
307 /* Attenuate other components */
308 weight *= (1.0f - metallic);
309 }
310
311 /* Transmission component */
312 if (transmission_weight > CLOSURE_WEIGHT_CUTOFF) {
313 if (reflective_caustics || refractive_caustics) {
315 sd, sizeof(MicrofacetBsdf), transmission_weight * weight);
318 sd, sizeof(FresnelGeneralizedSchlick)) :
319 NULL;
320
321 if (bsdf && fresnel) {
322 bsdf->N = valid_reflection_N;
323 bsdf->T = zero_float3();
324
325 bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
326 bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
327
328 fresnel->f0 = make_float3(F0_from_ior(ior)) * specular_tint;
329 fresnel->f90 = one_spectrum();
330 fresnel->exponent = -ior;
331 fresnel->reflection_tint = reflective_caustics ? one_spectrum() : zero_spectrum();
332 fresnel->transmission_tint = refractive_caustics ?
333 sqrt(rgb_to_spectrum(clamped_base_color)) :
335 fresnel->thin_film.thickness = thinfilm_thickness;
336 fresnel->thin_film.ior = (sd->flag & SD_BACKFACING) ? thinfilm_ior / ior :
337 thinfilm_ior;
338
339 /* setup bsdf */
340 sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
341 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
342 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
343 }
344 }
345 /* Attenuate other components */
346 weight *= (1.0f - transmission_weight);
347 }
348
349 /* Apply IOR adjustment */
350 float eta = ior;
351 float f0 = F0_from_ior(eta);
352 if (specular_ior_level != 0.5f) {
353 f0 *= 2.0f * specular_ior_level;
354 eta = ior_from_F0(f0);
355 if (ior < 1.0f) {
356 eta = 1.0f / eta;
357 }
358 }
359
360 /* Specular component */
361 if (reflective_caustics && (eta != 1.0f || thinfilm_thickness > 0.1f)) {
363 sd, sizeof(MicrofacetBsdf), weight);
366 sd, sizeof(FresnelGeneralizedSchlick)) :
367 NULL;
368
369 if (bsdf && fresnel) {
370 bsdf->N = valid_reflection_N;
371 bsdf->ior = eta;
372 bsdf->T = T;
373 bsdf->alpha_x = alpha_x;
374 bsdf->alpha_y = alpha_y;
375
376 fresnel->f0 = f0 * specular_tint;
377 fresnel->f90 = one_spectrum();
378 fresnel->exponent = -eta;
379 fresnel->reflection_tint = one_spectrum();
380 fresnel->transmission_tint = zero_spectrum();
381 fresnel->thin_film.thickness = thinfilm_thickness;
382 fresnel->thin_film.ior = thinfilm_ior;
383
384 /* setup bsdf */
385 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
386 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
387 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
388
389 /* Attenuate lower layers */
390 Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
391 weight = closure_layering_weight(albedo, weight);
392 }
393 }
394
395 /* Diffuse/Subsurface component */
396#ifdef __SUBSURFACE__
398 sd, rgb_to_spectrum(clamped_base_color) * subsurface_weight * weight);
399 if (bssrdf) {
400 float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y);
401 float subsurface_scale = stack_load_float(stack, data_subsurf.z);
402
403 bssrdf->radius = rgb_to_spectrum(max(subsurface_radius * subsurface_scale, zero_float3()));
404 bssrdf->albedo = rgb_to_spectrum(clamped_base_color);
406 bssrdf->alpha = sqr(roughness);
407 /* IOR is clamped to [1.01..3.8] inside bssrdf_setup */
408 bssrdf->ior = eta;
409 /* Anisotropy is clamped to [0.0..0.9] inside bssrdf_setup */
410 bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w);
411 if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
412 bssrdf->ior = stack_load_float(stack, data_subsurf.x);
413 }
414
415 /* setup bsdf */
416 sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, subsurface_method);
417 }
418#else
419 subsurface_weight = 0.0f;
420 (void)data_subsurf;
421#endif
422
424 sd,
425 sizeof(OrenNayarBsdf),
426 rgb_to_spectrum(base_color) * (1.0f - subsurface_weight) * weight);
427 if (bsdf) {
428 bsdf->N = N;
429
430 const float diffuse_roughness = saturatef(
431 stack_load_float(stack, diffuse_roughness_offset));
432 /* setup bsdf */
433 if (diffuse_roughness < CLOSURE_WEIGHT_CUTOFF) {
434 sd->flag |= bsdf_diffuse_setup((ccl_private DiffuseBsdf *)bsdf);
435 }
436 else {
437 bsdf->roughness = diffuse_roughness;
438 sd->flag |= bsdf_oren_nayar_setup(sd, bsdf, rgb_to_spectrum(base_color));
439 }
440 }
441
442 break;
443 }
445 Spectrum weight = closure_weight * mix_weight;
447 sd, sizeof(OrenNayarBsdf), weight);
448
449 if (bsdf) {
450 bsdf->N = N;
451
452 float roughness = param1;
453
454 if (roughness == 0.0f) {
455 sd->flag |= bsdf_diffuse_setup((ccl_private DiffuseBsdf *)bsdf);
456 }
457 else {
458 bsdf->roughness = roughness;
459 const Spectrum color = saturate(rgb_to_spectrum(stack_load_float3(stack, data_node.y)));
460 sd->flag |= bsdf_oren_nayar_setup(sd, bsdf, color);
461 }
462 }
463 break;
464 }
466 Spectrum weight = closure_weight * mix_weight;
468 sd, sizeof(DiffuseBsdf), weight);
469
470 if (bsdf) {
472 sd->flag |= bsdf_translucent_setup(bsdf);
473 }
474 break;
475 }
477 Spectrum weight = closure_weight * mix_weight;
478 bsdf_transparent_setup(sd, weight, path_flag);
479 break;
480 }
483#ifdef __CAUSTICS_TRICKS__
484 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
485 break;
486#endif
489
490 if (bsdf != NULL) {
491 uint base_ior_offset, edge_tint_k_offset, rotation_offset, tangent_offset;
493 node.z, &base_ior_offset, &edge_tint_k_offset, &rotation_offset, &tangent_offset);
494
495 float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
496 float3 T = stack_load_float3(stack, tangent_offset);
497 const float anisotropy = saturatef(param2);
498 const float roughness = saturatef(param1);
499 float alpha_x = sqr(roughness), alpha_y = sqr(roughness);
500 if (anisotropy > 0.0f) {
501 float aspect = sqrtf(1.0f - anisotropy * 0.9f);
502 alpha_x /= aspect;
503 alpha_y *= aspect;
504 float anisotropic_rotation = stack_load_float(stack, rotation_offset);
505 if (anisotropic_rotation != 0.0f) {
506 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
507 }
508 }
509
510 bsdf->N = valid_reflection_N;
511 bsdf->ior = 1.0f;
512 bsdf->T = T;
513 bsdf->alpha_x = alpha_x;
514 bsdf->alpha_y = alpha_y;
515
516 ClosureType distribution = (ClosureType)node.w;
517 /* Setup BSDF */
518 if (distribution == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) {
519 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
520 }
521 else {
522 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
523 }
524
525 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
526
530
531 const float3 n = max(stack_load_float3(stack, base_ior_offset), zero_float3());
532 const float3 k = max(stack_load_float3(stack, edge_tint_k_offset), zero_float3());
533
534 fresnel->n = rgb_to_spectrum(n);
535 fresnel->k = rgb_to_spectrum(k);
536 bsdf_microfacet_setup_fresnel_conductor(kg, bsdf, sd, fresnel, is_multiggx);
537 }
538 else {
540 sd, sizeof(FresnelF82Tint));
541
542 const float3 color = saturate(stack_load_float3(stack, base_ior_offset));
543 const float3 tint = saturate(stack_load_float3(stack, edge_tint_k_offset));
544
545 fresnel->f0 = rgb_to_spectrum(color);
546 const Spectrum f82 = rgb_to_spectrum(tint);
547 bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
548 }
549 }
550 break;
551 }
553 Spectrum weight = closure_weight * mix_weight;
554 float3 position = stack_load_float3(stack, data_node.y);
555 float3 direction = stack_load_float3(stack, data_node.z);
556 bsdf_ray_portal_setup(sd, weight, path_flag, position, direction);
557 break;
558 }
563#ifdef __CAUSTICS_TRICKS__
564 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
565 break;
566#endif
567 Spectrum weight = closure_weight * mix_weight;
569 sd, sizeof(MicrofacetBsdf), weight);
570
571 if (!bsdf) {
572 break;
573 }
574
575 float roughness = sqr(saturatef(param1));
576
578 bsdf->ior = 1.0f;
579
580 /* compute roughness */
581 float anisotropy = clamp(param2, -0.99f, 0.99f);
582 if (data_node.w == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) {
583 /* Isotropic case. */
584 bsdf->T = zero_float3();
585 bsdf->alpha_x = roughness;
586 bsdf->alpha_y = roughness;
587 }
588 else {
589 bsdf->T = stack_load_float3(stack, data_node.w);
590
591 /* rotate tangent */
592 float rotation = stack_load_float(stack, data_node.y);
593 if (rotation != 0.0f) {
594 bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
595 }
596
597 if (anisotropy < 0.0f) {
598 bsdf->alpha_x = roughness / (1.0f + anisotropy);
599 bsdf->alpha_y = roughness * (1.0f + anisotropy);
600 }
601 else {
602 bsdf->alpha_x = roughness * (1.0f - anisotropy);
603 bsdf->alpha_y = roughness / (1.0f - anisotropy);
604 }
605 }
606
607 /* setup bsdf */
609 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
610 }
611 else if (type == CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) {
612 sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
613 }
614 else {
615 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
617 kernel_assert(stack_valid(data_node.z));
618 const Spectrum color = max(rgb_to_spectrum(stack_load_float3(stack, data_node.z)),
619 zero_spectrum());
620 bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
621 }
622 }
623
624 break;
625 }
628#ifdef __CAUSTICS_TRICKS__
629 if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
630 break;
631#endif
632 Spectrum weight = closure_weight * mix_weight;
634 sd, sizeof(MicrofacetBsdf), weight);
635
636 if (bsdf) {
638 bsdf->T = zero_float3();
639
640 float eta = fmaxf(param2, 1e-5f);
641 eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
642
643 /* setup bsdf */
644 float roughness = sqr(param1);
645 bsdf->alpha_x = roughness;
646 bsdf->alpha_y = roughness;
647 bsdf->ior = eta;
648
651 }
652 else {
653 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
654 }
655 }
656
657 break;
658 }
662#ifdef __CAUSTICS_TRICKS__
663 const bool reflective_caustics = (kernel_data.integrator.caustics_reflective ||
664 (path_flag & PATH_RAY_DIFFUSE) == 0);
665 const bool refractive_caustics = (kernel_data.integrator.caustics_refractive ||
666 (path_flag & PATH_RAY_DIFFUSE) == 0);
667 if (!(reflective_caustics || refractive_caustics))
668 break;
669#else
670 const bool reflective_caustics = true;
671 const bool refractive_caustics = true;
672#endif
677 sd, sizeof(FresnelGeneralizedSchlick)) :
678 NULL;
679
680 if (bsdf && fresnel) {
682 bsdf->T = zero_float3();
683
684 float ior = fmaxf(param2, 1e-5f);
685 bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
686 bsdf->alpha_x = bsdf->alpha_y = sqr(saturatef(param1));
687
688 fresnel->f0 = make_float3(F0_from_ior(ior));
689 fresnel->f90 = one_spectrum();
690 fresnel->exponent = -ior;
691 const float3 color = max(stack_load_float3(stack, data_node.y), zero_float3());
692 fresnel->reflection_tint = reflective_caustics ? rgb_to_spectrum(color) : zero_spectrum();
693 fresnel->transmission_tint = refractive_caustics ? rgb_to_spectrum(color) :
695 fresnel->thin_film.thickness = 0.0f;
696 fresnel->thin_film.ior = 0.0f;
697
698 /* setup bsdf */
700 sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf);
701 }
702 else {
703 sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
704 }
705 const bool is_multiggx = (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
706 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
707 }
708 break;
709 }
711 Spectrum weight = closure_weight * mix_weight;
713 sd, sizeof(VelvetBsdf), weight);
714
715 if (bsdf) {
716 bsdf->N = N;
717
718 bsdf->sigma = saturatef(param1);
719 sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
720 }
721 break;
722 }
724 Spectrum weight = closure_weight * mix_weight;
726 sd, sizeof(SheenBsdf), weight);
727
728 if (bsdf) {
729 bsdf->N = N;
730 bsdf->roughness = saturatef(param1);
731
732 sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
733 }
734 break;
735 }
737#ifdef __CAUSTICS_TRICKS__
738 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
739 break;
741#endif
743 Spectrum weight = closure_weight * mix_weight;
745 sd, sizeof(ToonBsdf), weight);
746
747 if (bsdf) {
748 bsdf->N = N;
749 bsdf->size = param1;
750 bsdf->smooth = param2;
751
752 if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID) {
753 sd->flag |= bsdf_diffuse_toon_setup(bsdf);
754 }
755 else {
756 sd->flag |= bsdf_glossy_toon_setup(bsdf);
757 }
758 }
759 break;
760 }
761#ifdef __HAIR__
762# ifdef __PRINCIPLED_HAIR__
765 uint4 data_node2 = read_node(kg, &offset);
766 uint4 data_node3 = read_node(kg, &offset);
767 uint4 data_node4 = read_node(kg, &offset);
768
769 Spectrum weight = closure_weight * mix_weight;
770
771 uint offset_ofs, ior_ofs, color_ofs, parametrization;
772 svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
773 float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
774 float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
775
776 uint tint_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs;
777 svm_unpack_node_uchar4(data_node2.x,
778 &tint_ofs,
779 &melanin_ofs,
780 &melanin_redness_ofs,
781 &absorption_coefficient_ofs);
782
783 uint shared_ofs1, random_ofs, random_color_ofs, shared_ofs2;
785 data_node3.x, &shared_ofs1, &random_ofs, &random_color_ofs, &shared_ofs2);
786
787 const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node2.y);
788 float random = 0.0f;
789 if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
790 random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL);
791 }
792 else {
793 random = stack_load_float_default(stack, random_ofs, data_node3.y);
794 }
795
796 /* Random factors range: [-randomization/2, +randomization/2]. */
797 float random_roughness = param2;
798 float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
799 float roughness = param1 * factor_random_roughness;
800 float radial_roughness = (type == CLOSURE_BSDF_HAIR_CHIANG_ID) ?
801 stack_load_float_default(stack, shared_ofs2, data_node4.y) *
802 factor_random_roughness :
803 roughness;
804
805 Spectrum sigma;
806 switch (parametrization) {
808 float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs);
809 sigma = rgb_to_spectrum(absorption_coefficient);
810 break;
811 }
813 float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
814 float melanin_redness = stack_load_float_default(
815 stack, melanin_redness_ofs, data_node2.w);
816
817 /* Randomize melanin. */
818 float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
819 random_color = clamp(random_color, 0.0f, 1.0f);
820 float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
821 melanin *= factor_random_color;
822
823 /* Map melanin 0..inf from more perceptually linear 0..1. */
824 melanin = -logf(fmaxf(1.0f - melanin, 0.0001f));
825
826 /* Benedikt Bitterli's melanin ratio remapping. */
827 float eumelanin = melanin * (1.0f - melanin_redness);
828 float pheomelanin = melanin * melanin_redness;
830 pheomelanin);
831
832 /* Optional tint. */
833 float3 tint = stack_load_float3(stack, tint_ofs);
835 radial_roughness);
836
837 sigma = melanin_sigma + tint_sigma;
838 break;
839 }
841 float3 color = stack_load_float3(stack, color_ofs);
843 radial_roughness);
844 break;
845 }
846 default: {
847 /* Fallback to brownish hair, same as defaults for melanin. */
848 kernel_assert(!"Invalid Hair parametrization!");
849 sigma = bsdf_principled_hair_sigma_from_concentration(0.0f, 0.8054375f);
850 break;
851 }
852 }
853
854 if (type == CLOSURE_BSDF_HAIR_CHIANG_ID) {
856 sd, sizeof(ChiangHairBSDF), weight);
857 if (bsdf) {
858 /* Remap Coat value to [0, 100]% of Roughness. */
859 float coat = stack_load_float_default(stack, shared_ofs1, data_node3.w);
860 float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
861
862 bsdf->v = roughness;
863 bsdf->s = radial_roughness;
864 bsdf->m0_roughness = m0_roughness;
865 bsdf->alpha = alpha;
866 bsdf->eta = ior;
867 bsdf->sigma = sigma;
868
869 sd->flag |= bsdf_hair_chiang_setup(sd, bsdf);
870 }
871 }
872 else {
874 uint R_ofs, TT_ofs, TRT_ofs, unused;
875 svm_unpack_node_uchar4(data_node4.x, &R_ofs, &TT_ofs, &TRT_ofs, &unused);
876 float R = stack_load_float_default(stack, R_ofs, data_node4.y);
877 float TT = stack_load_float_default(stack, TT_ofs, data_node4.z);
878 float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w);
879 if (R <= 0.0f && TT <= 0.0f && TRT <= 0.0f) {
880 break;
881 }
882
884 sd, sizeof(HuangHairBSDF), weight);
885 if (bsdf) {
887 sd, sizeof(HuangHairExtra));
888
889 if (!extra) {
890 break;
891 }
892
893 bsdf->extra = extra;
894 bsdf->extra->R = fmaxf(0.0f, R);
895 bsdf->extra->TT = fmaxf(0.0f, TT);
896 bsdf->extra->TRT = fmaxf(0.0f, TRT);
897
898 bsdf->extra->pixel_coverage = 1.0f;
899
900 /* For camera ray, check if the hair covers more than one pixel, in which case a
901 * nearfield model is needed to prevent ribbon-like appearance. */
902 if ((path_flag & PATH_RAY_CAMERA) && (sd->type & PRIMITIVE_CURVE)) {
903 /* Interpolate radius between curve keys. */
904 const KernelCurve kcurve = kernel_data_fetch(curves, sd->prim);
905 const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
906 const int k1 = k0 + 1;
907 const float radius = mix(
908 kernel_data_fetch(curve_keys, k0).w, kernel_data_fetch(curve_keys, k1).w, sd->u);
909
910 bsdf->extra->pixel_coverage = 0.5f * sd->dP / radius;
911 }
912
913 bsdf->aspect_ratio = stack_load_float_default(stack, shared_ofs1, data_node3.w);
914 if (bsdf->aspect_ratio != 1.0f) {
915 /* Align ellipse major axis with the curve normal direction. */
916 const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, shared_ofs2);
917 bsdf->N = curve_attribute_float3(kg, sd, attr_descr_normal, NULL, NULL);
918 }
919
920 bsdf->roughness = roughness;
921 bsdf->tilt = alpha;
922 bsdf->eta = ior;
923 bsdf->sigma = sigma;
924
925 sd->flag |= bsdf_hair_huang_setup(sd, bsdf, path_flag);
926 }
927 }
928 break;
929 }
930# endif /* __PRINCIPLED_HAIR__ */
933 Spectrum weight = closure_weight * mix_weight;
934
936 sd, sizeof(HairBsdf), weight);
937
938 if (bsdf) {
940 bsdf->roughness1 = param1;
941 bsdf->roughness2 = param2;
942 bsdf->offset = -stack_load_float(stack, data_node.y);
943
944 if (stack_valid(data_node.w)) {
945 bsdf->T = normalize(stack_load_float3(stack, data_node.w));
946 }
947 else if (!(sd->type & PRIMITIVE_CURVE)) {
948 bsdf->T = normalize(sd->dPdv);
949 bsdf->offset = 0.0f;
950 }
951 else
952 bsdf->T = normalize(sd->dPdu);
953
955 sd->flag |= bsdf_hair_reflection_setup(bsdf);
956 }
957 else {
958 sd->flag |= bsdf_hair_transmission_setup(bsdf);
959 }
960 }
961
962 break;
963 }
964#endif /* __HAIR__ */
965
966#ifdef __SUBSURFACE__
970 Spectrum weight = closure_weight * mix_weight;
971 ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
972
973 if (bssrdf) {
974 bssrdf->radius = max(rgb_to_spectrum(stack_load_float3(stack, data_node.y) * param1),
975 zero_spectrum());
976 bssrdf->albedo = closure_weight;
978 bssrdf->ior = param2;
979 bssrdf->alpha = saturatef(stack_load_float(stack, data_node.w));
980 bssrdf->anisotropy = stack_load_float(stack, data_node.z);
981
982 sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, (ClosureType)type);
983 }
984
985 break;
986 }
987#endif
988 default:
989 break;
990 }
991
992 return offset;
993}
994
995template<ShaderType shader_type>
998 ccl_private float *stack,
999 Spectrum closure_weight,
1000 uint4 node)
1001{
1002#ifdef __VOLUME__
1003 /* Only sum extinction for volumes, variable is shared with surface transparency. */
1004 if (shader_type != SHADER_TYPE_VOLUME) {
1005 return;
1006 }
1007
1008 uint type, density_offset, param1_offset, mix_weight_offset;
1009 svm_unpack_node_uchar4(node.y, &type, &density_offset, &param1_offset, &mix_weight_offset);
1010 float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
1011 1.0f);
1012 if (mix_weight == 0.0f) {
1013 return;
1014 }
1015
1016 float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
1017 __uint_as_float(node.z);
1018 density = mix_weight * fmaxf(density, 0.0f) * object_volume_density(kg, sd->object);
1019
1020 /* Compute scattering coefficient. */
1021 Spectrum weight = closure_weight;
1022
1023 if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
1024 weight = one_spectrum() - weight;
1025 }
1026
1027 weight *= density;
1028
1029 /* Add closure for volume scattering. */
1030 if (CLOSURE_IS_VOLUME_SCATTER(type)) {
1031 switch (type) {
1034 bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
1035 if (volume) {
1036 volume->g = stack_valid(param1_offset) ? stack_load_float(stack, param1_offset) :
1037 __uint_as_float(node.w);
1038 sd->flag |= volume_henyey_greenstein_setup(volume);
1039 }
1040 } break;
1043 sd, sizeof(FournierForandVolume), weight);
1044 if (volume) {
1045 const float IOR = stack_load_float(stack, param1_offset);
1046 const float B = stack_load_float(stack, node.w);
1047 sd->flag |= volume_fournier_forand_setup(volume, B, IOR);
1048 }
1049 } break;
1052 sd, sizeof(RayleighVolume), weight);
1053 if (volume) {
1054 sd->flag |= volume_rayleigh_setup(volume);
1055 }
1056 break;
1057 }
1060 sd, sizeof(DraineVolume), weight);
1061 if (volume) {
1062 volume->g = stack_load_float(stack, param1_offset);
1063 volume->alpha = stack_load_float(stack, node.w);
1064 sd->flag |= volume_draine_setup(volume);
1065 }
1066 } break;
1067 case CLOSURE_VOLUME_MIE_ID: {
1068 /* We approximate the Mie phase function for water droplets using a mix of Draine and H-G
1069 * following "An Approximate Mie Scattering Function for Fog and Cloud Rendering", Johannes
1070 * Jendersie and Eugene d'Eon, https://research.nvidia.com/labs/rtr/approximate-mie.
1071 *
1072 * The numerical fit here (eq. 4-7 in the paper) is intended for 5<d<50.
1073 * Generally, we try to allow exceeding the soft limits when reasonable. Here, the only
1074 * real limit is that the values need to stay within -1<g<1, 0<a and 0<mixture<1.
1075 * This results in the condition d > 1.67154, so we clamp it to 2 to be safe. */
1076 const float d = max(2.0f,
1077 stack_valid(param1_offset) ? stack_load_float(stack, param1_offset) :
1078 __uint_as_float(node.w));
1079 const float mixture = fast_expf(-0.599085f / (d - 0.641583f) - 0.665888f);
1081 sd, sizeof(HenyeyGreensteinVolume), weight * (1.0f - mixture));
1082 if (hg) {
1083 hg->g = fast_expf(-0.0990567f / (d - 1.67154f));
1084 sd->flag |= volume_henyey_greenstein_setup(hg);
1085 }
1087 sd, sizeof(DraineVolume), weight * mixture);
1088 if (draine) {
1089 draine->g = fast_expf(-2.20679f / (d + 3.91029f) - 0.428934f);
1090 draine->alpha = fast_expf(3.62489f - 8.29288f / (d + 5.52825f));
1091 sd->flag |= volume_draine_setup(draine);
1092 }
1093 } break;
1094 }
1095 }
1096
1097 /* Sum total extinction weight. */
1098 volume_extinction_setup(sd, weight);
1099#endif
1100}
1101
1102template<ShaderType shader_type>
1105 ccl_private float *stack,
1106 Spectrum closure_weight,
1107 uint4 node,
1108 uint32_t path_flag,
1109 int offset)
1110{
1111#ifdef __VOLUME__
1112 uint4 value_node = read_node(kg, &offset);
1113 uint4 attr_node = read_node(kg, &offset);
1114
1115 /* Only sum extinction for volumes, variable is shared with surface transparency. */
1116 if (shader_type != SHADER_TYPE_VOLUME) {
1117 return offset;
1118 }
1119
1120 uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset;
1122 node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
1123 float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) :
1124 1.0f);
1125
1126 if (mix_weight == 0.0f) {
1127 return offset;
1128 }
1129
1130 /* Compute density. */
1131 float primitive_density = 1.0f;
1132 float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
1133 __uint_as_float(value_node.x);
1134 density = mix_weight * fmaxf(density, 0.0f) * object_volume_density(kg, sd->object);
1135
1136 if (density > CLOSURE_WEIGHT_CUTOFF) {
1137 /* Density and color attribute lookup if available. */
1138 const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x);
1139 if (attr_density.offset != ATTR_STD_NOT_FOUND) {
1140 primitive_density = primitive_volume_attribute_float(kg, sd, attr_density);
1141 density = fmaxf(density * primitive_density, 0.0f);
1142 }
1143 }
1144
1145 if (density > CLOSURE_WEIGHT_CUTOFF) {
1146 /* Compute scattering color. */
1147 Spectrum color = closure_weight;
1148
1149 const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
1150 if (attr_color.offset != ATTR_STD_NOT_FOUND) {
1151 color *= rgb_to_spectrum(primitive_volume_attribute_float3(kg, sd, attr_color));
1152 }
1153
1154 /* Add closure for volume scattering. */
1156 sd, sizeof(HenyeyGreensteinVolume), color * density);
1157 if (volume) {
1158 float anisotropy = (stack_valid(anisotropy_offset)) ?
1159 stack_load_float(stack, anisotropy_offset) :
1160 __uint_as_float(value_node.y);
1161 volume->g = anisotropy;
1162 sd->flag |= volume_henyey_greenstein_setup(volume);
1163 }
1164
1165 /* Add extinction weight. */
1166 float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)),
1167 zero_float3());
1168
1169 Spectrum zero = zero_spectrum();
1170 Spectrum one = one_spectrum();
1171 Spectrum absorption = max(one - color, zero) *
1172 max(one - rgb_to_spectrum(absorption_color), zero);
1173 volume_extinction_setup(sd, (color + absorption) * density);
1174 }
1175
1176 /* Compute emission. */
1177 if (path_flag & PATH_RAY_SHADOW) {
1178 /* Don't need emission for shadows. */
1179 return offset;
1180 }
1181
1182 uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset;
1184 node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
1185 float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) :
1186 __uint_as_float(value_node.z);
1187 float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) :
1188 __uint_as_float(value_node.w);
1189
1190 if (emission > CLOSURE_WEIGHT_CUTOFF) {
1191 float3 emission_color = stack_load_float3(stack, emission_color_offset);
1193 sd, rgb_to_spectrum(emission * emission_color * object_volume_density(kg, sd->object)));
1194 }
1195
1196 if (blackbody > CLOSURE_WEIGHT_CUTOFF) {
1197 float T = stack_load_float(stack, temperature_offset);
1198
1199 /* Add flame temperature from attribute if available. */
1200 const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
1201 if (attr_temperature.offset != ATTR_STD_NOT_FOUND) {
1202 float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature);
1203 T *= fmaxf(temperature, 0.0f);
1204 }
1205
1206 T = fmaxf(T, 0.0f);
1207
1208 /* Stefan-Boltzmann law. */
1209 float T4 = sqr(sqr(T));
1210 float sigma = 5.670373e-8f * 1e-6f / M_PI_F;
1211 float intensity = sigma * mix(1.0f, T4, blackbody);
1212
1213 if (intensity > CLOSURE_WEIGHT_CUTOFF) {
1214 float3 blackbody_tint = stack_load_float3(stack, node.w);
1215 float3 bb = blackbody_tint * intensity *
1217 emission_setup(sd, rgb_to_spectrum(bb * object_volume_density(kg, sd->object)));
1218 }
1219 }
1220#endif
1221 return offset;
1222}
1223
1226 ccl_private float *stack,
1227 Spectrum closure_weight,
1228 uint4 node)
1229{
1230 uint mix_weight_offset = node.y;
1231 Spectrum weight = closure_weight;
1232
1233 if (stack_valid(mix_weight_offset)) {
1234 float mix_weight = stack_load_float(stack, mix_weight_offset);
1235
1236 if (mix_weight == 0.0f) {
1237 return;
1238 }
1239
1240 weight *= mix_weight;
1241 }
1242
1243 if (sd->flag & SD_IS_VOLUME_SHADER_EVAL) {
1244 weight *= object_volume_density(kg, sd->object);
1245 }
1246
1247 emission_setup(sd, weight);
1248}
1249
1251 ccl_private float *stack,
1252 Spectrum closure_weight,
1253 uint4 node)
1254{
1255 uint mix_weight_offset = node.y;
1256 Spectrum weight = closure_weight;
1257
1258 if (stack_valid(mix_weight_offset)) {
1259 float mix_weight = stack_load_float(stack, mix_weight_offset);
1260
1261 if (mix_weight == 0.0f) {
1262 return;
1263 }
1264
1265 weight *= mix_weight;
1266 }
1267
1268 background_setup(sd, weight);
1269}
1270
1272 ccl_private float *stack,
1273 Spectrum closure_weight,
1274 uint4 node)
1275{
1276 uint mix_weight_offset = node.y;
1277
1278 if (stack_valid(mix_weight_offset)) {
1279 float mix_weight = stack_load_float(stack, mix_weight_offset);
1280
1281 if (mix_weight == 0.0f) {
1282 return;
1283 }
1284
1285 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight * mix_weight);
1286 }
1287 else {
1288 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight);
1289 }
1290
1291 sd->flag |= SD_HOLDOUT;
1292}
1293
1294/* Closure Nodes */
1295
1302
1304 ccl_private float *stack,
1305 ccl_private Spectrum *closure_weight,
1306 uint weight_offset)
1307{
1308 *closure_weight = rgb_to_spectrum(stack_load_float3(stack, weight_offset));
1309}
1310
1313 ccl_private float *stack,
1314 ccl_private Spectrum *closure_weight,
1315 uint4 node)
1316{
1317 uint color_offset = node.y;
1318 uint strength_offset = node.z;
1319
1320 float strength = stack_load_float(stack, strength_offset);
1321 *closure_weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength;
1322}
1323
1325 ccl_private float *stack,
1326 uint4 node)
1327{
1328 /* fetch weight from blend input, previous mix closures,
1329 * and write to stack to be used by closure nodes later */
1330 uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
1332 node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
1333
1334 float weight = stack_load_float(stack, weight_offset);
1335 weight = saturatef(weight);
1336
1337 float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) :
1338 1.0f;
1339
1340 if (stack_valid(weight1_offset))
1341 stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight));
1342 if (stack_valid(weight2_offset))
1343 stack_store_float(stack, weight2_offset, in_weight * weight);
1344}
1345
1346/* (Bump) normal */
1347
1350 ccl_private float *stack,
1351 uint in_direction,
1352 uint out_normal)
1353{
1354 float3 normal = stack_load_float3(stack, in_direction);
1355 sd->N = normal;
1356 stack_store_float3(stack, out_normal, normal);
1357}
1358
#define ATTR_FALLTHROUGH
sqrt(x)+1/max(0
unsigned int uint
#define saturate(a)
static float mix_weight(float weight, float weight2, char mix_mode)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue Hue Saturation Apply a color transformation in the HSV color model Specular Similar to the Principled BSDF node but uses the specular workflow instead of metallic
ccl_device_inline ccl_private ShaderClosure * bsdf_alloc(ccl_private ShaderData *sd, int size, Spectrum weight)
Definition alloc.h:52
ccl_device ccl_private void * closure_alloc_extra(ccl_private ShaderData *sd, int size)
Definition alloc.h:31
CCL_NAMESPACE_BEGIN ccl_device ccl_private ShaderClosure * closure_alloc(ccl_private ShaderData *sd, int size, ClosureType type, Spectrum weight)
Definition alloc.h:9
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc, const bool reflection, const bool transmission)
Definition bsdf.h:604
CCL_NAMESPACE_BEGIN ccl_device int bsdf_ashikhmin_shirley_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf)
ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf)
ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
ccl_device int bsdf_hair_reflection_setup(ccl_private HairBsdf *bsdf)
Definition bsdf_hair.h:23
ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
Definition bsdf_hair.h:31
ccl_device int bsdf_microfacet_beckmann_glass_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, ccl_private FresnelConductor *fresnel, const bool preserve_energy)
ccl_device int bsdf_microfacet_beckmann_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device void bsdf_microfacet_setup_fresnel_dielectric(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, ccl_private FresnelGeneralizedSchlick *fresnel, const bool preserve_energy)
ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, const Spectrum color)
ccl_device void bsdf_microfacet_setup_fresnel_f82_tint(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, ccl_private FresnelF82Tint *fresnel, const Spectrum f82_tint, const bool preserve_energy)
ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_oren_nayar_setup(ccl_private const ShaderData *sd, ccl_private OrenNayarBsdf *bsdf, const Spectrum color)
ccl_device void bsdf_ray_portal_setup(ccl_private ShaderData *sd, const Spectrum weight, uint32_t path_flag, float3 position, float3 direction)
ccl_device int bsdf_sheen_setup(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private SheenBsdf *bsdf)
Definition bsdf_sheen.h:25
ccl_device int bsdf_diffuse_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:31
ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:113
CCL_NAMESPACE_BEGIN ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, const Spectrum weight, uint32_t path_flag)
ccl_device float F0_from_ior(float ior)
Definition bsdf_util.h:112
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
Definition bsdf_util.h:241
ccl_device float3 maybe_ensure_valid_specular_reflection(ccl_private ShaderData *sd, float3 N)
Definition bsdf_util.h:221
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin, const float pheomelanin)
Definition bsdf_util.h:248
ccl_device_inline Spectrum closure_layering_weight(const Spectrum layer_albedo, const Spectrum weight)
Definition bsdf_util.h:261
ccl_device float ior_from_F0(float f0)
Definition bsdf_util.h:106
ccl_device int bssrdf_setup(ccl_private ShaderData *sd, ccl_private Bssrdf *bssrdf, int path_flag, ClosureType type)
Definition bssrdf.h:283
ccl_device_inline ccl_private Bssrdf * bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
Definition bssrdf.h:265
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
ccl_device void svm_node_closure_set_weight(ccl_private ShaderData *sd, ccl_private Spectrum *closure_weight, uint r, uint g, uint b)
Definition closure.h:1296
ccl_device_noinline void svm_node_emission_weight(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, ccl_private Spectrum *closure_weight, uint4 node)
Definition closure.h:1311
ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node)
Definition closure.h:996
ccl_device_noinline void svm_node_mix_closure(ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition closure.h:1324
ccl_device void svm_node_set_normal(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint in_direction, uint out_normal)
Definition closure.h:1348
ccl_device_noinline void svm_node_closure_emission(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node)
Definition closure.h:1224
CCL_NAMESPACE_BEGIN ccl_device_inline int svm_node_closure_bsdf_skip(KernelGlobals kg, int offset, uint type)
Definition closure.h:18
ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node)
Definition closure.h:1271
ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd, ccl_private float *stack, ccl_private Spectrum *closure_weight, uint weight_offset)
Definition closure.h:1303
ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node, uint32_t path_flag, int offset)
Definition closure.h:38
ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node)
Definition closure.h:1250
ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, uint4 node, uint32_t path_flag, int offset)
Definition closure.h:1103
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define kernel_assert(cond)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define logf(x)
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
#define fmaxf(x, y)
#define fabsf(x)
#define sqrtf(x)
#define __uint_as_float(x)
ccl_device void emission_setup(ccl_private ShaderData *sd, const Spectrum weight)
Definition emissive.h:27
CCL_NAMESPACE_BEGIN ccl_device void background_setup(ccl_private ShaderData *sd, const Spectrum weight)
Definition emissive.h:14
#define mix(a, b, c)
Definition hash.h:36
CCL_NAMESPACE_BEGIN ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, Spectrum weight)
ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(ccl_private float *stack, uint a)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *offset)
ccl_device_inline float stack_load_float_default(ccl_private float *stack, uint a, uint value)
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
ccl_device_inline float stack_load_float(ccl_private float *stack, uint a)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(uint a)
#define CLOSURE_IS_VOLUME_SCATTER(type)
@ NODE_PRINCIPLED_HAIR_REFLECTANCE
@ NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION
@ NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION
@ SHADER_TYPE_SURFACE
@ SHADER_TYPE_VOLUME
#define SVM_STACK_INVALID
ClosureType
@ CLOSURE_VOLUME_RAYLEIGH_ID
@ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID
@ CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID
@ CLOSURE_VOLUME_MIE_ID
@ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID
@ CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID
@ CLOSURE_BSDF_DIFFUSE_ID
@ CLOSURE_BSSRDF_BURLEY_ID
@ CLOSURE_BSDF_PRINCIPLED_ID
@ CLOSURE_BSDF_SHEEN_ID
@ CLOSURE_BSDF_TRANSPARENT_ID
@ CLOSURE_BSDF_DIFFUSE_TOON_ID
@ CLOSURE_VOLUME_DRAINE_ID
@ CLOSURE_BSDF_MICROFACET_GGX_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID
@ CLOSURE_BSDF_HAIR_TRANSMISSION_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID
@ CLOSURE_VOLUME_FOURNIER_FORAND_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_ID
@ CLOSURE_BSDF_PHYSICAL_CONDUCTOR
@ CLOSURE_BSDF_HAIR_HUANG_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_ID
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID
@ CLOSURE_BSDF_F82_CONDUCTOR
@ CLOSURE_BSDF_RAY_PORTAL_ID
@ CLOSURE_HOLDOUT_ID
@ CLOSURE_BSDF_GLOSSY_TOON_ID
@ CLOSURE_BSDF_HAIR_CHIANG_ID
@ CLOSURE_VOLUME_ABSORPTION_ID
@ CLOSURE_BSDF_HAIR_REFLECTION_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID
@ CLOSURE_BSDF_TRANSLUCENT_ID
@ CLOSURE_BSDF_ASHIKHMIN_VELVET_ID
#define CLOSURE_WEIGHT_CUTOFF
@ SD_IS_VOLUME_SHADER_EVAL
@ SD_BACKFACING
@ SD_HOLDOUT
@ PRIMITIVE_CURVE
@ ATTR_STD_NOT_FOUND
#define IF_KERNEL_NODES_FEATURE(feature)
@ PATH_RAY_SHADOW
@ PATH_RAY_DIFFUSE
@ PATH_RAY_CAMERA
#define PRIMITIVE_UNPACK_SEGMENT(type)
ShaderData
ShaderClosure
ccl_device float3 rec709_to_rgb(KernelGlobals kg, float3 rec709)
ccl_device_inline Spectrum rgb_to_spectrum(float3 rgb)
ccl_device_inline float fast_expf(float x)
Definition math_fast.h:427
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float2 power(float2 v, float e)
ccl_device_inline bool isequal(const float2 a, const float2 b)
ccl_device_inline float3 safe_normalize_fallback(const float3 a, const float3 fallback)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
ccl_device float3 svm_math_blackbody_color_rec709(float t)
Definition math_util.h:195
#define N
#define T
#define B
#define R
#define T4
Definition md5.cpp:21
#define M_PI_F
Definition mikk_util.hh:15
CCL_NAMESPACE_BEGIN ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
Definition primitive.h:22
#define M_2PI_F
Definition sky_float3.h:23
#define min(a, b)
Definition sort.c:32
closure color absorption() BUILTIN
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN
closure color draine(float g, float alpha) BUILTIN
unsigned int uint32_t
Definition stdint.h:80
static bool find_attribute(const std::string &attributes, const char *search_attribute)
Definition bssrdf.h:9
float roughness
Definition bsdf_sheen.h:18
float size
Definition bsdf_toon.h:15
uint x
Definition types_uint4.h:15
uint y
Definition types_uint4.h:15
uint z
Definition types_uint4.h:15
uint w
Definition types_uint4.h:15
float max
#define one_spectrum
#define zero_spectrum
#define make_spectrum(f)
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline float sqr(float a)
Definition util/math.h:782
ccl_device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
Definition util/math.h:683
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379
ccl_device int volume_draine_setup(ccl_private DraineVolume *volume)
ccl_device int volume_fournier_forand_setup(ccl_private FournierForandVolume *volume, float B, float IOR)
ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume *volume)
ccl_device int volume_rayleigh_setup(ccl_private RayleighVolume *volume)