Blender V4.5
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
13
14#include "kernel/geom/curve.h"
15#include "kernel/geom/object.h"
17
19#include "kernel/svm/util.h"
20
22
24
25/* Closure Nodes */
26
28{
29 if (type == CLOSURE_BSDF_PRINCIPLED_ID) {
30 /* Read all principled BSDF extra data to get the right offset. */
31 read_node(kg, &offset);
32 read_node(kg, &offset);
33 read_node(kg, &offset);
34 read_node(kg, &offset);
35 }
36
37 return offset;
38}
39
40template<uint node_feature_mask, ShaderType shader_type>
41#ifndef __KERNEL_ONEAPI__
43#else
45#endif
46 int
48 ccl_private ShaderData *sd,
49 ccl_private float *stack,
50 Spectrum closure_weight,
51 const uint4 node,
52 const uint32_t path_flag,
53 int offset)
54{
55 uint type;
56 uint param1_offset;
57 uint param2_offset;
58
59 uint mix_weight_offset;
60 svm_unpack_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
61 const float mix_weight = (stack_valid(mix_weight_offset) ?
62 stack_load_float(stack, mix_weight_offset) :
63 1.0f);
64
65 /* note we read this extra node before weight check, so offset is added */
66 const uint4 data_node = read_node(kg, &offset);
67
68 /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
70 {
71 if ((shader_type != SHADER_TYPE_SURFACE) || mix_weight == 0.0f) {
72 return svm_node_closure_bsdf_skip(kg, offset, type);
73 }
74 }
75 else IF_KERNEL_NODES_FEATURE(EMISSION) {
76 if (type != CLOSURE_BSDF_PRINCIPLED_ID) {
77 /* Only principled BSDF can have emission. */
78 return svm_node_closure_bsdf_skip(kg, offset, type);
79 }
80 }
81 else {
82 return svm_node_closure_bsdf_skip(kg, offset, type);
83 }
84
85 float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N;
86 N = safe_normalize_fallback(N, sd->N);
87
88 const float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) :
89 __uint_as_float(node.z);
90 const float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) :
91 __uint_as_float(node.w);
92
93 switch (type) {
95 uint specular_ior_level_offset;
96 uint roughness_offset;
97 uint specular_tint_offset;
98 uint anisotropic_offset;
99 uint sheen_weight_offset;
100 uint sheen_tint_offset;
101 uint sheen_roughness_offset;
102 uint coat_weight_offset;
103 uint coat_roughness_offset;
104 uint coat_ior_offset;
105 uint eta_offset;
106 uint transmission_weight_offset;
107 uint anisotropic_rotation_offset;
108 uint coat_tint_offset;
109 uint coat_normal_offset;
110 uint alpha_offset;
111 uint emission_strength_offset;
112 uint emission_offset;
113 uint thinfilm_thickness_offset;
114 uint diffuse_roughness_offset;
115 const uint4 data_node2 = read_node(kg, &offset);
116
117 float3 T = stack_load_float3(stack, data_node.y);
118 svm_unpack_node_uchar4(data_node.z,
119 &specular_ior_level_offset,
120 &roughness_offset,
121 &specular_tint_offset,
122 &anisotropic_offset);
123 svm_unpack_node_uchar4(data_node.w,
124 &sheen_weight_offset,
125 &sheen_tint_offset,
126 &sheen_roughness_offset,
127 &diffuse_roughness_offset);
128 svm_unpack_node_uchar4(data_node2.x,
129 &eta_offset,
130 &transmission_weight_offset,
131 &anisotropic_rotation_offset,
132 &coat_normal_offset);
133 svm_unpack_node_uchar4(data_node2.w,
134 &coat_weight_offset,
135 &coat_roughness_offset,
136 &coat_ior_offset,
137 &coat_tint_offset);
138
139 // get Disney principled parameters
140 const float metallic = saturatef(param1);
141#ifdef __SUBSURFACE__
142 const float subsurface_weight = saturatef(param2);
143#else
144 const float subsurface_weight = 0.0f;
145#endif
146 const float specular_ior_level = max(stack_load_float(stack, specular_ior_level_offset),
147 0.0f);
148 const float roughness = saturatef(stack_load_float(stack, roughness_offset));
149 const Spectrum specular_tint = rgb_to_spectrum(
150 max(stack_load_float3(stack, specular_tint_offset), zero_float3()));
151 const float anisotropic = saturatef(stack_load_float(stack, anisotropic_offset));
152 const float sheen_weight = max(stack_load_float(stack, sheen_weight_offset), 0.0f);
153 const float3 sheen_tint = max(stack_load_float3(stack, sheen_tint_offset), zero_float3());
154 const float sheen_roughness = saturatef(stack_load_float(stack, sheen_roughness_offset));
155 const float coat_weight = fmaxf(stack_load_float(stack, coat_weight_offset), 0.0f);
156 const float coat_roughness = saturatef(stack_load_float(stack, coat_roughness_offset));
157 const float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f);
158 const float3 coat_tint = max(stack_load_float3(stack, coat_tint_offset), zero_float3());
159 const float transmission_weight = saturatef(
160 stack_load_float(stack, transmission_weight_offset));
161 const float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
162 const float ior = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
163
164 const ClosureType distribution = (ClosureType)data_node2.y;
165#ifdef __SUBSURFACE__
166 const ClosureType subsurface_method = (ClosureType)data_node2.z;
167#endif
168
169 const float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
170 float3 coat_normal = stack_valid(coat_normal_offset) ?
171 stack_load_float3(stack, coat_normal_offset) :
172 sd->N;
173 coat_normal = safe_normalize_fallback(coat_normal, sd->N);
174
175 // get the base color
176 const uint4 data_base_color = read_node(kg, &offset);
177 float3 base_color = stack_valid(data_base_color.x) ?
178 stack_load_float3(stack, data_base_color.x) :
179 make_float3(__uint_as_float(data_base_color.y),
180 __uint_as_float(data_base_color.z),
181 __uint_as_float(data_base_color.w));
182 base_color = max(base_color, zero_float3());
183 const float3 clamped_base_color = min(base_color, one_float3());
184
185 // get the subsurface scattering data
186 const uint4 data_subsurf = read_node(kg, &offset);
187
188 const uint4 data_alpha_emission_thin = read_node(kg, &offset);
189 svm_unpack_node_uchar4(data_alpha_emission_thin.x,
190 &alpha_offset,
191 &emission_strength_offset,
192 &emission_offset,
193 &thinfilm_thickness_offset);
194 float alpha = stack_valid(alpha_offset) ? stack_load_float(stack, alpha_offset) :
195 __uint_as_float(data_alpha_emission_thin.y);
196 alpha = saturatef(alpha);
197
198 const float emission_strength = stack_valid(emission_strength_offset) ?
199 stack_load_float(stack, emission_strength_offset) :
200 __uint_as_float(data_alpha_emission_thin.z);
201 const float3 emission = stack_load_float3(stack, emission_offset) * emission_strength;
202
203 const float thinfilm_thickness = fmaxf(stack_load_float(stack, thinfilm_thickness_offset),
204 1e-5f);
205 const float thinfilm_ior = fmaxf(stack_load_float(stack, data_alpha_emission_thin.w), 1e-5f);
206
207 Spectrum weight = closure_weight * mix_weight;
208
209 float alpha_x = sqr(roughness);
210 float alpha_y = sqr(roughness);
211 if (anisotropic > 0.0f) {
212 const float aspect = sqrtf(1.0f - anisotropic * 0.9f);
213 alpha_x /= aspect;
214 alpha_y *= aspect;
215 if (anisotropic_rotation != 0.0f) {
216 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
217 }
218 }
219
220#ifdef __CAUSTICS_TRICKS__
221 const bool reflective_caustics = (kernel_data.integrator.caustics_reflective ||
222 (path_flag & PATH_RAY_DIFFUSE) == 0);
223 const bool refractive_caustics = (kernel_data.integrator.caustics_refractive ||
224 (path_flag & PATH_RAY_DIFFUSE) == 0);
225#else
226 const bool reflective_caustics = true;
227 const bool refractive_caustics = true;
228#endif
229
230 /* Before any actual shader components, apply transparency. */
231 if (alpha < 1.0f) {
232 bsdf_transparent_setup(sd, weight * (1.0f - alpha), path_flag);
233 weight *= alpha;
234 }
235
236 /* First layer: Sheen */
237 if (sheen_weight > CLOSURE_WEIGHT_CUTOFF) {
239 sd, sizeof(SheenBsdf), sheen_weight * rgb_to_spectrum(sheen_tint) * weight);
240
241 if (bsdf) {
242 bsdf->N = safe_normalize(mix(N, coat_normal, saturatef(coat_weight)));
243 bsdf->roughness = sheen_roughness;
244
245 /* setup bsdf */
246 const int sheen_flag = bsdf_sheen_setup(kg, sd, bsdf);
247
248 if (sheen_flag) {
249 sd->flag |= sheen_flag;
250
251 /* Attenuate lower layers */
252 const Spectrum albedo = bsdf_albedo(
253 kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
254 weight = closure_layering_weight(albedo, weight);
255 }
256 }
257 }
258
259 /* Second layer: Coat */
260 if (coat_weight > CLOSURE_WEIGHT_CUTOFF) {
261 coat_normal = maybe_ensure_valid_specular_reflection(sd, coat_normal);
262 if (reflective_caustics) {
264 sd, sizeof(MicrofacetBsdf), coat_weight * weight);
265
266 if (bsdf) {
267 bsdf->N = coat_normal;
268 bsdf->T = zero_float3();
269 bsdf->ior = coat_ior;
270
271 bsdf->alpha_x = bsdf->alpha_y = sqr(coat_roughness);
272
273 /* setup bsdf */
274 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
276
277 /* Attenuate lower layers */
278 const Spectrum albedo = bsdf_albedo(
279 kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
280 weight = closure_layering_weight(albedo, weight);
281 }
282 }
283
284 if (!isequal(coat_tint, one_float3())) {
285 /* Tint is normalized to perpendicular incidence.
286 * Therefore, if we define the coat thickness as length 1, the length along the ray is
287 * t = sqrt(1+tan^2(angle(N, I))) = sqrt(1+tan^2(acos(dotNI))) = 1 / dotNI.
288 * From Beer's law, we have T = exp(-sigma_e * t).
289 * Therefore, tint = exp(-sigma_e * 1) (per def.), so -sigma_e = log(tint).
290 * From this, T = exp(log(tint) * t) = exp(log(tint)) ^ t = tint ^ t;
291 *
292 * Note that this is only an approximation - it assumes that the outgoing ray
293 * follows the same angle, and that there aren't multiple internal bounces.
294 * In particular, things that could be improved:
295 * - For transmissive materials, there should not be an outgoing path at all if the path
296 * is transmitted.
297 * - For rough materials, we could blend towards a view-independent average path length
298 * (e.g. 2 for diffuse reflection) for the outgoing direction.
299 * However, there's also an argument to be made for keeping parameters independent of
300 * each other for more intuitive control, in particular main roughness not affecting the
301 * coat.
302 */
303 const float cosNI = dot(sd->wi, coat_normal);
304 /* Refract incoming direction into coat material.
305 * TIR is no concern here since we're always coming from the outside. */
306 const float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI)));
307 const float optical_depth = 1.0f / cosNT;
308 weight *= mix(
309 one_spectrum(), power(rgb_to_spectrum(coat_tint), optical_depth), coat_weight);
310 }
311 }
312
313 /* Emission (attenuated by sheen and coat) */
314 if (!is_zero(emission)) {
315 emission_setup(sd, rgb_to_spectrum(emission) * weight);
316 }
317
318 /* Metallic component */
319 if (metallic > CLOSURE_WEIGHT_CUTOFF) {
320 if (reflective_caustics) {
322 sd, sizeof(MicrofacetBsdf), metallic * weight);
323 ccl_private FresnelF82Tint *fresnel =
324 (bsdf != nullptr) ?
326 nullptr;
327
328 if (bsdf && fresnel) {
329 bsdf->N = valid_reflection_N;
330 bsdf->ior = 1.0f;
331 bsdf->T = T;
332 bsdf->alpha_x = alpha_x;
333 bsdf->alpha_y = alpha_y;
334
335 fresnel->f0 = rgb_to_spectrum(clamped_base_color);
336 const Spectrum f82 = min(specular_tint, one_spectrum());
337
338 /* setup bsdf */
339 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
340 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
341 bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
342 }
343 }
344 /* Attenuate other components */
345 weight *= (1.0f - metallic);
346 }
347
348 /* Transmission component */
349 if (transmission_weight > CLOSURE_WEIGHT_CUTOFF) {
350 if (reflective_caustics || refractive_caustics) {
352 sd, sizeof(MicrofacetBsdf), transmission_weight * weight);
355 sd, sizeof(FresnelGeneralizedSchlick)) :
356 nullptr;
357
358 if (bsdf && fresnel) {
359 bsdf->N = valid_reflection_N;
360 bsdf->T = zero_float3();
361
362 bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
363 bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
364
365 fresnel->f0 = make_float3(F0_from_ior(ior)) * specular_tint;
366 fresnel->f90 = one_spectrum();
367 fresnel->exponent = -ior;
368 fresnel->reflection_tint = reflective_caustics ? one_spectrum() : zero_spectrum();
369 fresnel->transmission_tint = refractive_caustics ?
370 sqrt(rgb_to_spectrum(clamped_base_color)) :
372 fresnel->thin_film.thickness = thinfilm_thickness;
373 fresnel->thin_film.ior = (sd->flag & SD_BACKFACING) ? thinfilm_ior / ior :
374 thinfilm_ior;
375
376 /* setup bsdf */
377 sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
378 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
379 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
380 }
381 }
382 /* Attenuate other components */
383 weight *= (1.0f - transmission_weight);
384 }
385
386 /* Apply IOR adjustment */
387 float eta = ior;
388 float f0 = F0_from_ior(eta);
389 if (specular_ior_level != 0.5f) {
390 f0 *= 2.0f * specular_ior_level;
391 eta = ior_from_F0(f0);
392 if (ior < 1.0f) {
393 eta = 1.0f / eta;
394 }
395 }
396
397 /* Specular component */
398 if (reflective_caustics && (eta != 1.0f || thinfilm_thickness > 0.1f)) {
400 sd, sizeof(MicrofacetBsdf), weight);
403 sd, sizeof(FresnelGeneralizedSchlick)) :
404 nullptr;
405
406 if (bsdf && fresnel) {
407 bsdf->N = valid_reflection_N;
408 bsdf->ior = eta;
409 bsdf->T = T;
410 bsdf->alpha_x = alpha_x;
411 bsdf->alpha_y = alpha_y;
412
413 fresnel->f0 = f0 * specular_tint;
414 fresnel->f90 = one_spectrum();
415 fresnel->exponent = -eta;
416 fresnel->reflection_tint = one_spectrum();
417 fresnel->transmission_tint = zero_spectrum();
418 fresnel->thin_film.thickness = thinfilm_thickness;
419 fresnel->thin_film.ior = thinfilm_ior;
420
421 /* setup bsdf */
422 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
423 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
424 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
425
426 /* Attenuate lower layers */
427 const Spectrum albedo = bsdf_albedo(
428 kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
429 weight = closure_layering_weight(albedo, weight);
430 }
431 }
432
433 /* Diffuse/Subsurface component */
434#ifdef __SUBSURFACE__
436 sd, rgb_to_spectrum(clamped_base_color) * subsurface_weight * weight);
437 if (bssrdf) {
438 const float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y);
439 const float subsurface_scale = stack_load_float(stack, data_subsurf.z);
440
441 bssrdf->radius = rgb_to_spectrum(max(subsurface_radius * subsurface_scale, zero_float3()));
442 bssrdf->albedo = rgb_to_spectrum(clamped_base_color);
444 bssrdf->alpha = sqr(roughness);
445 /* IOR is clamped to [1.01..3.8] inside bssrdf_setup */
446 bssrdf->ior = eta;
447 /* Anisotropy is clamped to [0.0..0.9] inside bssrdf_setup */
448 bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w);
449 if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
450 bssrdf->ior = stack_load_float(stack, data_subsurf.x);
451 }
452
453 /* setup bsdf */
454 sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, subsurface_method);
455 }
456#else
457 (void)data_subsurf;
458#endif
459
461 sd,
462 sizeof(OrenNayarBsdf),
463 rgb_to_spectrum(base_color) * (1.0f - subsurface_weight) * weight);
464 if (bsdf) {
465 bsdf->N = N;
466
467 const float diffuse_roughness = saturatef(
468 stack_load_float(stack, diffuse_roughness_offset));
469 /* setup bsdf */
470 if (diffuse_roughness < CLOSURE_WEIGHT_CUTOFF) {
471 sd->flag |= bsdf_diffuse_setup((ccl_private DiffuseBsdf *)bsdf);
472 }
473 else {
474 bsdf->roughness = diffuse_roughness;
475 sd->flag |= bsdf_oren_nayar_setup(sd, bsdf, rgb_to_spectrum(base_color));
476 }
477 }
478
479 break;
480 }
482 const Spectrum weight = closure_weight * mix_weight;
484 sd, sizeof(OrenNayarBsdf), weight);
485
486 if (bsdf) {
487 bsdf->N = N;
488
489 const float roughness = param1;
490
491 if (roughness == 0.0f) {
492 sd->flag |= bsdf_diffuse_setup((ccl_private DiffuseBsdf *)bsdf);
493 }
494 else {
495 bsdf->roughness = roughness;
496 const Spectrum color = saturate(rgb_to_spectrum(stack_load_float3(stack, data_node.y)));
497 sd->flag |= bsdf_oren_nayar_setup(sd, bsdf, color);
498 }
499 }
500 break;
501 }
503 const Spectrum weight = closure_weight * mix_weight;
505 sd, sizeof(DiffuseBsdf), weight);
506
507 if (bsdf) {
509 sd->flag |= bsdf_translucent_setup(bsdf);
510 }
511 break;
512 }
514 const Spectrum weight = closure_weight * mix_weight;
515 bsdf_transparent_setup(sd, weight, path_flag);
516 break;
517 }
520#ifdef __CAUSTICS_TRICKS__
521 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) {
522 break;
523 }
524#endif
527
528 if (bsdf != nullptr) {
529 uint base_ior_offset;
530 uint edge_tint_k_offset;
531 uint rotation_offset;
532 uint tangent_offset;
534 node.z, &base_ior_offset, &edge_tint_k_offset, &rotation_offset, &tangent_offset);
535
536 const float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
537 float3 T = stack_load_float3(stack, tangent_offset);
538 const float anisotropy = saturatef(param2);
539 const float roughness = saturatef(param1);
540 float alpha_x = sqr(roughness);
541 float alpha_y = sqr(roughness);
542 if (anisotropy > 0.0f) {
543 const float aspect = sqrtf(1.0f - anisotropy * 0.9f);
544 alpha_x /= aspect;
545 alpha_y *= aspect;
546 const float anisotropic_rotation = stack_load_float(stack, rotation_offset);
547 if (anisotropic_rotation != 0.0f) {
548 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
549 }
550 }
551
552 bsdf->N = valid_reflection_N;
553 bsdf->ior = 1.0f;
554 bsdf->T = T;
555 bsdf->alpha_x = alpha_x;
556 bsdf->alpha_y = alpha_y;
557
558 const ClosureType distribution = (ClosureType)node.w;
559 /* Setup BSDF */
560 if (distribution == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) {
561 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
562 }
563 else {
564 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
565 }
566
567 const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
568
572
573 const float3 n = max(stack_load_float3(stack, base_ior_offset), zero_float3());
574 const float3 k = max(stack_load_float3(stack, edge_tint_k_offset), zero_float3());
575
576 fresnel->n = rgb_to_spectrum(n);
577 fresnel->k = rgb_to_spectrum(k);
578 bsdf_microfacet_setup_fresnel_conductor(kg, bsdf, sd, fresnel, is_multiggx);
579 }
580 else {
582 sd, sizeof(FresnelF82Tint));
583
584 const float3 color = saturate(stack_load_float3(stack, base_ior_offset));
585 const float3 tint = saturate(stack_load_float3(stack, edge_tint_k_offset));
586
587 fresnel->f0 = rgb_to_spectrum(color);
588 const Spectrum f82 = rgb_to_spectrum(tint);
589 bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
590 }
591 }
592 break;
593 }
595 const Spectrum weight = closure_weight * mix_weight;
596 const float3 position = stack_load_float3(stack, data_node.y);
597 const float3 direction = stack_load_float3(stack, data_node.z);
598 bsdf_ray_portal_setup(sd, weight, path_flag, position, direction);
599 break;
600 }
605#ifdef __CAUSTICS_TRICKS__
606 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) {
607 break;
608 }
609#endif
610 const Spectrum weight = closure_weight * mix_weight;
612 sd, sizeof(MicrofacetBsdf), weight);
613
614 if (!bsdf) {
615 break;
616 }
617
618 const float roughness = sqr(saturatef(param1));
619
621 bsdf->ior = 1.0f;
622
623 /* compute roughness */
624 const float anisotropy = clamp(param2, -0.99f, 0.99f);
625 if (data_node.w == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) {
626 /* Isotropic case. */
627 bsdf->T = zero_float3();
628 bsdf->alpha_x = roughness;
629 bsdf->alpha_y = roughness;
630 }
631 else {
632 bsdf->T = stack_load_float3(stack, data_node.w);
633
634 /* rotate tangent */
635 const float rotation = stack_load_float(stack, data_node.y);
636 if (rotation != 0.0f) {
637 bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
638 }
639
640 if (anisotropy < 0.0f) {
641 bsdf->alpha_x = roughness / (1.0f + anisotropy);
642 bsdf->alpha_y = roughness * (1.0f + anisotropy);
643 }
644 else {
645 bsdf->alpha_x = roughness * (1.0f - anisotropy);
646 bsdf->alpha_y = roughness / (1.0f - anisotropy);
647 }
648 }
649
650 /* setup bsdf */
652 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
653 }
654 else if (type == CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) {
655 sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
656 }
657 else {
658 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
660 kernel_assert(stack_valid(data_node.z));
661 const Spectrum color = max(rgb_to_spectrum(stack_load_float3(stack, data_node.z)),
662 zero_spectrum());
663 bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
664 }
665 }
666
667 break;
668 }
671#ifdef __CAUSTICS_TRICKS__
672 if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) {
673 break;
674 }
675#endif
676 const Spectrum weight = closure_weight * mix_weight;
678 sd, sizeof(MicrofacetBsdf), weight);
679
680 if (bsdf) {
682 bsdf->T = zero_float3();
683
684 float eta = fmaxf(param2, 1e-5f);
685 eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
686
687 /* setup bsdf */
688 const float roughness = sqr(param1);
689 bsdf->alpha_x = roughness;
690 bsdf->alpha_y = roughness;
691 bsdf->ior = eta;
692
695 }
696 else {
697 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
698 }
699 }
700
701 break;
702 }
706#ifdef __CAUSTICS_TRICKS__
707 const bool reflective_caustics = (kernel_data.integrator.caustics_reflective ||
708 (path_flag & PATH_RAY_DIFFUSE) == 0);
709 const bool refractive_caustics = (kernel_data.integrator.caustics_refractive ||
710 (path_flag & PATH_RAY_DIFFUSE) == 0);
711 if (!(reflective_caustics || refractive_caustics)) {
712 break;
713 }
714#else
715 const bool reflective_caustics = true;
716 const bool refractive_caustics = true;
717#endif
722 sd, sizeof(FresnelGeneralizedSchlick)) :
723 nullptr;
724
725 if (bsdf && fresnel) {
727 bsdf->T = zero_float3();
728
729 const float ior = fmaxf(param2, 1e-5f);
730 bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
731 bsdf->alpha_x = bsdf->alpha_y = sqr(saturatef(param1));
732
733 fresnel->f0 = make_float3(F0_from_ior(ior));
734 fresnel->f90 = one_spectrum();
735 fresnel->exponent = -ior;
736 const float3 color = max(stack_load_float3(stack, data_node.y), zero_float3());
737 fresnel->reflection_tint = reflective_caustics ? rgb_to_spectrum(color) : zero_spectrum();
738 fresnel->transmission_tint = refractive_caustics ? rgb_to_spectrum(color) :
740 fresnel->thin_film.thickness = 0.0f;
741 fresnel->thin_film.ior = 0.0f;
742
743 /* setup bsdf */
745 sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf);
746 }
747 else {
748 sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
749 }
750 const bool is_multiggx = (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
751 bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
752 }
753 break;
754 }
756 const Spectrum weight = closure_weight * mix_weight;
758 sd, sizeof(VelvetBsdf), weight);
759
760 if (bsdf) {
761 bsdf->N = N;
762
763 bsdf->sigma = saturatef(param1);
764 sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
765 }
766 break;
767 }
769 const Spectrum weight = closure_weight * mix_weight;
771 sd, sizeof(SheenBsdf), weight);
772
773 if (bsdf) {
774 bsdf->N = N;
775 bsdf->roughness = saturatef(param1);
776
777 sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
778 }
779 break;
780 }
782#ifdef __CAUSTICS_TRICKS__
783 if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) {
784 break;
785 }
787#endif
789 const Spectrum weight = closure_weight * mix_weight;
791 sd, sizeof(ToonBsdf), weight);
792
793 if (bsdf) {
794 bsdf->N = N;
795 bsdf->size = param1;
796 bsdf->smooth = param2;
797
798 if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID) {
799 sd->flag |= bsdf_diffuse_toon_setup(bsdf);
800 }
801 else {
802 sd->flag |= bsdf_glossy_toon_setup(bsdf);
803 }
804 }
805 break;
806 }
807#ifdef __HAIR__
808# ifdef __PRINCIPLED_HAIR__
811 const uint4 data_node2 = read_node(kg, &offset);
812 const uint4 data_node3 = read_node(kg, &offset);
813 const uint4 data_node4 = read_node(kg, &offset);
814
815 const Spectrum weight = closure_weight * mix_weight;
816
817 uint offset_ofs;
818 uint ior_ofs;
819 uint color_ofs;
820 uint parametrization;
821 svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, &parametrization);
822 const float alpha = stack_load_float_default(stack, offset_ofs, data_node.z);
823 const float ior = stack_load_float_default(stack, ior_ofs, data_node.w);
824
825 uint tint_ofs;
826 uint melanin_ofs;
827 uint melanin_redness_ofs;
828 uint absorption_coefficient_ofs;
829 svm_unpack_node_uchar4(data_node2.x,
830 &tint_ofs,
831 &melanin_ofs,
832 &melanin_redness_ofs,
833 &absorption_coefficient_ofs);
834
835 uint shared_ofs1;
836 uint random_ofs;
837 uint random_color_ofs;
838 uint shared_ofs2;
840 data_node3.x, &shared_ofs1, &random_ofs, &random_color_ofs, &shared_ofs2);
841
842 const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node2.y);
843 float random = 0.0f;
844 if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) {
845 random = primitive_surface_attribute<float>(kg, sd, attr_descr_random, nullptr, nullptr);
846 }
847 else {
848 random = stack_load_float_default(stack, random_ofs, data_node3.y);
849 }
850
851 /* Random factors range: [-randomization/2, +randomization/2]. */
852 const float random_roughness = param2;
853 const float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness;
854 const float roughness = param1 * factor_random_roughness;
855 const float radial_roughness = (type == CLOSURE_BSDF_HAIR_CHIANG_ID) ?
857 stack, shared_ofs2, data_node4.y) *
858 factor_random_roughness :
859 roughness;
860
861 Spectrum sigma;
862 switch (parametrization) {
864 const float3 absorption_coefficient = stack_load_float3(stack,
865 absorption_coefficient_ofs);
866 sigma = rgb_to_spectrum(absorption_coefficient);
867 break;
868 }
870 float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z);
871 const float melanin_redness = stack_load_float_default(
872 stack, melanin_redness_ofs, data_node2.w);
873
874 /* Randomize melanin. */
875 float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
876 random_color = clamp(random_color, 0.0f, 1.0f);
877 const float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;
878 melanin *= factor_random_color;
879
880 /* Map melanin 0..inf from more perceptually linear 0..1. */
881 melanin = -logf(fmaxf(1.0f - melanin, 0.0001f));
882
883 /* Benedikt Bitterli's melanin ratio remapping. */
884 const float eumelanin = melanin * (1.0f - melanin_redness);
885 const float pheomelanin = melanin * melanin_redness;
887 eumelanin, pheomelanin);
888
889 /* Optional tint. */
890 const float3 tint = stack_load_float3(stack, tint_ofs);
892 rgb_to_spectrum(tint), radial_roughness);
893
894 sigma = melanin_sigma + tint_sigma;
895 break;
896 }
898 const float3 color = stack_load_float3(stack, color_ofs);
900 radial_roughness);
901 break;
902 }
903 default: {
904 /* Fallback to brownish hair, same as defaults for melanin. */
905 kernel_assert(!"Invalid Hair parametrization!");
906 sigma = bsdf_principled_hair_sigma_from_concentration(0.0f, 0.8054375f);
907 break;
908 }
909 }
910
911 if (type == CLOSURE_BSDF_HAIR_CHIANG_ID) {
913 sd, sizeof(ChiangHairBSDF), weight);
914 if (bsdf) {
915 /* Remap Coat value to [0, 100]% of Roughness. */
916 const float coat = stack_load_float_default(stack, shared_ofs1, data_node3.w);
917 const float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
918
919 bsdf->v = roughness;
920 bsdf->s = radial_roughness;
921 bsdf->m0_roughness = m0_roughness;
922 bsdf->alpha = alpha;
923 bsdf->eta = ior;
924 bsdf->sigma = sigma;
925
926 sd->flag |= bsdf_hair_chiang_setup(sd, bsdf);
927 }
928 }
929 else {
931 uint R_ofs;
932 uint TT_ofs;
933 uint TRT_ofs;
934 uint unused;
935 svm_unpack_node_uchar4(data_node4.x, &R_ofs, &TT_ofs, &TRT_ofs, &unused);
936 const float R = stack_load_float_default(stack, R_ofs, data_node4.y);
937 const float TT = stack_load_float_default(stack, TT_ofs, data_node4.z);
938 const float TRT = stack_load_float_default(stack, TRT_ofs, data_node4.w);
939 if (R <= 0.0f && TT <= 0.0f && TRT <= 0.0f) {
940 break;
941 }
942
944 sd, sizeof(HuangHairBSDF), weight);
945 if (bsdf) {
947 sd, sizeof(HuangHairExtra));
948
949 if (!extra) {
950 break;
951 }
952
953 bsdf->extra = extra;
954 bsdf->extra->R = fmaxf(0.0f, R);
955 bsdf->extra->TT = fmaxf(0.0f, TT);
956 bsdf->extra->TRT = fmaxf(0.0f, TRT);
957
958 bsdf->extra->pixel_coverage = 1.0f;
959
960 /* For camera ray, check if the hair covers more than one pixel, in which case a
961 * nearfield model is needed to prevent ribbon-like appearance. */
962 if ((path_flag & PATH_RAY_CAMERA) && (sd->type & PRIMITIVE_CURVE)) {
963 /* Interpolate radius between curve keys. */
964 const KernelCurve kcurve = kernel_data_fetch(curves, sd->prim);
965 const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
966 const int k1 = k0 + 1;
967 const float radius = mix(
968 kernel_data_fetch(curve_keys, k0).w, kernel_data_fetch(curve_keys, k1).w, sd->u);
969
970 bsdf->extra->pixel_coverage = 0.5f * sd->dP / radius;
971 }
972
973 bsdf->aspect_ratio = stack_load_float_default(stack, shared_ofs1, data_node3.w);
974 if (bsdf->aspect_ratio != 1.0f) {
975 /* Align ellipse major axis with the curve normal direction. */
976 const AttributeDescriptor attr_descr_normal = find_attribute(kg, sd, shared_ofs2);
977 bsdf->N = curve_attribute<float3>(kg, sd, attr_descr_normal, nullptr, nullptr);
978 }
979
980 bsdf->roughness = roughness;
981 bsdf->tilt = alpha;
982 bsdf->eta = ior;
983 bsdf->sigma = sigma;
984
985 sd->flag |= bsdf_hair_huang_setup(sd, bsdf, path_flag);
986 }
987 }
988 break;
989 }
990# endif /* __PRINCIPLED_HAIR__ */
993 const Spectrum weight = closure_weight * mix_weight;
994
996 sd, sizeof(HairBsdf), weight);
997
998 if (bsdf) {
1000 bsdf->roughness1 = param1;
1001 bsdf->roughness2 = param2;
1002 bsdf->offset = -stack_load_float(stack, data_node.y);
1003
1004 if (stack_valid(data_node.w)) {
1005 bsdf->T = normalize(stack_load_float3(stack, data_node.w));
1006 }
1007 else if (!(sd->type & PRIMITIVE_CURVE)) {
1008 bsdf->T = normalize(sd->dPdv);
1009 bsdf->offset = 0.0f;
1010 }
1011 else {
1012 bsdf->T = normalize(sd->dPdu);
1013 }
1014
1015 if (type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
1016 sd->flag |= bsdf_hair_reflection_setup(bsdf);
1017 }
1018 else {
1019 sd->flag |= bsdf_hair_transmission_setup(bsdf);
1020 }
1021 }
1022
1023 break;
1024 }
1025#endif /* __HAIR__ */
1026
1027#ifdef __SUBSURFACE__
1031 const Spectrum weight = closure_weight * mix_weight;
1032 ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
1033
1034 if (bssrdf) {
1035 bssrdf->radius = max(rgb_to_spectrum(stack_load_float3(stack, data_node.y) * param1),
1036 zero_spectrum());
1037 bssrdf->albedo = closure_weight;
1039 bssrdf->ior = param2;
1040 bssrdf->alpha = saturatef(stack_load_float(stack, data_node.w));
1041 bssrdf->anisotropy = stack_load_float(stack, data_node.z);
1042
1043 sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, (ClosureType)type);
1044 }
1045
1046 break;
1047 }
1048#endif
1049 default:
1050 break;
1051 }
1052
1053 return offset;
1054}
1055
1057 ccl_private float *stack,
1058 Spectrum weight,
1059 const uint type,
1060 const uint param1_offset,
1061 const uint param_extra)
1062{
1063 switch (type) {
1066 bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
1067 if (volume) {
1068 volume->g = stack_valid(param1_offset) ? stack_load_float(stack, param1_offset) :
1069 __uint_as_float(param_extra);
1070 sd->flag |= volume_henyey_greenstein_setup(volume);
1071 }
1072 } break;
1075 sd, sizeof(FournierForandVolume), weight);
1076 if (volume) {
1077 const float IOR = stack_load_float(stack, param1_offset);
1078 const float B = stack_load_float(stack, param_extra);
1079 sd->flag |= volume_fournier_forand_setup(volume, B, IOR);
1080 }
1081 } break;
1084 sd, sizeof(RayleighVolume), weight);
1085 if (volume) {
1086 sd->flag |= volume_rayleigh_setup(volume);
1087 }
1088 break;
1089 }
1092 sd, sizeof(DraineVolume), weight);
1093 if (volume) {
1094 volume->g = stack_load_float(stack, param1_offset);
1095 volume->alpha = stack_load_float(stack, param_extra);
1096 sd->flag |= volume_draine_setup(volume);
1097 }
1098 } break;
1099 case CLOSURE_VOLUME_MIE_ID: {
1100 const float d = stack_valid(param1_offset) ? stack_load_float(stack, param1_offset) :
1101 __uint_as_float(param_extra);
1102 float g_HG;
1103 float g_D;
1104 float alpha;
1105 float mixture;
1106 phase_mie_fitted_parameters(d, &g_HG, &g_D, &alpha, &mixture);
1108 sd, sizeof(HenyeyGreensteinVolume), weight * (1.0f - mixture));
1109 if (hg) {
1110 hg->g = g_HG;
1111 sd->flag |= volume_henyey_greenstein_setup(hg);
1112 }
1114 sd, sizeof(DraineVolume), weight * mixture);
1115 if (draine) {
1116 draine->g = g_D;
1117 draine->alpha = alpha;
1118 sd->flag |= volume_draine_setup(draine);
1119 }
1120 } break;
1121 default: {
1122 kernel_assert(0);
1123 break;
1124 }
1125 }
1126}
1127
1128template<ShaderType shader_type>
1130 ccl_private ShaderData *sd,
1131 ccl_private float *stack,
1132 Spectrum closure_weight,
1133 const uint4 node)
1134{
1135#ifdef __VOLUME__
1136 /* Only sum extinction for volumes, variable is shared with surface transparency. */
1137 if (shader_type != SHADER_TYPE_VOLUME) {
1138 return;
1139 }
1140
1141 uint type;
1142 uint density_offset;
1143 uint param1_offset;
1144 uint mix_weight_offset;
1145 svm_unpack_node_uchar4(node.y, &type, &density_offset, &param1_offset, &mix_weight_offset);
1146 const float mix_weight = (stack_valid(mix_weight_offset) ?
1147 stack_load_float(stack, mix_weight_offset) :
1148 1.0f);
1149 if (mix_weight == 0.0f) {
1150 return;
1151 }
1152
1153 float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
1154 __uint_as_float(node.z);
1155 density = mix_weight * fmaxf(density, 0.0f) * object_volume_density(kg, sd->object);
1156
1157 /* Compute scattering coefficient. */
1158 Spectrum weight = closure_weight;
1159
1160 if (type == CLOSURE_VOLUME_ABSORPTION_ID) {
1161 weight = one_spectrum() - weight;
1162 }
1163
1164 weight *= density;
1165
1166 /* Add closure for volume scattering. */
1167 if (CLOSURE_IS_VOLUME_SCATTER(type)) {
1168 svm_alloc_closure_volume_scatter(sd, stack, weight, type, param1_offset, node.w);
1169 }
1170
1171 /* Sum total extinction weight. */
1172 volume_extinction_setup(sd, weight);
1173#endif
1174}
1175
1176template<ShaderType shader_type>
1178 ccl_private ShaderData *sd,
1179 ccl_private float *stack,
1180 Spectrum scatter_coeffs,
1181 const uint4 node,
1182 const uint32_t path_flag)
1183{
1184#ifdef __VOLUME__
1185 /* Only sum extinction for volumes, variable is shared with surface transparency. */
1186 if (shader_type != SHADER_TYPE_VOLUME) {
1187 return;
1188 }
1189
1190 uint type;
1191 uint empty_offset;
1192 uint param1_offset;
1193 uint mix_weight_offset;
1194 svm_unpack_node_uchar4(node.y, &type, &empty_offset, &param1_offset, &mix_weight_offset);
1195 const float mix_weight = (stack_valid(mix_weight_offset) ?
1196 stack_load_float(stack, mix_weight_offset) :
1197 1.0f);
1198 if (mix_weight == 0.0f) {
1199 return;
1200 }
1201
1202 /* Compute scattering coefficient. */
1203 const float weight = mix_weight * object_volume_density(kg, sd->object);
1204
1205 /* Add closure for volume scattering. */
1206 if (!is_zero(scatter_coeffs) && CLOSURE_IS_VOLUME_SCATTER(type)) {
1208 sd, stack, weight * scatter_coeffs, type, param1_offset, node.z);
1209 }
1210 uint absorption_coeffs_offset;
1211 uint emission_coeffs_offset;
1213 node.w, &absorption_coeffs_offset, &emission_coeffs_offset, &empty_offset, &empty_offset);
1214 const float3 absorption_coeffs = stack_load_float3(stack, absorption_coeffs_offset);
1215 volume_extinction_setup(sd, weight * (scatter_coeffs + absorption_coeffs));
1216
1217 const float3 emission_coeffs = stack_load_float3(stack, emission_coeffs_offset);
1218 /* Compute emission. */
1219 if (path_flag & PATH_RAY_SHADOW) {
1220 /* Don't need emission for shadows. */
1221 return;
1222 }
1223
1224 if (is_zero(emission_coeffs)) {
1225 return;
1226 }
1227 emission_setup(sd, weight * emission_coeffs);
1228
1229#endif
1230}
1231
1232template<ShaderType shader_type>
1234 ccl_private ShaderData *sd,
1235 ccl_private float *stack,
1236 const Spectrum closure_weight,
1237 const uint4 node,
1238 const uint32_t path_flag,
1239 int offset)
1240{
1241#ifdef __VOLUME__
1242 const uint4 value_node = read_node(kg, &offset);
1243 const uint4 attr_node = read_node(kg, &offset);
1244
1245 /* Only sum extinction for volumes, variable is shared with surface transparency. */
1246 if (shader_type != SHADER_TYPE_VOLUME) {
1247 return offset;
1248 }
1249
1250 uint density_offset;
1251 uint anisotropy_offset;
1252 uint absorption_color_offset;
1253 uint mix_weight_offset;
1255 node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset);
1256 const float mix_weight = (stack_valid(mix_weight_offset) ?
1257 stack_load_float(stack, mix_weight_offset) :
1258 1.0f);
1259
1260 if (mix_weight == 0.0f) {
1261 return offset;
1262 }
1263
1264 /* Compute density. */
1265 const float weight = mix_weight * object_volume_density(kg, sd->object);
1266 float primitive_density = 1.0f;
1267 float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) :
1268 __uint_as_float(value_node.x);
1269 density = weight * fmaxf(density, 0.0f);
1270
1271 if (density > 0.0f) {
1272 /* Density and color attribute lookup if available. */
1273 const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x);
1274 if (attr_density.offset != ATTR_STD_NOT_FOUND) {
1275 primitive_density = primitive_volume_attribute<float>(kg, sd, attr_density);
1276 density = fmaxf(density * primitive_density, 0.0f);
1277 }
1278 }
1279
1280 if (density > 0.0f) {
1281 /* Compute scattering color. */
1282 Spectrum color = closure_weight;
1283
1284 const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y);
1285 if (attr_color.offset != ATTR_STD_NOT_FOUND) {
1286 color *= rgb_to_spectrum(primitive_volume_attribute<float3>(kg, sd, attr_color));
1287 }
1288
1289 /* Add closure for volume scattering. */
1291 sd, sizeof(HenyeyGreensteinVolume), color * density);
1292 if (volume) {
1293 const float anisotropy = (stack_valid(anisotropy_offset)) ?
1294 stack_load_float(stack, anisotropy_offset) :
1295 __uint_as_float(value_node.y);
1296 volume->g = anisotropy;
1297 sd->flag |= volume_henyey_greenstein_setup(volume);
1298 }
1299
1300 /* Add extinction weight. */
1301 const float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)),
1302 zero_float3());
1303
1304 const Spectrum zero = zero_spectrum();
1305 const Spectrum one = one_spectrum();
1306 const Spectrum absorption = max(one - color, zero) *
1307 max(one - rgb_to_spectrum(absorption_color), zero);
1308 volume_extinction_setup(sd, (color + absorption) * density);
1309 }
1310
1311 /* Compute emission. */
1312 if (path_flag & PATH_RAY_SHADOW) {
1313 /* Don't need emission for shadows. */
1314 return offset;
1315 }
1316
1317 uint emission_offset;
1318 uint emission_color_offset;
1319 uint blackbody_offset;
1320 uint temperature_offset;
1322 node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset);
1323 const float emission = (stack_valid(emission_offset)) ?
1324 stack_load_float(stack, emission_offset) :
1325 __uint_as_float(value_node.z);
1326 const float blackbody = (stack_valid(blackbody_offset)) ?
1327 stack_load_float(stack, blackbody_offset) :
1328 __uint_as_float(value_node.w);
1329
1330 if (emission > 0.0f) {
1331 const float3 emission_color = stack_load_float3(stack, emission_color_offset);
1332 emission_setup(sd, rgb_to_spectrum(emission * emission_color * weight));
1333 }
1334
1335 if (blackbody > 0.0f) {
1336 float T = stack_load_float(stack, temperature_offset);
1337
1338 /* Add flame temperature from attribute if available. */
1339 const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z);
1340 if (attr_temperature.offset != ATTR_STD_NOT_FOUND) {
1341 const float temperature = primitive_volume_attribute<float>(kg, sd, attr_temperature);
1342 T *= fmaxf(temperature, 0.0f);
1343 }
1344
1345 T = fmaxf(T, 0.0f);
1346
1347 /* Stefan-Boltzmann law. */
1348 const float T4 = sqr(sqr(T));
1349 const float sigma = 5.670373e-8f * 1e-6f / M_PI_F;
1350 const float intensity = sigma * mix(1.0f, T4, blackbody);
1351
1352 if (intensity > 0.0f) {
1353 const float3 blackbody_tint = stack_load_float3(stack, node.w);
1354 const float3 bb = blackbody_tint * intensity *
1356 emission_setup(sd, rgb_to_spectrum(bb * weight));
1357 }
1358 }
1359#endif
1360 return offset;
1361}
1362
1364 ccl_private ShaderData *sd,
1365 ccl_private float *stack,
1366 Spectrum closure_weight,
1367 const uint4 node)
1368{
1369 const uint mix_weight_offset = node.y;
1370 Spectrum weight = closure_weight;
1371
1372 if (stack_valid(mix_weight_offset)) {
1373 const float mix_weight = stack_load_float(stack, mix_weight_offset);
1374
1375 if (mix_weight == 0.0f) {
1376 return;
1377 }
1378
1379 weight *= mix_weight;
1380 }
1381
1382 if (sd->flag & SD_IS_VOLUME_SHADER_EVAL) {
1383 weight *= object_volume_density(kg, sd->object);
1384 }
1385
1386 emission_setup(sd, weight);
1387}
1388
1390 ccl_private float *stack,
1391 Spectrum closure_weight,
1392 const uint4 node)
1393{
1394 const uint mix_weight_offset = node.y;
1395 Spectrum weight = closure_weight;
1396
1397 if (stack_valid(mix_weight_offset)) {
1398 const float mix_weight = stack_load_float(stack, mix_weight_offset);
1399
1400 if (mix_weight == 0.0f) {
1401 return;
1402 }
1403
1404 weight *= mix_weight;
1405 }
1406
1407 background_setup(sd, weight);
1408}
1409
1411 ccl_private float *stack,
1412 Spectrum closure_weight,
1413 const uint4 node)
1414{
1415 const uint mix_weight_offset = node.y;
1416
1417 if (stack_valid(mix_weight_offset)) {
1418 const float mix_weight = stack_load_float(stack, mix_weight_offset);
1419
1420 if (mix_weight == 0.0f) {
1421 return;
1422 }
1423
1424 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight * mix_weight);
1425 }
1426 else {
1427 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, closure_weight);
1428 }
1429
1430 sd->flag |= SD_HOLDOUT;
1431}
1432
1433/* Closure Nodes */
1434
1436 ccl_private Spectrum *closure_weight,
1437 const uint r,
1438 uint g,
1439 const uint b)
1440{
1441 *closure_weight = rgb_to_spectrum(
1443}
1444
1446 ccl_private float *stack,
1447 ccl_private Spectrum *closure_weight,
1448 const uint weight_offset)
1449{
1450 *closure_weight = rgb_to_spectrum(stack_load_float3(stack, weight_offset));
1451}
1452
1454 ccl_private ShaderData *sd,
1455 ccl_private float *stack,
1456 ccl_private Spectrum *closure_weight,
1457 const uint4 node)
1458{
1459 const uint color_offset = node.y;
1460 const uint strength_offset = node.z;
1461
1462 const float strength = stack_load_float(stack, strength_offset);
1463 *closure_weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength;
1464}
1465
1467 ccl_private float *stack,
1468 const uint4 node)
1469{
1470 /* fetch weight from blend input, previous mix closures,
1471 * and write to stack to be used by closure nodes later */
1472 uint weight_offset;
1473 uint in_weight_offset;
1474 uint weight1_offset;
1475 uint weight2_offset;
1477 node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
1478
1479 float weight = stack_load_float(stack, weight_offset);
1480 weight = saturatef(weight);
1481
1482 const float in_weight = (stack_valid(in_weight_offset)) ?
1483 stack_load_float(stack, in_weight_offset) :
1484 1.0f;
1485
1486 if (stack_valid(weight1_offset)) {
1487 stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight));
1488 }
1489 if (stack_valid(weight2_offset)) {
1490 stack_store_float(stack, weight2_offset, in_weight * weight);
1491 }
1492}
1493
1494/* (Bump) normal */
1495
1497 ccl_private ShaderData *sd,
1498 ccl_private float *stack,
1499 const uint in_direction,
1500 const uint out_normal)
1501{
1502 const float3 normal = stack_load_float3(stack, in_direction);
1503 sd->N = normal;
1504 stack_store_float3(stack, out_normal, normal);
1505}
1506
#define ATTR_FALLTHROUGH
unsigned int uint
static float mix_weight(float weight, float weight2, char mix_mode)
CCL_NAMESPACE_BEGIN ccl_device ccl_private ShaderClosure * closure_alloc(ccl_private ShaderData *sd, const int size, ClosureType type, Spectrum weight)
Definition alloc.h:11
ccl_device_inline ccl_private ShaderClosure * bsdf_alloc(ccl_private ShaderData *sd, const int size, Spectrum weight)
Definition alloc.h:55
ccl_device ccl_private void * closure_alloc_extra(ccl_private ShaderData *sd, const int size)
Definition alloc.h:34
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg, const ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const bool reflection, const bool transmission)
Definition bsdf.h:633
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:27
ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf)
Definition bsdf_hair.h:35
ccl_device void bsdf_microfacet_setup_fresnel_f82_tint(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, const ccl_private ShaderData *sd, ccl_private FresnelF82Tint *fresnel, const Spectrum f82_tint, const bool preserve_energy)
ccl_device int bsdf_microfacet_beckmann_glass_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_beckmann_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, const ccl_private ShaderData *sd, const Spectrum color)
ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, const ccl_private ShaderData *sd, ccl_private FresnelGeneralizedSchlick *fresnel, const bool preserve_energy)
ccl_device void bsdf_microfacet_setup_fresnel_dielectric(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, const ccl_private ShaderData *sd)
ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, const ccl_private ShaderData *sd, ccl_private FresnelConductor *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 int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_oren_nayar_setup(const ccl_private ShaderData *sd, ccl_private OrenNayarBsdf *bsdf, const Spectrum color)
ccl_device void bsdf_ray_portal_setup(ccl_private ShaderData *sd, const Spectrum weight, const uint32_t path_flag, const float3 position, float3 direction)
ccl_device int bsdf_sheen_setup(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private SheenBsdf *bsdf)
Definition bsdf_sheen.h:27
ccl_device int bsdf_diffuse_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:35
ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf)
Definition bsdf_toon.h:119
CCL_NAMESPACE_BEGIN ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, const Spectrum weight, const uint32_t path_flag)
ccl_device float3 maybe_ensure_valid_specular_reflection(ccl_private ShaderData *sd, const float3 N)
Definition bsdf_util.h:281
ccl_device float ior_from_F0(const float f0)
Definition bsdf_util.h:166
ccl_device float F0_from_ior(const float ior)
Definition bsdf_util.h:172
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
Definition bsdf_util.h:302
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin, const float pheomelanin)
Definition bsdf_util.h:309
ccl_device_inline Spectrum closure_layering_weight(const Spectrum layer_albedo, const Spectrum weight)
Definition bsdf_util.h:322
ccl_device_inline ccl_private Bssrdf * bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
Definition bssrdf.h:270
ccl_device int bssrdf_setup(ccl_private ShaderData *sd, ccl_private Bssrdf *bssrdf, const int path_flag, ClosureType type)
Definition bssrdf.h:288
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, const Spectrum closure_weight, const uint4 node, const uint32_t path_flag, int offset)
Definition closure.h:1233
ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, const uint4 node)
Definition closure.h:1410
ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, const uint4 node)
Definition closure.h:1389
ccl_device_noinline void svm_node_volume_coefficients(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum scatter_coeffs, const uint4 node, const uint32_t path_flag)
Definition closure.h:1177
ccl_device_inline void svm_alloc_closure_volume_scatter(ccl_private ShaderData *sd, ccl_private float *stack, Spectrum weight, const uint type, const uint param1_offset, const uint param_extra)
Definition closure.h:1056
ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd, ccl_private float *stack, ccl_private Spectrum *closure_weight, const uint weight_offset)
Definition closure.h:1445
ccl_device_noinline void svm_node_closure_emission(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, const uint4 node)
Definition closure.h:1363
ccl_device_noinline void svm_node_mix_closure(ccl_private ShaderData *sd, ccl_private float *stack, const uint4 node)
Definition closure.h:1466
ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, const uint4 node)
Definition closure.h:1129
ccl_device void svm_node_set_normal(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, const uint in_direction, const uint out_normal)
Definition closure.h:1496
CCL_NAMESPACE_BEGIN ccl_device_inline int svm_node_closure_bsdf_skip(KernelGlobals kg, int offset, const uint type)
Definition closure.h:27
ccl_device void svm_node_closure_set_weight(ccl_private ShaderData *sd, ccl_private Spectrum *closure_weight, const uint r, uint g, const uint b)
Definition closure.h:1435
ccl_device_noinline void svm_node_emission_weight(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, ccl_private Spectrum *closure_weight, const uint4 node)
Definition closure.h:1453
ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, Spectrum closure_weight, const uint4 node, const uint32_t path_flag, int offset)
Definition closure.h:47
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device_inline float stack_load_float(const ccl_private float *stack, const uint a)
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *const offset)
ccl_device_inline void stack_store_float3(ccl_private float *stack, const uint a, const float3 f)
ccl_device_inline float stack_load_float_default(const ccl_private float *stack, const uint a, const uint value)
ccl_device_forceinline void svm_unpack_node_uchar4(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(const uint a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(const ccl_private float *stack, const uint a)
#define kernel_assert(cond)
#define CLOSURE_IS_VOLUME_SCATTER(type)
#define kernel_data
#define IF_KERNEL_NODES_FEATURE(feature)
#define kernel_data_fetch(name, index)
#define one_spectrum
#define PRIMITIVE_UNPACK_SEGMENT(type)
#define ccl_device
#define zero_spectrum
#define M_2PI_F
#define make_spectrum(f)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define M_PI_F
#define SVM_STACK_INVALID
#define ccl_device_noinline
#define CLOSURE_WEIGHT_CUTOFF
#define logf(x)
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#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:29
CCL_NAMESPACE_BEGIN ccl_device void background_setup(ccl_private ShaderData *sd, const Spectrum weight)
Definition emissive.h:16
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
Definition frames.inl:1282
VecBase< float, D > normalize(VecOp< float, D >) RET
#define sqrt
constexpr T clamp(T, U, U) RET
#define mix(a, b, c)
Definition hash.h:35
CCL_NAMESPACE_BEGIN ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, Spectrum weight)
ccl_device_inline float object_volume_density(KernelGlobals kg, const int object)
@ NODE_PRINCIPLED_HAIR_REFLECTANCE
@ NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION
@ NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION
@ SHADER_TYPE_SURFACE
@ SHADER_TYPE_VOLUME
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
@ SD_IS_VOLUME_SHADER_EVAL
@ SD_BACKFACING
@ SD_HOLDOUT
@ PRIMITIVE_CURVE
@ ATTR_STD_NOT_FOUND
@ PATH_RAY_SHADOW
@ PATH_RAY_DIFFUSE
@ PATH_RAY_CAMERA
ccl_device float3 rec709_to_rgb(KernelGlobals kg, const float3 rec709)
ccl_device_inline Spectrum rgb_to_spectrum(const float3 rgb)
ccl_device_inline float sqr(const float a)
Definition math_base.h:600
ccl_device_inline float2 power(const float2 v, const float e)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
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_inline float3 rotate_around_axis(const float3 p, const float3 axis, const float angle)
ccl_device float3 svm_math_blackbody_color_rec709(const float t)
Definition math_util.h:207
#define N
#define T
#define B
#define R
#define T4
Definition md5.cpp:22
CCL_NAMESPACE_BEGIN ccl_device_forceinline T primitive_surface_attribute(KernelGlobals kg, const ccl_private ShaderData *sd, const AttributeDescriptor desc, ccl_private T *dfdx, ccl_private T *dfdy)
Definition primitive.h:32
#define saturate(a)
Definition smaa.cc:315
#define min(a, b)
Definition sort.cc:36
closure color absorption() BUILTIN
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN
closure color draine(float g, float alpha) BUILTIN
static bool find_attribute(const std::string &attributes, const char *search_attribute)
uint x
Definition types_uint4.h:13
uint y
Definition types_uint4.h:13
uint z
Definition types_uint4.h:13
uint w
Definition types_uint4.h:13
max
Definition text_draw.cc:251
float3 Spectrum
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)
ccl_device void phase_mie_fitted_parameters(float d, ccl_private float *g_HG, ccl_private float *g_D, ccl_private float *alpha, ccl_private float *w)