Fix random walk SSS issues with different base and subsurface color.
[blender-staging.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 = (ClosureType) data_node2.y;
118                         ClosureType subsurface_method = (ClosureType) data_node2.z;
119
120                         /* rotate tangent */
121                         if(anisotropic_rotation != 0.0f)
122                                 T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F);
123
124                         /* calculate ior */
125                         float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
126
127                         // calculate fresnel for refraction
128                         float cosNO = dot(N, sd->I);
129                         float fresnel = fresnel_dielectric_cos(cosNO, ior);
130
131                         // calculate weights of the diffuse and specular part
132                         float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission));
133                         
134                         float final_transmission = saturate(transmission) * (1.0f - saturate(metallic));
135                         float specular_weight = (1.0f - final_transmission);
136
137                         // get the base color
138                         uint4 data_base_color = read_node(kg, offset);
139                         float3 base_color = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) :
140                                 make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w));
141
142                         // get the additional clearcoat normal and subsurface scattering radius
143                         uint4 data_cn_ssr = read_node(kg, offset);
144                         float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : sd->N;
145                         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);
146
147                         // get the subsurface color
148                         uint4 data_subsurface_color = read_node(kg, offset);
149                         float3 subsurface_color = stack_valid(data_subsurface_color.x) ? stack_load_float3(stack, data_subsurface_color.x) :
150                                 make_float3(__uint_as_float(data_subsurface_color.y), __uint_as_float(data_subsurface_color.z), __uint_as_float(data_subsurface_color.w));
151
152                         float3 weight = sd->svm_closure_weight * mix_weight;
153
154 #ifdef __SUBSURFACE__
155                         float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface);
156                         float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight;
157
158                         /* disable in case of diffuse ancestor, can't see it well then and
159                          * adds considerably noise due to probabilities of continuing path
160                          * getting lower and lower */
161                         if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
162                                 subsurface = 0.0f;
163
164                                 /* need to set the base color in this case such that the
165                                  * rays get the correctly mixed color after transmitting
166                                  * the object */
167                                 base_color = mixed_ss_base_color;
168                         }
169
170                         /* diffuse */
171                         if(fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) {
172                                 if(subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
173                                         float3 diff_weight = weight * base_color * diffuse_weight;
174
175                                         PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
176
177                                         if(bsdf) {
178                                                 bsdf->N = N;
179                                                 bsdf->roughness = roughness;
180
181                                                 /* setup bsdf */
182                                                 sd->flag |= bsdf_principled_diffuse_setup(bsdf);
183                                         }
184                                 }
185                                 else if(subsurface > CLOSURE_WEIGHT_CUTOFF) {
186                                         Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight);
187
188                                         if(bssrdf) {
189                                                 bssrdf->radius = subsurface_radius * subsurface;
190                                                 bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID)? subsurface_color:  mixed_ss_base_color;
191                                                 bssrdf->texture_blur = 0.0f;
192                                                 bssrdf->sharpness = 0.0f;
193                                                 bssrdf->N = N;
194                                                 bssrdf->roughness = roughness;
195
196                                                 /* setup bsdf */
197                                                 sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method);
198                                         }
199                                 }
200                         }
201 #else
202                         /* diffuse */
203                         if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF) {
204                                 float3 diff_weight = weight * base_color * diffuse_weight;
205
206                                 PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight);
207
208                                 if(bsdf) {
209                                         bsdf->N = N;
210                                         bsdf->roughness = roughness;
211
212                                         /* setup bsdf */
213                                         sd->flag |= bsdf_principled_diffuse_setup(bsdf);
214                                 }
215                         }
216 #endif
217
218                         /* sheen */
219                         if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) {
220                                 float m_cdlum = linear_rgb_to_gray(base_color);
221                                 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
222
223                                 /* color of the sheen component */
224                                 float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint;
225
226                                 float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight;
227
228                                 PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf*)bsdf_alloc(sd, sizeof(PrincipledSheenBsdf), sheen_weight);
229
230                                 if(bsdf) {
231                                         bsdf->N = N;
232
233                                         /* setup bsdf */
234                                         sd->flag |= bsdf_principled_sheen_setup(bsdf);
235                                 }
236                         }
237
238                         /* specular reflection */
239 #ifdef __CAUSTICS_TRICKS__
240                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
241 #endif
242                                 if(specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) {
243                                         float3 spec_weight = weight * specular_weight;
244
245                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight);
246                                         if(!bsdf){
247                                                 break;
248                                         }
249
250                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
251                                         if(!extra) {
252                                                 break;
253                                         }
254
255                                         bsdf->N = N;
256                                         bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f;
257                                         bsdf->T = T;
258                                         bsdf->extra = extra;
259
260                                         float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f);
261                                         float r2 = roughness * roughness;
262
263                                         bsdf->alpha_x = r2 / aspect;
264                                         bsdf->alpha_y = r2 * aspect;
265
266                                         float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx.
267                                         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
268                                         float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + m_ctint * specular_tint;
269
270                                         bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic;
271                                         bsdf->extra->color = base_color;
272                                         bsdf->extra->clearcoat = 0.0f;
273
274                                         /* setup bsdf */
275                                         if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */
276                                                 sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
277                                         else /* use multi-scatter GGX */
278                                                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
279                                 }
280 #ifdef __CAUSTICS_TRICKS__
281                         }
282 #endif
283
284                         /* BSDF */
285 #ifdef __CAUSTICS_TRICKS__
286                         if(kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) {
287 #endif
288                                 if(final_transmission > CLOSURE_WEIGHT_CUTOFF) {
289                                         float3 glass_weight = weight * final_transmission;
290                                         float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint);
291
292                                         if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */
293                                                 float refl_roughness = roughness;
294
295                                                 /* reflection */
296 #ifdef __CAUSTICS_TRICKS__
297                                                 if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
298 #endif
299                                                 {
300                                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel);
301                                                         if(!bsdf) {
302                                                                 break;
303                                                         }
304
305                                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
306                                                         if(!extra) {
307                                                                 break;
308                                                         }
309
310                                                         bsdf->N = N;
311                                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
312                                                         bsdf->extra = extra;
313
314                                                         bsdf->alpha_x = refl_roughness * refl_roughness;
315                                                         bsdf->alpha_y = refl_roughness * refl_roughness;
316                                                         bsdf->ior = ior;
317
318                                                         bsdf->extra->color = base_color;
319                                                         bsdf->extra->cspec0 = cspec0;
320                                                         bsdf->extra->clearcoat = 0.0f;
321
322                                                         /* setup bsdf */
323                                                         sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
324                                                 }
325
326                                                 /* refraction */
327 #ifdef __CAUSTICS_TRICKS__
328                                                 if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
329 #endif
330                                                 {
331                                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), base_color*glass_weight*(1.0f - fresnel));
332                                                         if(!bsdf) {
333                                                                 break;
334                                                         }
335
336                                                         bsdf->N = N;
337                                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
338                                                         bsdf->extra = NULL;
339
340                                                         if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
341                                                                 transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness);
342                                                         else
343                                                                 transmission_roughness = refl_roughness;
344
345                                                         bsdf->alpha_x = transmission_roughness * transmission_roughness;
346                                                         bsdf->alpha_y = transmission_roughness * transmission_roughness;
347                                                         bsdf->ior = ior;
348
349                                                         /* setup bsdf */
350                                                         sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
351                                                 }
352                                         }
353                                         else { /* use multi-scatter GGX */
354                                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
355                                                 if(!bsdf) {
356                                                         break;
357                                                 }
358
359                                                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
360                                                 if(!extra) {
361                                                         break;
362                                                 }
363
364                                                 bsdf->N = N;
365                                                 bsdf->extra = extra;
366                                                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
367
368                                                 bsdf->alpha_x = roughness * roughness;
369                                                 bsdf->alpha_y = roughness * roughness;
370                                                 bsdf->ior = ior;
371
372                                                 bsdf->extra->color = base_color;
373                                                 bsdf->extra->cspec0 = cspec0;
374                                                 bsdf->extra->clearcoat = 0.0f;
375
376                                                 /* setup bsdf */
377                                                 sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
378                                         }
379                                 }
380 #ifdef __CAUSTICS_TRICKS__
381                         }
382 #endif
383
384                         /* clearcoat */
385 #ifdef __CAUSTICS_TRICKS__
386                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
387 #endif
388                                 if(clearcoat > CLOSURE_WEIGHT_CUTOFF) {
389                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
390                                         if(!bsdf) {
391                                                 break;
392                                         }
393
394                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
395                                         if(!extra) {
396                                                 break;
397                                         }
398
399                                         bsdf->N = clearcoat_normal;
400                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
401                                         bsdf->ior = 1.5f;
402                                         bsdf->extra = extra;
403
404                                         bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
405                                         bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
406
407                                         bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
408                                         bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
409                                         bsdf->extra->clearcoat = clearcoat;
410
411                                         /* setup bsdf */
412                                         sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
413                                 }
414 #ifdef __CAUSTICS_TRICKS__
415                         }
416 #endif
417
418                         break;
419                 }
420 #endif  /* __PRINCIPLED__ */
421                 case CLOSURE_BSDF_DIFFUSE_ID: {
422                         float3 weight = sd->svm_closure_weight * mix_weight;
423                         OrenNayarBsdf *bsdf = (OrenNayarBsdf*)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
424
425                         if(bsdf) {
426                                 bsdf->N = N;
427
428                                 float roughness = param1;
429
430                                 if(roughness == 0.0f) {
431                                         sd->flag |= bsdf_diffuse_setup((DiffuseBsdf*)bsdf);
432                                 }
433                                 else {
434                                         bsdf->roughness = roughness;
435                                         sd->flag |= bsdf_oren_nayar_setup(bsdf);
436                                 }
437                         }
438                         break;
439                 }
440                 case CLOSURE_BSDF_TRANSLUCENT_ID: {
441                         float3 weight = sd->svm_closure_weight * mix_weight;
442                         DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
443
444                         if(bsdf) {
445                                 bsdf->N = N;
446                                 sd->flag |= bsdf_translucent_setup(bsdf);
447                         }
448                         break;
449                 }
450                 case CLOSURE_BSDF_TRANSPARENT_ID: {
451                         float3 weight = sd->svm_closure_weight * mix_weight;
452                         bsdf_transparent_setup(sd, weight);
453                         break;
454                 }
455                 case CLOSURE_BSDF_REFLECTION_ID:
456                 case CLOSURE_BSDF_MICROFACET_GGX_ID:
457                 case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
458                 case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
459                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
460 #ifdef __CAUSTICS_TRICKS__
461                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
462                                 break;
463 #endif
464                         float3 weight = sd->svm_closure_weight * mix_weight;
465                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
466
467                         if(!bsdf) {
468                                 break;
469                         }
470
471                         bsdf->N = N;
472                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
473                         bsdf->alpha_x = param1;
474                         bsdf->alpha_y = param1;
475                         bsdf->ior = 0.0f;
476                         bsdf->extra = NULL;
477
478                         /* setup bsdf */
479                         if(type == CLOSURE_BSDF_REFLECTION_ID)
480                                 sd->flag |= bsdf_reflection_setup(bsdf);
481                         else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
482                                 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
483                         else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID)
484                                 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
485                         else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
486                                 kernel_assert(stack_valid(data_node.z));
487                                 bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
488                                 if(bsdf->extra) {
489                                         bsdf->extra->color = stack_load_float3(stack, data_node.z);
490                                         bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
491                                         bsdf->extra->clearcoat = 0.0f;
492                                         sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
493                                 }
494                         }
495                         else {
496                                 sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
497                         }
498
499                         break;
500                 }
501                 case CLOSURE_BSDF_REFRACTION_ID:
502                 case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
503                 case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
504 #ifdef __CAUSTICS_TRICKS__
505                         if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
506                                 break;
507 #endif
508                         float3 weight = sd->svm_closure_weight * mix_weight;
509                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
510
511                         if(bsdf) {
512                                 bsdf->N = N;
513                                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
514                                 bsdf->extra = NULL;
515
516                                 float eta = fmaxf(param2, 1e-5f);
517                                 eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
518
519                                 /* setup bsdf */
520                                 if(type == CLOSURE_BSDF_REFRACTION_ID) {
521                                         bsdf->alpha_x = 0.0f;
522                                         bsdf->alpha_y = 0.0f;
523                                         bsdf->ior = eta;
524
525                                         sd->flag |= bsdf_refraction_setup(bsdf);
526                                 }
527                                 else {
528                                         bsdf->alpha_x = param1;
529                                         bsdf->alpha_y = param1;
530                                         bsdf->ior = eta;
531
532                                         if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
533                                                 sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
534                                         else
535                                                 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
536                                 }
537                         }
538
539                         break;
540                 }
541                 case CLOSURE_BSDF_SHARP_GLASS_ID:
542                 case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
543                 case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
544 #ifdef __CAUSTICS_TRICKS__
545                         if(!kernel_data.integrator.caustics_reflective &&
546                            !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
547                         {
548                                 break;
549                         }
550 #endif
551                         float3 weight = sd->svm_closure_weight * mix_weight;
552
553                         /* index of refraction */
554                         float eta = fmaxf(param2, 1e-5f);
555                         eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
556
557                         /* fresnel */
558                         float cosNO = dot(N, sd->I);
559                         float fresnel = fresnel_dielectric_cos(cosNO, eta);
560                         float roughness = param1;
561
562                         /* reflection */
563 #ifdef __CAUSTICS_TRICKS__
564                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
565 #endif
566                         {
567                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*fresnel);
568
569                                 if(bsdf) {
570                                         bsdf->N = N;
571                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
572                                         bsdf->extra = NULL;
573                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
574                                 }
575                         }
576
577                         /* refraction */
578 #ifdef __CAUSTICS_TRICKS__
579                         if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
580 #endif
581                         {
582                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*(1.0f - fresnel));
583
584                                 if(bsdf) {
585                                         bsdf->N = N;
586                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
587                                         bsdf->extra = NULL;
588                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
589                                 }
590                         }
591
592                         break;
593                 }
594                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
595 #ifdef __CAUSTICS_TRICKS__
596                         if(!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
597                                 break;
598 #endif
599                         float3 weight = sd->svm_closure_weight * mix_weight;
600                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
601                         if(!bsdf) {
602                                 break;
603                         }
604
605                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
606                         if(!extra) {
607                                 break;
608                         }
609
610                         bsdf->N = N;
611                         bsdf->extra = extra;
612                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
613
614                         bsdf->alpha_x = param1;
615                         bsdf->alpha_y = param1;
616                         float eta = fmaxf(param2, 1e-5f);
617                         bsdf->ior = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
618
619                         kernel_assert(stack_valid(data_node.z));
620                         bsdf->extra->color = stack_load_float3(stack, data_node.z);
621                         bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
622                         bsdf->extra->clearcoat = 0.0f;
623
624                         /* setup bsdf */
625                         sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
626                         break;
627                 }
628                 case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
629                 case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
630                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
631                 case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
632 #ifdef __CAUSTICS_TRICKS__
633                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
634                                 break;
635 #endif
636                         float3 weight = sd->svm_closure_weight * mix_weight;
637                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
638
639                         if(bsdf) {
640                                 bsdf->N = N;
641                                 bsdf->extra = NULL;
642                                 bsdf->T = stack_load_float3(stack, data_node.y);
643
644                                 /* rotate tangent */
645                                 float rotation = stack_load_float(stack, data_node.z);
646
647                                 if(rotation != 0.0f)
648                                         bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
649
650                                 /* compute roughness */
651                                 float roughness = param1;
652                                 float anisotropy = clamp(param2, -0.99f, 0.99f);
653
654                                 if(anisotropy < 0.0f) {
655                                         bsdf->alpha_x = roughness/(1.0f + anisotropy);
656                                         bsdf->alpha_y = roughness*(1.0f + anisotropy);
657                                 }
658                                 else {
659                                         bsdf->alpha_x = roughness*(1.0f - anisotropy);
660                                         bsdf->alpha_y = roughness/(1.0f - anisotropy);
661                                 }
662
663                                 bsdf->ior = 0.0f;
664
665                                 if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
666                                         sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
667                                 }
668                                 else if(type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
669                                         sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
670                                 }
671                                 else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
672                                         kernel_assert(stack_valid(data_node.w));
673                                         bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
674                                         if(bsdf->extra) {
675                                                 bsdf->extra->color = stack_load_float3(stack, data_node.w);
676                                                 bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
677                                                 bsdf->extra->clearcoat = 0.0f;
678                                                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
679                                         }
680                                 }
681                                 else
682                                         sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
683                         }
684                         break;
685                 }
686                 case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
687                         float3 weight = sd->svm_closure_weight * mix_weight;
688                         VelvetBsdf *bsdf = (VelvetBsdf*)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
689
690                         if(bsdf) {
691                                 bsdf->N = N;
692
693                                 bsdf->sigma = saturate(param1);
694                                 sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
695                         }
696                         break;
697                 }
698                 case CLOSURE_BSDF_GLOSSY_TOON_ID:
699 #ifdef __CAUSTICS_TRICKS__
700                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
701                                 break;
702                         ATTR_FALLTHROUGH;
703 #endif
704                 case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
705                         float3 weight = sd->svm_closure_weight * mix_weight;
706                         ToonBsdf *bsdf = (ToonBsdf*)bsdf_alloc(sd, sizeof(ToonBsdf), weight);
707
708                         if(bsdf) {
709                                 bsdf->N = N;
710                                 bsdf->size = param1;
711                                 bsdf->smooth = param2;
712                                 
713                                 if(type == CLOSURE_BSDF_DIFFUSE_TOON_ID)
714                                         sd->flag |= bsdf_diffuse_toon_setup(bsdf);
715                                 else
716                                         sd->flag |= bsdf_glossy_toon_setup(bsdf);
717                         }
718                         break;
719                 }
720 #ifdef __HAIR__
721                 case CLOSURE_BSDF_HAIR_REFLECTION_ID:
722                 case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
723                         float3 weight = sd->svm_closure_weight * mix_weight;
724                         
725                         if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
726                                 /* todo: giving a fixed weight here will cause issues when
727                                  * mixing multiple BSDFS. energy will not be conserved and
728                                  * the throughput can blow up after multiple bounces. we
729                                  * better figure out a way to skip backfaces from rays
730                                  * spawned by transmission from the front */
731                                 bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f));
732                         }
733                         else {
734                                 HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight);
735
736                                 if(bsdf) {
737                                         bsdf->N = N;
738                                         bsdf->roughness1 = param1;
739                                         bsdf->roughness2 = param2;
740                                         bsdf->offset = -stack_load_float(stack, data_node.z);
741
742                                         if(stack_valid(data_node.y)) {
743                                                 bsdf->T = normalize(stack_load_float3(stack, data_node.y));
744                                         }
745                                         else if(!(sd->type & PRIMITIVE_ALL_CURVE)) {
746                                                 bsdf->T = normalize(sd->dPdv);
747                                                 bsdf->offset = 0.0f;
748                                         }
749                                         else
750                                                 bsdf->T = normalize(sd->dPdu);
751
752                                         if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
753                                                 sd->flag |= bsdf_hair_reflection_setup(bsdf);
754                                         }
755                                         else {
756                                                 sd->flag |= bsdf_hair_transmission_setup(bsdf);
757                                         }
758                                 }
759                         }
760
761                         break;
762                 }
763 #endif
764
765 #ifdef __SUBSURFACE__
766                 case CLOSURE_BSSRDF_CUBIC_ID:
767                 case CLOSURE_BSSRDF_GAUSSIAN_ID:
768                 case CLOSURE_BSSRDF_BURLEY_ID:
769                 case CLOSURE_BSSRDF_RANDOM_WALK_ID: {
770                         float3 weight = sd->svm_closure_weight * mix_weight;
771                         Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
772
773                         if(bssrdf) {
774                                 /* disable in case of diffuse ancestor, can't see it well then and
775                                  * adds considerably noise due to probabilities of continuing path
776                                  * getting lower and lower */
777                                 if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
778                                         param1 = 0.0f;
779
780                                 bssrdf->radius = stack_load_float3(stack, data_node.z)*param1;
781                                 bssrdf->albedo = sd->svm_closure_weight;
782                                 bssrdf->texture_blur = param2;
783                                 bssrdf->sharpness = stack_load_float(stack, data_node.w);
784                                 bssrdf->N = N;
785                                 bssrdf->roughness = 0.0f;
786                                 sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
787                         }
788
789                         break;
790                 }
791 #endif
792                 default:
793                         break;
794         }
795 }
796
797 ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag)
798 {
799 #ifdef __VOLUME__
800         /* Only sum extinction for volumes, variable is shared with surface transparency. */
801         if(shader_type != SHADER_TYPE_VOLUME) {
802                 return;
803         }
804
805         uint type, param1_offset, param2_offset;
806
807         uint mix_weight_offset;
808         decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
809         float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
810
811         if(mix_weight == 0.0f)
812                 return;
813
814         float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
815
816         /* Compute scattering coefficient. */
817         float density = mix_weight * fmaxf(param1, 0.0f);
818         float3 weight = sd->svm_closure_weight;
819
820         if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
821                 weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
822         }
823
824         weight *= density;
825
826         /* Add closure for volume scattering. */
827         if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
828                 float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
829                 HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
830
831                 if(volume) {
832                         volume->g = param2; /* g */
833                         sd->flag |= volume_henyey_greenstein_setup(volume);
834                 }
835         }
836
837         /* Sum total extinction weight. */
838         volume_extinction_setup(sd, weight);
839 #endif
840 }
841
842 ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
843 {
844         uint mix_weight_offset = node.y;
845         float3 weight = sd->svm_closure_weight;
846
847         if(stack_valid(mix_weight_offset)) {
848                 float mix_weight = stack_load_float(stack, mix_weight_offset);
849
850                 if(mix_weight == 0.0f)
851                         return;
852
853                 weight *= mix_weight;
854         }
855
856         emission_setup(sd, weight);
857 }
858
859 ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
860 {
861         uint mix_weight_offset = node.y;
862         float3 weight = sd->svm_closure_weight;
863
864         if(stack_valid(mix_weight_offset)) {
865                 float mix_weight = stack_load_float(stack, mix_weight_offset);
866
867                 if(mix_weight == 0.0f)
868                         return;
869
870                 weight *= mix_weight;
871         }
872
873         background_setup(sd, weight);
874 }
875
876 ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
877 {
878         uint mix_weight_offset = node.y;
879
880         if(stack_valid(mix_weight_offset)) {
881                 float mix_weight = stack_load_float(stack, mix_weight_offset);
882
883                 if(mix_weight == 0.0f)
884                         return;
885
886                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
887         }
888         else
889                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
890
891         sd->flag |= SD_HOLDOUT;
892 }
893
894 ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
895 {
896         uint mix_weight_offset = node.y;
897
898         if(stack_valid(mix_weight_offset)) {
899                 float mix_weight = stack_load_float(stack, mix_weight_offset);
900
901                 if(mix_weight == 0.0f)
902                         return;
903
904                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight * mix_weight);
905         }
906         else
907                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight);
908
909         sd->flag |= SD_AO;
910 }
911
912 /* Closure Nodes */
913
914 ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
915 {
916         sd->svm_closure_weight = weight;
917 }
918
919 ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
920 {
921         float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
922         svm_node_closure_store_weight(sd, weight);
923 }
924
925 ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
926 {
927         float3 weight = stack_load_float3(stack, weight_offset);
928
929         svm_node_closure_store_weight(sd, weight);
930 }
931
932 ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
933 {
934         uint color_offset = node.y;
935         uint strength_offset = node.z;
936
937         float strength = stack_load_float(stack, strength_offset);
938         float3 weight = stack_load_float3(stack, color_offset)*strength;
939
940         svm_node_closure_store_weight(sd, weight);
941 }
942
943 ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
944 {
945         /* fetch weight from blend input, previous mix closures,
946          * and write to stack to be used by closure nodes later */
947         uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
948         decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
949
950         float weight = stack_load_float(stack, weight_offset);
951         weight = saturate(weight);
952
953         float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f;
954
955         if(stack_valid(weight1_offset))
956                 stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
957         if(stack_valid(weight2_offset))
958                 stack_store_float(stack, weight2_offset, in_weight*weight);
959 }
960
961 /* (Bump) normal */
962
963 ccl_device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
964 {
965         float3 normal = stack_load_float3(stack, in_direction);
966         sd->N = normal;
967         stack_store_float3(stack, out_normal, normal);
968 }
969
970 CCL_NAMESPACE_END
971