7fc96f7e47f1b3a87b72035d7be396561396d75c
[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 /* Closure Nodes */
20
21 ccl_device void svm_node_glass_setup(ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract)
22 {
23         if(type == CLOSURE_BSDF_SHARP_GLASS_ID) {
24                 if(refract) {
25                         bsdf->alpha_y = 0.0f;
26                         bsdf->alpha_x = 0.0f;
27                         bsdf->ior = eta;
28                         sd->flag |= bsdf_refraction_setup(bsdf);
29                 }
30                 else {
31                         bsdf->alpha_y = 0.0f;
32                         bsdf->alpha_x = 0.0f;
33                         bsdf->ior = 0.0f;
34                         sd->flag |= bsdf_reflection_setup(bsdf);
35                 }
36         }
37         else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
38                 bsdf->alpha_x = roughness;
39                 bsdf->alpha_y = roughness;
40                 bsdf->ior = eta;
41
42                 if(refract)
43                         sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
44                 else
45                         sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
46         }
47         else {
48                 bsdf->alpha_x = roughness;
49                 bsdf->alpha_y = roughness;
50                 bsdf->ior = eta;
51
52                 if(refract)
53                         sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
54                 else
55                         sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
56         }
57 }
58
59 ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag, int *offset)
60 {
61         uint type, param1_offset, param2_offset;
62
63         uint mix_weight_offset;
64         decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
65         float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
66
67         /* note we read this extra node before weight check, so offset is added */
68         uint4 data_node = read_node(kg, offset);
69
70         /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */
71         if(mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) {
72                 if(type == CLOSURE_BSDF_PRINCIPLED_ID) {
73                         /* Read all principled BSDF extra data to get the right offset. */
74                         read_node(kg, offset);
75                         read_node(kg, offset);
76                         read_node(kg, offset);
77                         read_node(kg, offset);
78                 }
79
80                 return;
81         }
82
83         float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
84
85         float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
86         float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
87
88         switch(type) {
89 #ifdef __PRINCIPLED__
90                 case CLOSURE_BSDF_PRINCIPLED_ID: {
91                         uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, sheen_offset,
92                                 sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, eta_offset, transmission_offset,
93                                 anisotropic_rotation_offset, transmission_roughness_offset;
94                         uint4 data_node2 = read_node(kg, offset);
95
96                         float3 T = stack_load_float3(stack, data_node.y);
97                         decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specular_tint_offset, &anisotropic_offset);
98                         decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_roughness_offset);
99                         decode_node_uchar4(data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &transmission_roughness_offset);
100
101                         // get Disney principled parameters
102                         float metallic = param1;
103                         float subsurface = param2;
104                         float specular = stack_load_float(stack, specular_offset);
105                         float roughness = stack_load_float(stack, roughness_offset);
106                         float specular_tint = stack_load_float(stack, specular_tint_offset);
107                         float anisotropic = stack_load_float(stack, anisotropic_offset);
108                         float sheen = stack_load_float(stack, sheen_offset);
109                         float sheen_tint = stack_load_float(stack, sheen_tint_offset);
110                         float clearcoat = stack_load_float(stack, clearcoat_offset);
111                         float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
112                         float transmission = stack_load_float(stack, transmission_offset);
113                         float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
114                         float transmission_roughness = stack_load_float(stack, transmission_roughness_offset);
115                         float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
116
117                         ClosureType distribution = stack_valid(data_node2.y) ? (ClosureType) data_node2.y : CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
118
119                         /* rotate tangent */
120                         if(anisotropic_rotation != 0.0f)
121                                 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
122
123                         /* calculate ior */
124                         float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
125
126                         // calculate fresnel for refraction
127                         float cosNO = dot(N, sd->I);
128                         float fresnel = fresnel_dielectric_cos(cosNO, ior);
129
130                         // calculate weights of the diffuse and specular part
131                         float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission));
132                         
133                         float final_transmission = saturate(transmission) * (1.0f - saturate(metallic));
134                         float specular_weight = (1.0f - final_transmission);
135
136                         // get the base color
137                         uint4 data_base_color = read_node(kg, offset);
138                         float3 base_color = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) :
139                                 make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w));
140
141                         // get the additional clearcoat normal and subsurface scattering radius
142                         uint4 data_cn_ssr = read_node(kg, offset);
143                         float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : sd->N;
144                         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);
145
146                         // get the subsurface color
147                         uint4 data_subsurface_color = read_node(kg, offset);
148                         float3 subsurface_color = stack_valid(data_subsurface_color.x) ? stack_load_float3(stack, data_subsurface_color.x) :
149                                 make_float3(__uint_as_float(data_subsurface_color.y), __uint_as_float(data_subsurface_color.z), __uint_as_float(data_subsurface_color.w));
150
151                         float3 weight = sd->svm_closure_weight * mix_weight;
152
153 #ifdef __SUBSURFACE__
154                         float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface);
155                         float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
156
157                         /* disable in case of diffuse ancestor, can't see it well then and
158                          * adds considerably noise due to probabilities of continuing path
159                          * getting lower and lower */
160                         if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
161                                 subsurface = 0.0f;
162
163                                 /* need to set the base color in this case such that the
164                                  * rays get the correctly mixed color after transmitting
165                                  * the object */
166                                 base_color = mixed_ss_base_color;
167                         }
168
169                         /* diffuse */
170                         if(fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
171                                 if(subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
172                                         float3 diff_weight = weight * base_color * diffuse_weight;
173
174                                         PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
175
176                                         if(bsdf) {
177                                                 bsdf->N = N;
178                                                 bsdf->roughness = roughness;
179
180                                                 /* setup bsdf */
181                                                 sd->flag |= bsdf_principled_diffuse_setup(bsdf);
182                                         }
183                                 }
184                                 else if(subsurface > CLOSURE_WEIGHT_CUTOFF) {
185                                         Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
186
187                                         if(bssrdf) {
188                                                 bssrdf->radius = subsurface_radius * subsurface;
189                                                 bssrdf->albedo = subsurface_color;
190                                                 bssrdf->texture_blur = 0.0f;
191                                                 bssrdf->sharpness = 0.0f;
192                                                 bssrdf->N = N;
193                                                 bssrdf->roughness = roughness;
194
195                                                 /* setup bsdf */
196                                                 sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID);
197                                         }
198                                 }
199                         }
200 #else
201                         /* diffuse */
202                         if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
203                                 float3 diff_weight = weight * base_color * diffuse_weight;
204
205                                 PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
206
207                                 if(bsdf) {
208                                         bsdf->N = N;
209                                         bsdf->roughness = roughness;
210
211                                         /* setup bsdf */
212                                         sd->flag |= bsdf_principled_diffuse_setup(bsdf);
213                                 }
214                         }
215 #endif
216
217                         /* sheen */
218                         if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
219                                 float m_cdlum = linear_rgb_to_gray(base_color);
220                                 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
221
222                                 /* color of the sheen component */
223                                 float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint;
224
225                                 float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
226
227                                 PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf*)bsdf_alloc(sd, sizeof(PrincipledSheenBsdf), sheen_weight);
228
229                                 if(bsdf) {
230                                         bsdf->N = N;
231
232                                         /* setup bsdf */
233                                         sd->flag |= bsdf_principled_sheen_setup(bsdf);
234                                 }
235                         }
236
237                         /* specular reflection */
238 #ifdef __CAUSTICS_TRICKS__
239                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
240 #endif
241                                 if(specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
242                                         float3 spec_weight = weight * specular_weight;
243
244                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
245                                         if(!bsdf){
246                                                 break;
247                                         }
248
249                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
250                                         if(!extra) {
251                                                 break;
252                                         }
253
254                                         bsdf->N = N;
255                                         bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
256                                         bsdf->T = T;
257                                         bsdf->extra = extra;
258
259                                         float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
260                                         float r2 = roughness * roughness;
261
262                                         bsdf->alpha_x = r2 / aspect;
263                                         bsdf->alpha_y = r2 * aspect;
264
265                                         float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
266                                         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
267                                         float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + m_ctint * specular_tint;
268
269                                         bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
270                                         bsdf->extra->color = base_color;
271                                         bsdf->extra->clearcoat = 0.0f;
272
273                                         /* setup bsdf */
274                                         if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
275                                                 sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
276                                         else /* use multi-scatter GGX */
277                                                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
278                                 }
279 #ifdef __CAUSTICS_TRICKS__
280                         }
281 #endif
282
283                         /* BSDF */
284 #ifdef __CAUSTICS_TRICKS__
285                         if(kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
286 #endif
287                                 if(final_transmission > CLOSURE_WEIGHT_CUTOFF) {
288                                         float3 glass_weight = weight * final_transmission;
289                                         float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
290
291                                         if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
292                                                 float refl_roughness = roughness;
293
294                                                 /* reflection */
295 #ifdef __CAUSTICS_TRICKS__
296                                                 if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
297 #endif
298                                                 {
299                                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel);
300                                                         if(!bsdf) {
301                                                                 break;
302                                                         }
303
304                                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
305                                                         if(!extra) {
306                                                                 break;
307                                                         }
308
309                                                         bsdf->N = N;
310                                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
311                                                         bsdf->extra = extra;
312
313                                                         bsdf->alpha_x = refl_roughness * refl_roughness;
314                                                         bsdf->alpha_y = refl_roughness * refl_roughness;
315                                                         bsdf->ior = ior;
316
317                                                         bsdf->extra->color = base_color;
318                                                         bsdf->extra->cspec0 = cspec0;
319                                                         bsdf->extra->clearcoat = 0.0f;
320
321                                                         /* setup bsdf */
322                                                         sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
323                                                 }
324
325                                                 /* refraction */
326 #ifdef __CAUSTICS_TRICKS__
327                                                 if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
328 #endif
329                                                 {
330                                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), base_color*glass_weight*(1.0f - fresnel));
331                                                         if(!bsdf) {
332                                                                 break;
333                                                         }
334
335                                                         bsdf->N = N;
336
337                                                         if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
338                                                                 transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness);
339                                                         else
340                                                                 transmission_roughness = refl_roughness;
341
342                                                         bsdf->alpha_x = transmission_roughness * transmission_roughness;
343                                                         bsdf->alpha_y = transmission_roughness * transmission_roughness;
344                                                         bsdf->ior = ior;
345
346                                                         /* setup bsdf */
347                                                         sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
348                                                 }
349                                         }
350                                         else { /* use multi-scatter GGX */
351                                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
352                                                 if(!bsdf) {
353                                                         break;
354                                                 }
355
356                                                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
357                                                 if(!extra) {
358                                                         break;
359                                                 }
360
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 #ifdef __CAUSTICS_TRICKS__
378                         }
379 #endif
380
381                         /* clearcoat */
382 #ifdef __CAUSTICS_TRICKS__
383                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
384 #endif
385                                 if(clearcoat > CLOSURE_WEIGHT_CUTOFF) {
386                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
387                                         if(!bsdf) {
388                                                 break;
389                                         }
390
391                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
392                                         if(!extra) {
393                                                 break;
394                                         }
395
396                                         bsdf->N = clearcoat_normal;
397                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
398                                         bsdf->ior = 1.5f;
399                                         bsdf->extra = extra;
400
401                                         bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
402                                         bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
403
404                                         bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
405                                         bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
406                                         bsdf->extra->clearcoat = clearcoat;
407
408                                         /* setup bsdf */
409                                         sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
410                                 }
411 #ifdef __CAUSTICS_TRICKS__
412                         }
413 #endif
414
415                         break;
416                 }
417 #endif  /* __PRINCIPLED__ */
418                 case CLOSURE_BSDF_DIFFUSE_ID: {
419                         float3 weight = sd->svm_closure_weight * mix_weight;
420                         OrenNayarBsdf *bsdf = (OrenNayarBsdf*)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
421
422                         if(bsdf) {
423                                 bsdf->N = N;
424
425                                 float roughness = param1;
426
427                                 if(roughness == 0.0f) {
428                                         sd->flag |= bsdf_diffuse_setup((DiffuseBsdf*)bsdf);
429                                 }
430                                 else {
431                                         bsdf->roughness = roughness;
432                                         sd->flag |= bsdf_oren_nayar_setup(bsdf);
433                                 }
434                         }
435                         break;
436                 }
437                 case CLOSURE_BSDF_TRANSLUCENT_ID: {
438                         float3 weight = sd->svm_closure_weight * mix_weight;
439                         DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
440
441                         if(bsdf) {
442                                 bsdf->N = N;
443                                 sd->flag |= bsdf_translucent_setup(bsdf);
444                         }
445                         break;
446                 }
447                 case CLOSURE_BSDF_TRANSPARENT_ID: {
448                         float3 weight = sd->svm_closure_weight * mix_weight;
449                         bsdf_transparent_setup(sd, weight);
450                         break;
451                 }
452                 case CLOSURE_BSDF_REFLECTION_ID:
453                 case CLOSURE_BSDF_MICROFACET_GGX_ID:
454                 case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
455                 case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
456                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
457 #ifdef __CAUSTICS_TRICKS__
458                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
459                                 break;
460 #endif
461                         float3 weight = sd->svm_closure_weight * mix_weight;
462                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
463
464                         if(!bsdf) {
465                                 break;
466                         }
467
468                         bsdf->N = N;
469                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
470                         bsdf->alpha_x = param1;
471                         bsdf->alpha_y = param1;
472                         bsdf->ior = 0.0f;
473                         bsdf->extra = NULL;
474
475                         /* setup bsdf */
476                         if(type == CLOSURE_BSDF_REFLECTION_ID)
477                                 sd->flag |= bsdf_reflection_setup(bsdf);
478                         else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
479                                 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
480                         else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID)
481                                 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
482                         else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
483                                 kernel_assert(stack_valid(data_node.z));
484                                 bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
485                                 if(bsdf->extra) {
486                                         bsdf->extra->color = stack_load_float3(stack, data_node.z);
487                                         bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
488                                         bsdf->extra->clearcoat = 0.0f;
489                                         sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
490                                 }
491                         }
492                         else {
493                                 sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
494                         }
495
496                         break;
497                 }
498                 case CLOSURE_BSDF_REFRACTION_ID:
499                 case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
500                 case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
501 #ifdef __CAUSTICS_TRICKS__
502                         if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
503                                 break;
504 #endif
505                         float3 weight = sd->svm_closure_weight * mix_weight;
506                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
507
508                         if(bsdf) {
509                                 bsdf->N = N;
510                                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
511                                 bsdf->extra = NULL;
512
513                                 float eta = fmaxf(param2, 1e-5f);
514                                 eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
515
516                                 /* setup bsdf */
517                                 if(type == CLOSURE_BSDF_REFRACTION_ID) {
518                                         bsdf->alpha_x = 0.0f;
519                                         bsdf->alpha_y = 0.0f;
520                                         bsdf->ior = eta;
521
522                                         sd->flag |= bsdf_refraction_setup(bsdf);
523                                 }
524                                 else {
525                                         bsdf->alpha_x = param1;
526                                         bsdf->alpha_y = param1;
527                                         bsdf->ior = eta;
528
529                                         if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
530                                                 sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
531                                         else
532                                                 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
533                                 }
534                         }
535
536                         break;
537                 }
538                 case CLOSURE_BSDF_SHARP_GLASS_ID:
539                 case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
540                 case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
541 #ifdef __CAUSTICS_TRICKS__
542                         if(!kernel_data.integrator.caustics_reflective &&
543                            !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
544                         {
545                                 break;
546                         }
547 #endif
548                         float3 weight = sd->svm_closure_weight * mix_weight;
549
550                         /* index of refraction */
551                         float eta = fmaxf(param2, 1e-5f);
552                         eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
553
554                         /* fresnel */
555                         float cosNO = dot(N, sd->I);
556                         float fresnel = fresnel_dielectric_cos(cosNO, eta);
557                         float roughness = param1;
558
559                         /* reflection */
560 #ifdef __CAUSTICS_TRICKS__
561                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
562 #endif
563                         {
564                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*fresnel);
565
566                                 if(bsdf) {
567                                         bsdf->N = N;
568                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
569                                         bsdf->extra = NULL;
570                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
571                                 }
572                         }
573
574                         /* refraction */
575 #ifdef __CAUSTICS_TRICKS__
576                         if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
577 #endif
578                         {
579                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*(1.0f - fresnel));
580
581                                 if(bsdf) {
582                                         bsdf->N = N;
583                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
584                                         bsdf->extra = NULL;
585                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
586                                 }
587                         }
588
589                         break;
590                 }
591                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
592 #ifdef __CAUSTICS_TRICKS__
593                         if(!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
594                                 break;
595 #endif
596                         float3 weight = sd->svm_closure_weight * mix_weight;
597                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
598                         if(!bsdf) {
599                                 break;
600                         }
601
602                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
603                         if(!extra) {
604                                 break;
605                         }
606
607                         bsdf->N = N;
608                         bsdf->extra = extra;
609                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
610
611                         bsdf->alpha_x = param1;
612                         bsdf->alpha_y = param1;
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 = 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_REFLECTION_ID:
719                 case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
720                         float3 weight = sd->svm_closure_weight * mix_weight;
721                         
722                         if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
723                                 /* todo: giving a fixed weight here will cause issues when
724                                  * mixing multiple BSDFS. energy will not be conserved and
725                                  * the throughput can blow up after multiple bounces. we
726                                  * better figure out a way to skip backfaces from rays
727                                  * spawned by transmission from the front */
728                                 bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f));
729                         }
730                         else {
731                                 HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight);
732
733                                 if(bsdf) {
734                                         bsdf->N = N;
735                                         bsdf->roughness1 = param1;
736                                         bsdf->roughness2 = param2;
737                                         bsdf->offset = -stack_load_float(stack, data_node.z);
738
739                                         if(stack_valid(data_node.y)) {
740                                                 bsdf->T = normalize(stack_load_float3(stack, data_node.y));
741                                         }
742                                         else if(!(sd->type & PRIMITIVE_ALL_CURVE)) {
743                                                 bsdf->T = normalize(sd->dPdv);
744                                                 bsdf->offset = 0.0f;
745                                         }
746                                         else
747                                                 bsdf->T = normalize(sd->dPdu);
748
749                                         if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
750                                                 sd->flag |= bsdf_hair_reflection_setup(bsdf);
751                                         }
752                                         else {
753                                                 sd->flag |= bsdf_hair_transmission_setup(bsdf);
754                                         }
755                                 }
756                         }
757
758                         break;
759                 }
760 #endif
761
762 #ifdef __SUBSURFACE__
763                 case CLOSURE_BSSRDF_CUBIC_ID:
764                 case CLOSURE_BSSRDF_GAUSSIAN_ID:
765                 case CLOSURE_BSSRDF_BURLEY_ID: {
766                         float3 weight = sd->svm_closure_weight * mix_weight;
767                         Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
768
769                         if(bssrdf) {
770                                 /* disable in case of diffuse ancestor, can't see it well then and
771                                  * adds considerably noise due to probabilities of continuing path
772                                  * getting lower and lower */
773                                 if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
774                                         param1 = 0.0f;
775
776                                 bssrdf->radius = stack_load_float3(stack, data_node.z)*param1;
777                                 bssrdf->albedo = sd->svm_closure_weight;
778                                 bssrdf->texture_blur = param2;
779                                 bssrdf->sharpness = stack_load_float(stack, data_node.w);
780                                 bssrdf->N = N;
781                                 sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
782                         }
783
784                         break;
785                 }
786 #endif
787                 default:
788                         break;
789         }
790 }
791
792 ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag)
793 {
794 #ifdef __VOLUME__
795         /* Only sum extinction for volumes, variable is shared with surface transparency. */
796         if(shader_type != SHADER_TYPE_VOLUME) {
797                 return;
798         }
799
800         uint type, param1_offset, param2_offset;
801
802         uint mix_weight_offset;
803         decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
804         float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
805
806         if(mix_weight == 0.0f)
807                 return;
808
809         float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
810
811         /* Compute scattering coefficient. */
812         float density = mix_weight * fmaxf(param1, 0.0f);
813         float3 weight = sd->svm_closure_weight;
814
815         if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
816                 weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
817         }
818
819         weight *= density;
820
821         /* Add closure for volume scattering. */
822         if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
823                 float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
824                 HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
825
826                 if(volume) {
827                         volume->g = param2; /* g */
828                         sd->flag |= volume_henyey_greenstein_setup(volume);
829                 }
830         }
831
832         /* Sum total extinction weight. */
833         volume_extinction_setup(sd, weight);
834 #endif
835 }
836
837 ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
838 {
839         uint mix_weight_offset = node.y;
840         float3 weight = sd->svm_closure_weight;
841
842         if(stack_valid(mix_weight_offset)) {
843                 float mix_weight = stack_load_float(stack, mix_weight_offset);
844
845                 if(mix_weight == 0.0f)
846                         return;
847
848                 weight *= mix_weight;
849         }
850
851         emission_setup(sd, weight);
852 }
853
854 ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
855 {
856         uint mix_weight_offset = node.y;
857         float3 weight = sd->svm_closure_weight;
858
859         if(stack_valid(mix_weight_offset)) {
860                 float mix_weight = stack_load_float(stack, mix_weight_offset);
861
862                 if(mix_weight == 0.0f)
863                         return;
864
865                 weight *= mix_weight;
866         }
867
868         background_setup(sd, weight);
869 }
870
871 ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
872 {
873         uint mix_weight_offset = node.y;
874
875         if(stack_valid(mix_weight_offset)) {
876                 float mix_weight = stack_load_float(stack, mix_weight_offset);
877
878                 if(mix_weight == 0.0f)
879                         return;
880
881                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
882         }
883         else
884                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
885
886         sd->flag |= SD_HOLDOUT;
887 }
888
889 ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
890 {
891         uint mix_weight_offset = node.y;
892
893         if(stack_valid(mix_weight_offset)) {
894                 float mix_weight = stack_load_float(stack, mix_weight_offset);
895
896                 if(mix_weight == 0.0f)
897                         return;
898
899                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight * mix_weight);
900         }
901         else
902                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight);
903
904         sd->flag |= SD_AO;
905 }
906
907 /* Closure Nodes */
908
909 ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
910 {
911         sd->svm_closure_weight = weight;
912 }
913
914 ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
915 {
916         float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
917         svm_node_closure_store_weight(sd, weight);
918 }
919
920 ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
921 {
922         float3 weight = stack_load_float3(stack, weight_offset);
923
924         svm_node_closure_store_weight(sd, weight);
925 }
926
927 ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
928 {
929         uint color_offset = node.y;
930         uint strength_offset = node.z;
931
932         float strength = stack_load_float(stack, strength_offset);
933         float3 weight = stack_load_float3(stack, color_offset)*strength;
934
935         svm_node_closure_store_weight(sd, weight);
936 }
937
938 ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
939 {
940         /* fetch weight from blend input, previous mix closures,
941          * and write to stack to be used by closure nodes later */
942         uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
943         decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
944
945         float weight = stack_load_float(stack, weight_offset);
946         weight = saturate(weight);
947
948         float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f;
949
950         if(stack_valid(weight1_offset))
951                 stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
952         if(stack_valid(weight2_offset))
953                 stack_store_float(stack, weight2_offset, in_weight*weight);
954 }
955
956 /* (Bump) normal */
957
958 ccl_device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
959 {
960         float3 normal = stack_load_float3(stack, in_direction);
961         sd->N = normal;
962         stack_store_float3(stack, out_normal, normal);
963 }
964
965 CCL_NAMESPACE_END
966