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