f013dc396d08a29b7ac0eb40ab841a3bb9d55659
[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                                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
337                                                         bsdf->extra = NULL;
338
339                                                         if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID)
340                                                                 transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness);
341                                                         else
342                                                                 transmission_roughness = refl_roughness;
343
344                                                         bsdf->alpha_x = transmission_roughness * transmission_roughness;
345                                                         bsdf->alpha_y = transmission_roughness * transmission_roughness;
346                                                         bsdf->ior = ior;
347
348                                                         /* setup bsdf */
349                                                         sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
350                                                 }
351                                         }
352                                         else { /* use multi-scatter GGX */
353                                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight);
354                                                 if(!bsdf) {
355                                                         break;
356                                                 }
357
358                                                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
359                                                 if(!extra) {
360                                                         break;
361                                                 }
362
363                                                 bsdf->N = N;
364                                                 bsdf->extra = extra;
365                                                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
366
367                                                 bsdf->alpha_x = roughness * roughness;
368                                                 bsdf->alpha_y = roughness * roughness;
369                                                 bsdf->ior = ior;
370
371                                                 bsdf->extra->color = base_color;
372                                                 bsdf->extra->cspec0 = cspec0;
373                                                 bsdf->extra->clearcoat = 0.0f;
374
375                                                 /* setup bsdf */
376                                                 sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
377                                         }
378                                 }
379 #ifdef __CAUSTICS_TRICKS__
380                         }
381 #endif
382
383                         /* clearcoat */
384 #ifdef __CAUSTICS_TRICKS__
385                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) {
386 #endif
387                                 if(clearcoat > CLOSURE_WEIGHT_CUTOFF) {
388                                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
389                                         if(!bsdf) {
390                                                 break;
391                                         }
392
393                                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
394                                         if(!extra) {
395                                                 break;
396                                         }
397
398                                         bsdf->N = clearcoat_normal;
399                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
400                                         bsdf->ior = 1.5f;
401                                         bsdf->extra = extra;
402
403                                         bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness;
404                                         bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness;
405
406                                         bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
407                                         bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
408                                         bsdf->extra->clearcoat = clearcoat;
409
410                                         /* setup bsdf */
411                                         sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
412                                 }
413 #ifdef __CAUSTICS_TRICKS__
414                         }
415 #endif
416
417                         break;
418                 }
419 #endif  /* __PRINCIPLED__ */
420                 case CLOSURE_BSDF_DIFFUSE_ID: {
421                         float3 weight = sd->svm_closure_weight * mix_weight;
422                         OrenNayarBsdf *bsdf = (OrenNayarBsdf*)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight);
423
424                         if(bsdf) {
425                                 bsdf->N = N;
426
427                                 float roughness = param1;
428
429                                 if(roughness == 0.0f) {
430                                         sd->flag |= bsdf_diffuse_setup((DiffuseBsdf*)bsdf);
431                                 }
432                                 else {
433                                         bsdf->roughness = roughness;
434                                         sd->flag |= bsdf_oren_nayar_setup(bsdf);
435                                 }
436                         }
437                         break;
438                 }
439                 case CLOSURE_BSDF_TRANSLUCENT_ID: {
440                         float3 weight = sd->svm_closure_weight * mix_weight;
441                         DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight);
442
443                         if(bsdf) {
444                                 bsdf->N = N;
445                                 sd->flag |= bsdf_translucent_setup(bsdf);
446                         }
447                         break;
448                 }
449                 case CLOSURE_BSDF_TRANSPARENT_ID: {
450                         float3 weight = sd->svm_closure_weight * mix_weight;
451                         bsdf_transparent_setup(sd, weight);
452                         break;
453                 }
454                 case CLOSURE_BSDF_REFLECTION_ID:
455                 case CLOSURE_BSDF_MICROFACET_GGX_ID:
456                 case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
457                 case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
458                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: {
459 #ifdef __CAUSTICS_TRICKS__
460                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
461                                 break;
462 #endif
463                         float3 weight = sd->svm_closure_weight * mix_weight;
464                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
465
466                         if(!bsdf) {
467                                 break;
468                         }
469
470                         bsdf->N = N;
471                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
472                         bsdf->alpha_x = param1;
473                         bsdf->alpha_y = param1;
474                         bsdf->ior = 0.0f;
475                         bsdf->extra = NULL;
476
477                         /* setup bsdf */
478                         if(type == CLOSURE_BSDF_REFLECTION_ID)
479                                 sd->flag |= bsdf_reflection_setup(bsdf);
480                         else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
481                                 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
482                         else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID)
483                                 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
484                         else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
485                                 kernel_assert(stack_valid(data_node.z));
486                                 bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
487                                 if(bsdf->extra) {
488                                         bsdf->extra->color = stack_load_float3(stack, data_node.z);
489                                         bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
490                                         bsdf->extra->clearcoat = 0.0f;
491                                         sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
492                                 }
493                         }
494                         else {
495                                 sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
496                         }
497
498                         break;
499                 }
500                 case CLOSURE_BSDF_REFRACTION_ID:
501                 case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
502                 case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
503 #ifdef __CAUSTICS_TRICKS__
504                         if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
505                                 break;
506 #endif
507                         float3 weight = sd->svm_closure_weight * mix_weight;
508                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
509
510                         if(bsdf) {
511                                 bsdf->N = N;
512                                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
513                                 bsdf->extra = NULL;
514
515                                 float eta = fmaxf(param2, 1e-5f);
516                                 eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
517
518                                 /* setup bsdf */
519                                 if(type == CLOSURE_BSDF_REFRACTION_ID) {
520                                         bsdf->alpha_x = 0.0f;
521                                         bsdf->alpha_y = 0.0f;
522                                         bsdf->ior = eta;
523
524                                         sd->flag |= bsdf_refraction_setup(bsdf);
525                                 }
526                                 else {
527                                         bsdf->alpha_x = param1;
528                                         bsdf->alpha_y = param1;
529                                         bsdf->ior = eta;
530
531                                         if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
532                                                 sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
533                                         else
534                                                 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
535                                 }
536                         }
537
538                         break;
539                 }
540                 case CLOSURE_BSDF_SHARP_GLASS_ID:
541                 case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
542                 case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
543 #ifdef __CAUSTICS_TRICKS__
544                         if(!kernel_data.integrator.caustics_reflective &&
545                            !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
546                         {
547                                 break;
548                         }
549 #endif
550                         float3 weight = sd->svm_closure_weight * mix_weight;
551
552                         /* index of refraction */
553                         float eta = fmaxf(param2, 1e-5f);
554                         eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
555
556                         /* fresnel */
557                         float cosNO = dot(N, sd->I);
558                         float fresnel = fresnel_dielectric_cos(cosNO, eta);
559                         float roughness = param1;
560
561                         /* reflection */
562 #ifdef __CAUSTICS_TRICKS__
563                         if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0)
564 #endif
565                         {
566                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*fresnel);
567
568                                 if(bsdf) {
569                                         bsdf->N = N;
570                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
571                                         bsdf->extra = NULL;
572                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, false);
573                                 }
574                         }
575
576                         /* refraction */
577 #ifdef __CAUSTICS_TRICKS__
578                         if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0)
579 #endif
580                         {
581                                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*(1.0f - fresnel));
582
583                                 if(bsdf) {
584                                         bsdf->N = N;
585                                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
586                                         bsdf->extra = NULL;
587                                         svm_node_glass_setup(sd, bsdf, type, eta, roughness, true);
588                                 }
589                         }
590
591                         break;
592                 }
593                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: {
594 #ifdef __CAUSTICS_TRICKS__
595                         if(!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE))
596                                 break;
597 #endif
598                         float3 weight = sd->svm_closure_weight * mix_weight;
599                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
600                         if(!bsdf) {
601                                 break;
602                         }
603
604                         MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
605                         if(!extra) {
606                                 break;
607                         }
608
609                         bsdf->N = N;
610                         bsdf->extra = extra;
611                         bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
612
613                         bsdf->alpha_x = param1;
614                         bsdf->alpha_y = param1;
615                         float eta = fmaxf(param2, 1e-5f);
616                         bsdf->ior = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
617
618                         kernel_assert(stack_valid(data_node.z));
619                         bsdf->extra->color = stack_load_float3(stack, data_node.z);
620                         bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
621                         bsdf->extra->clearcoat = 0.0f;
622
623                         /* setup bsdf */
624                         sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
625                         break;
626                 }
627                 case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
628                 case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
629                 case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
630                 case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
631 #ifdef __CAUSTICS_TRICKS__
632                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
633                                 break;
634 #endif
635                         float3 weight = sd->svm_closure_weight * mix_weight;
636                         MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
637
638                         if(bsdf) {
639                                 bsdf->N = N;
640                                 bsdf->extra = NULL;
641                                 bsdf->T = stack_load_float3(stack, data_node.y);
642
643                                 /* rotate tangent */
644                                 float rotation = stack_load_float(stack, data_node.z);
645
646                                 if(rotation != 0.0f)
647                                         bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
648
649                                 /* compute roughness */
650                                 float roughness = param1;
651                                 float anisotropy = clamp(param2, -0.99f, 0.99f);
652
653                                 if(anisotropy < 0.0f) {
654                                         bsdf->alpha_x = roughness/(1.0f + anisotropy);
655                                         bsdf->alpha_y = roughness*(1.0f + anisotropy);
656                                 }
657                                 else {
658                                         bsdf->alpha_x = roughness*(1.0f - anisotropy);
659                                         bsdf->alpha_y = roughness/(1.0f - anisotropy);
660                                 }
661
662                                 bsdf->ior = 0.0f;
663
664                                 if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
665                                         sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
666                                 }
667                                 else if(type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
668                                         sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
669                                 }
670                                 else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
671                                         kernel_assert(stack_valid(data_node.w));
672                                         bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
673                                         if(bsdf->extra) {
674                                                 bsdf->extra->color = stack_load_float3(stack, data_node.w);
675                                                 bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
676                                                 bsdf->extra->clearcoat = 0.0f;
677                                                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
678                                         }
679                                 }
680                                 else
681                                         sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
682                         }
683                         break;
684                 }
685                 case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
686                         float3 weight = sd->svm_closure_weight * mix_weight;
687                         VelvetBsdf *bsdf = (VelvetBsdf*)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
688
689                         if(bsdf) {
690                                 bsdf->N = N;
691
692                                 bsdf->sigma = saturate(param1);
693                                 sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf);
694                         }
695                         break;
696                 }
697                 case CLOSURE_BSDF_GLOSSY_TOON_ID:
698 #ifdef __CAUSTICS_TRICKS__
699                         if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
700                                 break;
701                         ATTR_FALLTHROUGH;
702 #endif
703                 case CLOSURE_BSDF_DIFFUSE_TOON_ID: {
704                         float3 weight = sd->svm_closure_weight * mix_weight;
705                         ToonBsdf *bsdf = (ToonBsdf*)bsdf_alloc(sd, sizeof(ToonBsdf), weight);
706
707                         if(bsdf) {
708                                 bsdf->N = N;
709                                 bsdf->size = param1;
710                                 bsdf->smooth = param2;
711                                 
712                                 if(type == CLOSURE_BSDF_DIFFUSE_TOON_ID)
713                                         sd->flag |= bsdf_diffuse_toon_setup(bsdf);
714                                 else
715                                         sd->flag |= bsdf_glossy_toon_setup(bsdf);
716                         }
717                         break;
718                 }
719 #ifdef __HAIR__
720                 case CLOSURE_BSDF_HAIR_REFLECTION_ID:
721                 case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: {
722                         float3 weight = sd->svm_closure_weight * mix_weight;
723                         
724                         if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) {
725                                 /* todo: giving a fixed weight here will cause issues when
726                                  * mixing multiple BSDFS. energy will not be conserved and
727                                  * the throughput can blow up after multiple bounces. we
728                                  * better figure out a way to skip backfaces from rays
729                                  * spawned by transmission from the front */
730                                 bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f));
731                         }
732                         else {
733                                 HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight);
734
735                                 if(bsdf) {
736                                         bsdf->N = N;
737                                         bsdf->roughness1 = param1;
738                                         bsdf->roughness2 = param2;
739                                         bsdf->offset = -stack_load_float(stack, data_node.z);
740
741                                         if(stack_valid(data_node.y)) {
742                                                 bsdf->T = normalize(stack_load_float3(stack, data_node.y));
743                                         }
744                                         else if(!(sd->type & PRIMITIVE_ALL_CURVE)) {
745                                                 bsdf->T = normalize(sd->dPdv);
746                                                 bsdf->offset = 0.0f;
747                                         }
748                                         else
749                                                 bsdf->T = normalize(sd->dPdu);
750
751                                         if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
752                                                 sd->flag |= bsdf_hair_reflection_setup(bsdf);
753                                         }
754                                         else {
755                                                 sd->flag |= bsdf_hair_transmission_setup(bsdf);
756                                         }
757                                 }
758                         }
759
760                         break;
761                 }
762 #endif
763
764 #ifdef __SUBSURFACE__
765                 case CLOSURE_BSSRDF_CUBIC_ID:
766                 case CLOSURE_BSSRDF_GAUSSIAN_ID:
767                 case CLOSURE_BSSRDF_BURLEY_ID:
768                 case CLOSURE_BSSRDF_RANDOM_WALK_ID: {
769                         float3 weight = sd->svm_closure_weight * mix_weight;
770                         Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
771
772                         if(bssrdf) {
773                                 /* disable in case of diffuse ancestor, can't see it well then and
774                                  * adds considerably noise due to probabilities of continuing path
775                                  * getting lower and lower */
776                                 if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
777                                         param1 = 0.0f;
778
779                                 bssrdf->radius = stack_load_float3(stack, data_node.z)*param1;
780                                 bssrdf->albedo = sd->svm_closure_weight;
781                                 bssrdf->texture_blur = param2;
782                                 bssrdf->sharpness = stack_load_float(stack, data_node.w);
783                                 bssrdf->N = N;
784                                 sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
785                         }
786
787                         break;
788                 }
789 #endif
790                 default:
791                         break;
792         }
793 }
794
795 ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag)
796 {
797 #ifdef __VOLUME__
798         /* Only sum extinction for volumes, variable is shared with surface transparency. */
799         if(shader_type != SHADER_TYPE_VOLUME) {
800                 return;
801         }
802
803         uint type, param1_offset, param2_offset;
804
805         uint mix_weight_offset;
806         decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
807         float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
808
809         if(mix_weight == 0.0f)
810                 return;
811
812         float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
813
814         /* Compute scattering coefficient. */
815         float density = mix_weight * fmaxf(param1, 0.0f);
816         float3 weight = sd->svm_closure_weight;
817
818         if(type == CLOSURE_VOLUME_ABSORPTION_ID) {
819                 weight = make_float3(1.0f, 1.0f, 1.0f) - weight;
820         }
821
822         weight *= density;
823
824         /* Add closure for volume scattering. */
825         if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) {
826                 float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
827                 HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight);
828
829                 if(volume) {
830                         volume->g = param2; /* g */
831                         sd->flag |= volume_henyey_greenstein_setup(volume);
832                 }
833         }
834
835         /* Sum total extinction weight. */
836         volume_extinction_setup(sd, weight);
837 #endif
838 }
839
840 ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
841 {
842         uint mix_weight_offset = node.y;
843         float3 weight = sd->svm_closure_weight;
844
845         if(stack_valid(mix_weight_offset)) {
846                 float mix_weight = stack_load_float(stack, mix_weight_offset);
847
848                 if(mix_weight == 0.0f)
849                         return;
850
851                 weight *= mix_weight;
852         }
853
854         emission_setup(sd, weight);
855 }
856
857 ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
858 {
859         uint mix_weight_offset = node.y;
860         float3 weight = sd->svm_closure_weight;
861
862         if(stack_valid(mix_weight_offset)) {
863                 float mix_weight = stack_load_float(stack, mix_weight_offset);
864
865                 if(mix_weight == 0.0f)
866                         return;
867
868                 weight *= mix_weight;
869         }
870
871         background_setup(sd, weight);
872 }
873
874 ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
875 {
876         uint mix_weight_offset = node.y;
877
878         if(stack_valid(mix_weight_offset)) {
879                 float mix_weight = stack_load_float(stack, mix_weight_offset);
880
881                 if(mix_weight == 0.0f)
882                         return;
883
884                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight);
885         }
886         else
887                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight);
888
889         sd->flag |= SD_HOLDOUT;
890 }
891
892 ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
893 {
894         uint mix_weight_offset = node.y;
895
896         if(stack_valid(mix_weight_offset)) {
897                 float mix_weight = stack_load_float(stack, mix_weight_offset);
898
899                 if(mix_weight == 0.0f)
900                         return;
901
902                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight * mix_weight);
903         }
904         else
905                 closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_AMBIENT_OCCLUSION_ID, sd->svm_closure_weight);
906
907         sd->flag |= SD_AO;
908 }
909
910 /* Closure Nodes */
911
912 ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
913 {
914         sd->svm_closure_weight = weight;
915 }
916
917 ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
918 {
919         float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b));
920         svm_node_closure_store_weight(sd, weight);
921 }
922
923 ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset)
924 {
925         float3 weight = stack_load_float3(stack, weight_offset);
926
927         svm_node_closure_store_weight(sd, weight);
928 }
929
930 ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
931 {
932         uint color_offset = node.y;
933         uint strength_offset = node.z;
934
935         float strength = stack_load_float(stack, strength_offset);
936         float3 weight = stack_load_float3(stack, color_offset)*strength;
937
938         svm_node_closure_store_weight(sd, weight);
939 }
940
941 ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
942 {
943         /* fetch weight from blend input, previous mix closures,
944          * and write to stack to be used by closure nodes later */
945         uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
946         decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset);
947
948         float weight = stack_load_float(stack, weight_offset);
949         weight = saturate(weight);
950
951         float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f;
952
953         if(stack_valid(weight1_offset))
954                 stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
955         if(stack_valid(weight2_offset))
956                 stack_store_float(stack, weight2_offset, in_weight*weight);
957 }
958
959 /* (Bump) normal */
960
961 ccl_device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
962 {
963         float3 normal = stack_load_float3(stack, in_direction);
964         sd->N = normal;
965         stack_store_float3(stack, out_normal, normal);
966 }
967
968 CCL_NAMESPACE_END
969