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