Fix T62892 EEVEE HDRI lightning glitch
[blender.git] / source / blender / gpu / shaders / gpu_shader_material.glsl
1
2 uniform mat4 ModelViewMatrix;
3 uniform mat4 ModelViewMatrixInverse;
4 uniform mat3 NormalMatrix;
5 uniform mat3 NormalMatrixInverse;
6
7 #ifndef USE_ATTR
8 uniform mat4 ModelMatrix;
9 uniform mat4 ModelMatrixInverse;
10 #endif
11
12 /* Converters */
13
14 float convert_rgba_to_float(vec4 color)
15 {
16         return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
17 }
18
19 float exp_blender(float f)
20 {
21         return pow(2.71828182846, f);
22 }
23
24 float compatible_pow(float x, float y)
25 {
26         if (y == 0.0) /* x^0 -> 1, including 0^0 */
27                 return 1.0;
28
29         /* glsl pow doesn't accept negative x */
30         if (x < 0.0) {
31                 if (mod(-y, 2.0) == 0.0)
32                         return pow(-x, y);
33                 else
34                         return -pow(-x, y);
35         }
36         else if (x == 0.0)
37                 return 0.0;
38
39         return pow(x, y);
40 }
41
42 void rgb_to_hsv(vec4 rgb, out vec4 outcol)
43 {
44         float cmax, cmin, h, s, v, cdelta;
45         vec3 c;
46
47         cmax = max(rgb[0], max(rgb[1], rgb[2]));
48         cmin = min(rgb[0], min(rgb[1], rgb[2]));
49         cdelta = cmax - cmin;
50
51         v = cmax;
52         if (cmax != 0.0)
53                 s = cdelta / cmax;
54         else {
55                 s = 0.0;
56                 h = 0.0;
57         }
58
59         if (s == 0.0) {
60                 h = 0.0;
61         }
62         else {
63                 c = (vec3(cmax) - rgb.xyz) / cdelta;
64
65                 if (rgb.x == cmax) h = c[2] - c[1];
66                 else if (rgb.y == cmax) h = 2.0 + c[0] -  c[2];
67                 else h = 4.0 + c[1] - c[0];
68
69                 h /= 6.0;
70
71                 if (h < 0.0)
72                         h += 1.0;
73         }
74
75         outcol = vec4(h, s, v, rgb.w);
76 }
77
78 void hsv_to_rgb(vec4 hsv, out vec4 outcol)
79 {
80         float i, f, p, q, t, h, s, v;
81         vec3 rgb;
82
83         h = hsv[0];
84         s = hsv[1];
85         v = hsv[2];
86
87         if (s == 0.0) {
88                 rgb = vec3(v, v, v);
89         }
90         else {
91                 if (h == 1.0)
92                         h = 0.0;
93
94                 h *= 6.0;
95                 i = floor(h);
96                 f = h - i;
97                 rgb = vec3(f, f, f);
98                 p = v * (1.0 - s);
99                 q = v * (1.0 - (s * f));
100                 t = v * (1.0 - (s * (1.0 - f)));
101
102                 if (i == 0.0) rgb = vec3(v, t, p);
103                 else if (i == 1.0) rgb = vec3(q, v, p);
104                 else if (i == 2.0) rgb = vec3(p, v, t);
105                 else if (i == 3.0) rgb = vec3(p, q, v);
106                 else if (i == 4.0) rgb = vec3(t, p, v);
107                 else rgb = vec3(v, p, q);
108         }
109
110         outcol = vec4(rgb, hsv.w);
111 }
112
113 float srgb_to_linearrgb(float c)
114 {
115         if (c < 0.04045)
116                 return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
117         else
118                 return pow((c + 0.055) * (1.0 / 1.055), 2.4);
119 }
120
121 float linearrgb_to_srgb(float c)
122 {
123         if (c < 0.0031308)
124                 return (c < 0.0) ? 0.0 : c * 12.92;
125         else
126                 return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
127 }
128
129 void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
130 {
131         col_to.r = srgb_to_linearrgb(col_from.r);
132         col_to.g = srgb_to_linearrgb(col_from.g);
133         col_to.b = srgb_to_linearrgb(col_from.b);
134         col_to.a = col_from.a;
135 }
136
137 void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
138 {
139         col_to.r = linearrgb_to_srgb(col_from.r);
140         col_to.g = linearrgb_to_srgb(col_from.g);
141         col_to.b = linearrgb_to_srgb(col_from.b);
142         col_to.a = col_from.a;
143 }
144
145 void color_to_normal_new_shading(vec3 color, out vec3 normal)
146 {
147         normal = vec3(2.0) * color - vec3(1.0);
148 }
149
150 void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
151 {
152         normal = vec3(2.0, -2.0, -2.0) * color - vec3(1.0);
153 }
154
155 #ifndef M_PI
156 #define M_PI 3.14159265358979323846
157 #endif
158 #ifndef M_1_PI
159 #define M_1_PI 0.318309886183790671538
160 #endif
161
162 /*********** SHADER NODES ***************/
163
164 void particle_info(
165         vec4 sprops, vec4 loc, vec3 vel, vec3 avel,
166         out float index, out float random, out float age,
167         out float life_time, out vec3 location,
168         out float size, out vec3 velocity, out vec3 angular_velocity)
169 {
170         index = sprops.x;
171         random = loc.w;
172         age = sprops.y;
173         life_time = sprops.z;
174         size = sprops.w;
175
176         location = loc.xyz;
177         velocity = vel;
178         angular_velocity = avel;
179 }
180
181 void vect_normalize(vec3 vin, out vec3 vout)
182 {
183         vout = normalize(vin);
184 }
185
186 void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
187 {
188         vout = (mat * vec4(vin, 0.0)).xyz;
189 }
190
191 void mat3_mul(vec3 vin, mat3 mat, out vec3 vout)
192 {
193         vout = mat * vin;
194 }
195
196 void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
197 {
198         vout = (mat * vec4(vin, 1.0)).xyz;
199 }
200
201 void point_texco_remap_square(vec3 vin, out vec3 vout)
202 {
203         vout = vin * 2.0 - 1.0;
204 }
205
206 void point_texco_clamp(vec3 vin, sampler2D ima, out vec3 vout)
207 {
208         vec2 half_texel_size = 0.5 / vec2(textureSize(ima, 0).xy);
209         vout = clamp(vin, half_texel_size.xyy, 1.0 - half_texel_size.xyy);
210 }
211
212 void point_map_to_sphere(vec3 vin, out vec3 vout)
213 {
214         float len = length(vin);
215         float v, u;
216         if (len > 0.0) {
217                 if (vin.x == 0.0 && vin.y == 0.0)
218                         u = 0.0;
219                 else
220                         u = (1.0 - atan(vin.x, vin.y) / M_PI) / 2.0;
221
222                 v = 1.0 - acos(vin.z / len) / M_PI;
223         }
224         else
225                 v = u = 0.0;
226
227         vout = vec3(u, v, 0.0);
228 }
229
230 void point_map_to_tube(vec3 vin, out vec3 vout)
231 {
232         float u, v;
233         v = (vin.z + 1.0) * 0.5;
234         float len = sqrt(vin.x * vin.x + vin.y * vin[1]);
235         if (len > 0.0)
236                 u = (1.0 - (atan(vin.x / len, vin.y / len) / M_PI)) * 0.5;
237         else
238                 v = u = 0.0;
239
240         vout = vec3(u, v, 0.0);
241 }
242
243 void mapping(vec3 vec, vec4 m0, vec4 m1, vec4 m2, vec4 m3, vec3 minvec, vec3 maxvec, out vec3 outvec)
244 {
245         mat4 mat = mat4(m0, m1, m2, m3);
246         outvec = (mat * vec4(vec, 1.0)).xyz;
247         outvec = clamp(outvec, minvec, maxvec);
248 }
249
250 void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
251 {
252         outdepth = abs(co.z);
253         outdist = length(co);
254         outview = normalize(co);
255 }
256
257 void math_add(float val1, float val2, out float outval)
258 {
259         outval = val1 + val2;
260 }
261
262 void math_subtract(float val1, float val2, out float outval)
263 {
264         outval = val1 - val2;
265 }
266
267 void math_multiply(float val1, float val2, out float outval)
268 {
269         outval = val1 * val2;
270 }
271
272 void math_divide(float val1, float val2, out float outval)
273 {
274         if (val2 == 0.0)
275                 outval = 0.0;
276         else
277                 outval = val1 / val2;
278 }
279
280 void math_sine(float val, out float outval)
281 {
282         outval = sin(val);
283 }
284
285 void math_cosine(float val, out float outval)
286 {
287         outval = cos(val);
288 }
289
290 void math_tangent(float val, out float outval)
291 {
292         outval = tan(val);
293 }
294
295 void math_asin(float val, out float outval)
296 {
297         if (val <= 1.0 && val >= -1.0)
298                 outval = asin(val);
299         else
300                 outval = 0.0;
301 }
302
303 void math_acos(float val, out float outval)
304 {
305         if (val <= 1.0 && val >= -1.0)
306                 outval = acos(val);
307         else
308                 outval = 0.0;
309 }
310
311 void math_atan(float val, out float outval)
312 {
313         outval = atan(val);
314 }
315
316 void math_pow(float val1, float val2, out float outval)
317 {
318         if (val1 >= 0.0) {
319                 outval = compatible_pow(val1, val2);
320         }
321         else {
322                 float val2_mod_1 = mod(abs(val2), 1.0);
323
324                 if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
325                         outval = compatible_pow(val1, floor(val2 + 0.5));
326                 else
327                         outval = 0.0;
328         }
329 }
330
331 void math_log(float val1, float val2, out float outval)
332 {
333         if (val1 > 0.0  && val2 > 0.0)
334                 outval = log2(val1) / log2(val2);
335         else
336                 outval = 0.0;
337 }
338
339 void math_max(float val1, float val2, out float outval)
340 {
341         outval = max(val1, val2);
342 }
343
344 void math_min(float val1, float val2, out float outval)
345 {
346         outval = min(val1, val2);
347 }
348
349 void math_round(float val, out float outval)
350 {
351         outval = floor(val + 0.5);
352 }
353
354 void math_less_than(float val1, float val2, out float outval)
355 {
356         if (val1 < val2)
357                 outval = 1.0;
358         else
359                 outval = 0.0;
360 }
361
362 void math_greater_than(float val1, float val2, out float outval)
363 {
364         if (val1 > val2)
365                 outval = 1.0;
366         else
367                 outval = 0.0;
368 }
369
370 void math_modulo(float val1, float val2, out float outval)
371 {
372         if (val2 == 0.0)
373                 outval = 0.0;
374         else
375                 outval = mod(val1, val2);
376
377         /* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
378          * see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
379         outval = (val1 > 0.0) ? outval : outval - val2;
380 }
381
382 void math_abs(float val1, out float outval)
383 {
384         outval = abs(val1);
385 }
386
387 void math_atan2(float val1, float val2, out float outval)
388 {
389         outval = atan(val1, val2);
390 }
391
392 void math_floor(float val, out float outval)
393 {
394         outval = floor(val);
395 }
396
397 void math_ceil(float val, out float outval)
398 {
399         outval = ceil(val);
400 }
401
402 void math_fract(float val, out float outval)
403 {
404         outval = val - floor(val);
405 }
406
407 void math_sqrt(float val, out float outval)
408 {
409         if (val > 0.0)
410                 outval = sqrt(val);
411         else
412                 outval = 0.0;
413 }
414
415 void squeeze(float val, float width, float center, out float outval)
416 {
417         outval = 1.0 / (1.0 + pow(2.71828183, -((val - center) * width)));
418 }
419
420 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
421 {
422         outvec = v1 + v2;
423         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
424 }
425
426 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
427 {
428         outvec = v1 - v2;
429         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
430 }
431
432 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
433 {
434         outvec = v1 + v2;
435         outval = length(outvec);
436         outvec = normalize(outvec);
437 }
438 void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec)
439 {
440         outvec = strength * v1 + (1 - strength) * v2;
441 }
442
443 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
444 {
445         outvec = vec3(0);
446         outval = dot(v1, v2);
447 }
448
449 void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
450 {
451         outvec = cross(v1, v2);
452         outval = length(outvec);
453         outvec /= outval;
454 }
455
456 void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
457 {
458         outval = length(v);
459         outvec = normalize(v);
460 }
461
462 void vec_math_negate(vec3 v, out vec3 outv)
463 {
464         outv = -v;
465 }
466
467 void invert_z(vec3 v, out vec3 outv)
468 {
469         v.z = -v.z;
470         outv = v;
471 }
472
473 void normal_new_shading(vec3 nor, vec3 dir, out vec3 outnor, out float outdot)
474 {
475         outnor = dir;
476         outdot = dot(normalize(nor), dir);
477 }
478
479 void curves_vec(float fac, vec3 vec, sampler1DArray curvemap, float layer, out vec3 outvec)
480 {
481         vec4 co = vec4(vec * 0.5 + 0.5, layer);
482         outvec.x = texture(curvemap, co.xw).x;
483         outvec.y = texture(curvemap, co.yw).y;
484         outvec.z = texture(curvemap, co.zw).z;
485         outvec = mix(vec, outvec, fac);
486 }
487
488 /* ext is vec4(in_x, in_dy, out_x, out_dy). */
489 float curve_extrapolate(float x, float y, vec4 ext)
490 {
491         if (x < 0.0) {
492                 return y + x * ext.y;
493         }
494         else if (x > 1.0) {
495                 return y + (x - 1.0) * ext.w;
496         }
497         else {
498                 return y;
499         }
500 }
501
502 #define RANGE_RESCALE(x, min, range) ((x - min) * range)
503
504 void curves_rgb(
505         float fac, vec4 col, sampler1DArray curvemap, float layer,
506         vec4 range, vec4 ext_r, vec4 ext_g, vec4 ext_b, vec4 ext_a,
507         out vec4 outcol)
508 {
509         vec4 co = vec4(RANGE_RESCALE(col.rgb, ext_a.x, range.a), layer);
510         vec3 samp;
511         samp.r = texture(curvemap, co.xw).a;
512         samp.g = texture(curvemap, co.yw).a;
513         samp.b = texture(curvemap, co.zw).a;
514
515         samp.r = curve_extrapolate(co.x, samp.r, ext_a);
516         samp.g = curve_extrapolate(co.y, samp.g, ext_a);
517         samp.b = curve_extrapolate(co.z, samp.b, ext_a);
518
519         vec3 rgb_min = vec3(ext_r.x, ext_g.x, ext_b.x);
520         co.xyz = RANGE_RESCALE(samp.rgb, rgb_min, range.rgb);
521
522         samp.r = texture(curvemap, co.xw).r;
523         samp.g = texture(curvemap, co.yw).g;
524         samp.b = texture(curvemap, co.zw).b;
525
526         outcol.r = curve_extrapolate(co.x, samp.r, ext_r);
527         outcol.g = curve_extrapolate(co.y, samp.g, ext_g);
528         outcol.b = curve_extrapolate(co.z, samp.b, ext_b);
529         outcol.a = col.a;
530
531         outcol = mix(col, outcol, fac);
532 }
533
534 void curves_rgb_opti(
535         float fac, vec4 col, sampler1DArray curvemap, float layer,
536         vec4 range, vec4 ext_a,
537         out vec4 outcol)
538 {
539         vec4 co = vec4(RANGE_RESCALE(col.rgb, ext_a.x, range.a), layer);
540         vec3 samp;
541         samp.r = texture(curvemap, co.xw).a;
542         samp.g = texture(curvemap, co.yw).a;
543         samp.b = texture(curvemap, co.zw).a;
544
545         outcol.r = curve_extrapolate(co.x, samp.r, ext_a);
546         outcol.g = curve_extrapolate(co.y, samp.g, ext_a);
547         outcol.b = curve_extrapolate(co.z, samp.b, ext_a);
548         outcol.a = col.a;
549
550         outcol = mix(col, outcol, fac);
551 }
552
553 void set_value(float val, out float outval)
554 {
555         outval = val;
556 }
557
558 void set_rgb(vec3 col, out vec3 outcol)
559 {
560         outcol = col;
561 }
562
563 void set_rgba(vec4 col, out vec4 outcol)
564 {
565         outcol = col;
566 }
567
568 void set_value_zero(out float outval)
569 {
570         outval = 0.0;
571 }
572
573 void set_value_one(out float outval)
574 {
575         outval = 1.0;
576 }
577
578 void set_rgb_zero(out vec3 outval)
579 {
580         outval = vec3(0.0);
581 }
582
583 void set_rgb_one(out vec3 outval)
584 {
585         outval = vec3(1.0);
586 }
587
588 void set_rgba_zero(out vec4 outval)
589 {
590         outval = vec4(0.0);
591 }
592
593 void set_rgba_one(out vec4 outval)
594 {
595         outval = vec4(1.0);
596 }
597
598 void brightness_contrast(vec4 col, float brightness, float contrast, out vec4 outcol)
599 {
600         float a = 1.0 + contrast;
601         float b = brightness - contrast * 0.5;
602
603         outcol.r = max(a * col.r + b, 0.0);
604         outcol.g = max(a * col.g + b, 0.0);
605         outcol.b = max(a * col.b + b, 0.0);
606         outcol.a = col.a;
607 }
608
609 void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
610 {
611         fac = clamp(fac, 0.0, 1.0);
612         outcol = mix(col1, col2, fac);
613         outcol.a = col1.a;
614 }
615
616 void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
617 {
618         fac = clamp(fac, 0.0, 1.0);
619         outcol = mix(col1, col1 + col2, fac);
620         outcol.a = col1.a;
621 }
622
623 void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
624 {
625         fac = clamp(fac, 0.0, 1.0);
626         outcol = mix(col1, col1 * col2, fac);
627         outcol.a = col1.a;
628 }
629
630 void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
631 {
632         fac = clamp(fac, 0.0, 1.0);
633         float facm = 1.0 - fac;
634
635         outcol = vec4(1.0) - (vec4(facm) + fac * (vec4(1.0) - col2)) * (vec4(1.0) - col1);
636         outcol.a = col1.a;
637 }
638
639 void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
640 {
641         fac = clamp(fac, 0.0, 1.0);
642         float facm = 1.0 - fac;
643
644         outcol = col1;
645
646         if (outcol.r < 0.5)
647                 outcol.r *= facm + 2.0 * fac * col2.r;
648         else
649                 outcol.r = 1.0 - (facm + 2.0 * fac * (1.0 - col2.r)) * (1.0 - outcol.r);
650
651         if (outcol.g < 0.5)
652                 outcol.g *= facm + 2.0 * fac * col2.g;
653         else
654                 outcol.g = 1.0 - (facm + 2.0 * fac * (1.0 - col2.g)) * (1.0 - outcol.g);
655
656         if (outcol.b < 0.5)
657                 outcol.b *= facm + 2.0 * fac * col2.b;
658         else
659                 outcol.b = 1.0 - (facm + 2.0 * fac * (1.0 - col2.b)) * (1.0 - outcol.b);
660 }
661
662 void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
663 {
664         fac = clamp(fac, 0.0, 1.0);
665         outcol = mix(col1, col1 - col2, fac);
666         outcol.a = col1.a;
667 }
668
669 void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
670 {
671         fac = clamp(fac, 0.0, 1.0);
672         float facm = 1.0 - fac;
673
674         outcol = col1;
675
676         if (col2.r != 0.0) outcol.r = facm * outcol.r + fac * outcol.r / col2.r;
677         if (col2.g != 0.0) outcol.g = facm * outcol.g + fac * outcol.g / col2.g;
678         if (col2.b != 0.0) outcol.b = facm * outcol.b + fac * outcol.b / col2.b;
679 }
680
681 void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
682 {
683         fac = clamp(fac, 0.0, 1.0);
684         outcol = mix(col1, abs(col1 - col2), fac);
685         outcol.a = col1.a;
686 }
687
688 void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
689 {
690         fac = clamp(fac, 0.0, 1.0);
691         outcol.rgb = min(col1.rgb, col2.rgb * fac);
692         outcol.a = col1.a;
693 }
694
695 void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
696 {
697         fac = clamp(fac, 0.0, 1.0);
698         outcol.rgb = max(col1.rgb, col2.rgb * fac);
699         outcol.a = col1.a;
700 }
701
702 void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
703 {
704         fac = clamp(fac, 0.0, 1.0);
705         outcol = col1;
706
707         if (outcol.r != 0.0) {
708                 float tmp = 1.0 - fac * col2.r;
709                 if (tmp <= 0.0)
710                         outcol.r = 1.0;
711                 else if ((tmp = outcol.r / tmp) > 1.0)
712                         outcol.r = 1.0;
713                 else
714                         outcol.r = tmp;
715         }
716         if (outcol.g != 0.0) {
717                 float tmp = 1.0 - fac * col2.g;
718                 if (tmp <= 0.0)
719                         outcol.g = 1.0;
720                 else if ((tmp = outcol.g / tmp) > 1.0)
721                         outcol.g = 1.0;
722                 else
723                         outcol.g = tmp;
724         }
725         if (outcol.b != 0.0) {
726                 float tmp = 1.0 - fac * col2.b;
727                 if (tmp <= 0.0)
728                         outcol.b = 1.0;
729                 else if ((tmp = outcol.b / tmp) > 1.0)
730                         outcol.b = 1.0;
731                 else
732                         outcol.b = tmp;
733         }
734 }
735
736 void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
737 {
738         fac = clamp(fac, 0.0, 1.0);
739         float tmp, facm = 1.0 - fac;
740
741         outcol = col1;
742
743         tmp = facm + fac * col2.r;
744         if (tmp <= 0.0)
745                 outcol.r = 0.0;
746         else if ((tmp = (1.0 - (1.0 - outcol.r) / tmp)) < 0.0)
747                 outcol.r = 0.0;
748         else if (tmp > 1.0)
749                 outcol.r = 1.0;
750         else
751                 outcol.r = tmp;
752
753         tmp = facm + fac * col2.g;
754         if (tmp <= 0.0)
755                 outcol.g = 0.0;
756         else if ((tmp = (1.0 - (1.0 - outcol.g) / tmp)) < 0.0)
757                 outcol.g = 0.0;
758         else if (tmp > 1.0)
759                 outcol.g = 1.0;
760         else
761                 outcol.g = tmp;
762
763         tmp = facm + fac * col2.b;
764         if (tmp <= 0.0)
765                 outcol.b = 0.0;
766         else if ((tmp = (1.0 - (1.0 - outcol.b) / tmp)) < 0.0)
767                 outcol.b = 0.0;
768         else if (tmp > 1.0)
769                 outcol.b = 1.0;
770         else
771                 outcol.b = tmp;
772 }
773
774 void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
775 {
776         fac = clamp(fac, 0.0, 1.0);
777         float facm = 1.0 - fac;
778
779         outcol = col1;
780
781         vec4 hsv, hsv2, tmp;
782         rgb_to_hsv(col2, hsv2);
783
784         if (hsv2.y != 0.0) {
785                 rgb_to_hsv(outcol, hsv);
786                 hsv.x = hsv2.x;
787                 hsv_to_rgb(hsv, tmp);
788
789                 outcol = mix(outcol, tmp, fac);
790                 outcol.a = col1.a;
791         }
792 }
793
794 void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
795 {
796         fac = clamp(fac, 0.0, 1.0);
797         float facm = 1.0 - fac;
798
799         outcol = col1;
800
801         vec4 hsv, hsv2;
802         rgb_to_hsv(outcol, hsv);
803
804         if (hsv.y != 0.0) {
805                 rgb_to_hsv(col2, hsv2);
806
807                 hsv.y = facm * hsv.y + fac * hsv2.y;
808                 hsv_to_rgb(hsv, outcol);
809         }
810 }
811
812 void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
813 {
814         fac = clamp(fac, 0.0, 1.0);
815         float facm = 1.0 - fac;
816
817         vec4 hsv, hsv2;
818         rgb_to_hsv(col1, hsv);
819         rgb_to_hsv(col2, hsv2);
820
821         hsv.z = facm * hsv.z + fac * hsv2.z;
822         hsv_to_rgb(hsv, outcol);
823 }
824
825 void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
826 {
827         fac = clamp(fac, 0.0, 1.0);
828         float facm = 1.0 - fac;
829
830         outcol = col1;
831
832         vec4 hsv, hsv2, tmp;
833         rgb_to_hsv(col2, hsv2);
834
835         if (hsv2.y != 0.0) {
836                 rgb_to_hsv(outcol, hsv);
837                 hsv.x = hsv2.x;
838                 hsv.y = hsv2.y;
839                 hsv_to_rgb(hsv, tmp);
840
841                 outcol = mix(outcol, tmp, fac);
842                 outcol.a = col1.a;
843         }
844 }
845
846 void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
847 {
848         fac = clamp(fac, 0.0, 1.0);
849         float facm = 1.0 - fac;
850
851         vec4 one = vec4(1.0);
852         vec4 scr = one - (one - col2) * (one - col1);
853         outcol = facm * col1 + fac * ((one - col1) * col2 * col1 + col1 * scr);
854 }
855
856 void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
857 {
858         fac = clamp(fac, 0.0, 1.0);
859
860         outcol = col1 + fac * (2.0 * (col2 - vec4(0.5)));
861 }
862
863 void valtorgb_opti_constant(float fac, float edge, vec4 color1, vec4 color2, out vec4 outcol, out float outalpha)
864 {
865         outcol = (fac > edge) ? color2 : color1;
866         outalpha = outcol.a;
867 }
868
869 void valtorgb_opti_linear(float fac, vec2 mulbias, vec4 color1, vec4 color2, out vec4 outcol, out float outalpha)
870 {
871         fac = clamp(fac * mulbias.x + mulbias.y, 0.0, 1.0);
872         outcol = mix(color1, color2, fac);
873         outalpha = outcol.a;
874 }
875
876 void valtorgb(float fac, sampler1DArray colormap, float layer, out vec4 outcol, out float outalpha)
877 {
878         outcol = texture(colormap, vec2(fac, layer));
879         outalpha = outcol.a;
880 }
881
882 void valtorgb_nearest(float fac, sampler1DArray colormap, float layer, out vec4 outcol, out float outalpha)
883 {
884         fac = clamp(fac, 0.0, 1.0);
885         outcol = texelFetch(colormap, ivec2(fac * (textureSize(colormap, 0).x - 1), layer), 0);
886         outalpha = outcol.a;
887 }
888
889 void rgbtobw(vec4 color, out float outval)
890 {
891         vec3 factors = vec3(0.2126, 0.7152, 0.0722);
892         outval = dot(color.rgb, factors);
893 }
894
895 void invert(float fac, vec4 col, out vec4 outcol)
896 {
897         outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac);
898         outcol.w = col.w;
899 }
900
901 void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
902 {
903         out_vec = clamp(vec, min, max);
904 }
905
906 void clamp_val(float value, float min, float max, out float out_value)
907 {
908         out_value = clamp(value, min, max);
909 }
910
911 void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
912 {
913         vec4 hsv;
914
915         rgb_to_hsv(col, hsv);
916
917         hsv[0] = fract(hsv[0] + hue + 0.5);
918         hsv[1] = clamp(hsv[1] * sat, 0.0, 1.0);
919         hsv[2] = hsv[2] * value;
920
921         hsv_to_rgb(hsv, outcol);
922
923         outcol = mix(col, outcol, fac);
924 }
925
926 void separate_rgb(vec4 col, out float r, out float g, out float b)
927 {
928         r = col.r;
929         g = col.g;
930         b = col.b;
931 }
932
933 void combine_rgb(float r, float g, float b, out vec4 col)
934 {
935         col = vec4(r, g, b, 1.0);
936 }
937
938 void separate_xyz(vec3 vec, out float x, out float y, out float z)
939 {
940         x = vec.r;
941         y = vec.g;
942         z = vec.b;
943 }
944
945 void combine_xyz(float x, float y, float z, out vec3 vec)
946 {
947         vec = vec3(x, y, z);
948 }
949
950 void separate_hsv(vec4 col, out float h, out float s, out float v)
951 {
952         vec4 hsv;
953
954         rgb_to_hsv(col, hsv);
955         h = hsv[0];
956         s = hsv[1];
957         v = hsv[2];
958 }
959
960 void combine_hsv(float h, float s, float v, out vec4 col)
961 {
962         hsv_to_rgb(vec4(h, s, v, 1.0), col);
963 }
964
965 void output_node(vec4 rgb, float alpha, out vec4 outrgb)
966 {
967         outrgb = vec4(rgb.rgb, alpha);
968 }
969
970 /*********** TEXTURES ***************/
971
972 void texco_norm(vec3 normal, out vec3 outnormal)
973 {
974         /* corresponds to shi->orn, which is negated so cancels
975            out blender normal negation */
976         outnormal = normalize(normal);
977 }
978
979 vec3 mtex_2d_mapping(vec3 vec)
980 {
981         return vec3(vec.xy * 0.5 + vec2(0.5), vec.z);
982 }
983
984 /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
985 mat3 to_mat3(mat4 m4)
986 {
987         mat3 m3;
988         m3[0] = m4[0].xyz;
989         m3[1] = m4[1].xyz;
990         m3[2] = m4[2].xyz;
991         return m3;
992 }
993
994 /*********** NEW SHADER UTILITIES **************/
995
996 float fresnel_dielectric_0(float eta)
997 {
998         /* compute fresnel reflactance at normal incidence => cosi = 1.0 */
999         float A = (eta - 1.0) / (eta + 1.0);
1000
1001         return A * A;
1002 }
1003
1004 float fresnel_dielectric_cos(float cosi, float eta)
1005 {
1006         /* compute fresnel reflectance without explicitly computing
1007          * the refracted direction */
1008         float c = abs(cosi);
1009         float g = eta * eta - 1.0 + c * c;
1010         float result;
1011
1012         if (g > 0.0) {
1013                 g = sqrt(g);
1014                 float A = (g - c) / (g + c);
1015                 float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
1016                 result = 0.5 * A * A * (1.0 + B * B);
1017         }
1018         else {
1019                 result = 1.0;  /* TIR (no refracted component) */
1020         }
1021
1022         return result;
1023 }
1024
1025 float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
1026 {
1027         /* compute fresnel reflectance without explicitly computing
1028          * the refracted direction */
1029         return fresnel_dielectric_cos(dot(Incoming, Normal), eta);
1030 }
1031
1032 float hypot(float x, float y)
1033 {
1034         return sqrt(x * x + y * y);
1035 }
1036
1037 void generated_from_orco(vec3 orco, out vec3 generated)
1038 {
1039 #ifdef VOLUMETRICS
1040 #ifdef MESH_SHADER
1041         generated = volumeObjectLocalCoord;
1042 #else
1043         generated = worldPosition;
1044 #endif
1045 #else
1046         generated = orco;
1047 #endif
1048 }
1049
1050 int floor_to_int(float x)
1051 {
1052         return int(floor(x));
1053 }
1054
1055 int quick_floor(float x)
1056 {
1057         return int(x) - ((x < 0) ? 1 : 0);
1058 }
1059
1060 float integer_noise(int n)
1061 {
1062         int nn;
1063         n = (n + 1013) & 0x7fffffff;
1064         n = (n >> 13) ^ n;
1065         nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
1066         return 0.5 * (float(nn) / 1073741824.0);
1067 }
1068
1069 uint hash(uint kx, uint ky, uint kz)
1070 {
1071 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
1072 #define final(a, b, c) \
1073 { \
1074         c ^= b; c -= rot(b, 14); \
1075         a ^= c; a -= rot(c, 11); \
1076         b ^= a; b -= rot(a, 25); \
1077         c ^= b; c -= rot(b, 16); \
1078         a ^= c; a -= rot(c, 4);  \
1079         b ^= a; b -= rot(a, 14); \
1080         c ^= b; c -= rot(b, 24); \
1081 }
1082         // now hash the data!
1083         uint a, b, c, len = 3u;
1084         a = b = c = 0xdeadbeefu + (len << 2u) + 13u;
1085
1086         c += kz;
1087         b += ky;
1088         a += kx;
1089         final (a, b, c);
1090
1091         return c;
1092 #undef rot
1093 #undef final
1094 }
1095
1096 uint hash(int kx, int ky, int kz)
1097 {
1098         return hash(uint(kx), uint(ky), uint(kz));
1099 }
1100
1101 float bits_to_01(uint bits)
1102 {
1103         return (float(bits) / 4294967295.0);
1104 }
1105
1106 float cellnoise(vec3 p)
1107 {
1108         int ix = quick_floor(p.x);
1109         int iy = quick_floor(p.y);
1110         int iz = quick_floor(p.z);
1111
1112         return bits_to_01(hash(uint(ix), uint(iy), uint(iz)));
1113 }
1114
1115 vec3 cellnoise_color(vec3 p)
1116 {
1117         float r = cellnoise(p.xyz);
1118         float g = cellnoise(p.yxz);
1119         float b = cellnoise(p.yzx);
1120
1121         return vec3(r, g, b);
1122 }
1123
1124 float floorfrac(float x, out int i)
1125 {
1126         i = floor_to_int(x);
1127         return x - i;
1128 }
1129
1130 /* bsdfs */
1131
1132 vec3 tint_from_color(vec3 color)
1133 {
1134         float lum = dot(color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
1135         return (lum > 0) ? color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */
1136 }
1137
1138 void convert_metallic_to_specular_tinted(
1139         vec3 basecol, vec3 basecol_tint, float metallic, float specular_fac, float specular_tint,
1140         out vec3 diffuse, out vec3 f0)
1141 {
1142         vec3 tmp_col = mix(vec3(1.0), basecol_tint, specular_tint);
1143         f0 = mix((0.08 * specular_fac) * tmp_col, basecol, metallic);
1144         diffuse = basecol * (1.0 - metallic);
1145 }
1146
1147 vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint)
1148 {
1149         float f = 1.0 - NV;
1150         /* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps, therefore we need to clamp value. */
1151         f = clamp(f, 0.0, 1.0);
1152         /* Empirical approximation (manual curve fitting). Can be refined. */
1153         float sheen = f*f*f*0.077 + f*0.01 + 0.00026;
1154         return sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
1155 }
1156
1157 #ifndef VOLUMETRICS
1158 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
1159 {
1160         N = normalize(N);
1161         vec3 vN = mat3(ViewMatrix) * N;
1162         result = CLOSURE_DEFAULT;
1163         result.ssr_normal = normal_encode(vN, viewCameraVec);
1164         eevee_closure_diffuse(N, color.rgb, 1.0, result.radiance);
1165         result.radiance *= color.rgb;
1166 }
1167
1168 void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
1169 {
1170         N = normalize(N);
1171         vec3 out_spec, ssr_spec;
1172         eevee_closure_glossy(N, vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
1173         vec3 vN = mat3(ViewMatrix) * N;
1174         result = CLOSURE_DEFAULT;
1175         result.radiance = out_spec * color.rgb;
1176         result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
1177         result.ssr_normal = normal_encode(vN, viewCameraVec);
1178         result.ssr_id = int(ssr_id);
1179 }
1180
1181 void node_bsdf_anisotropic(
1182         vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
1183         out Closure result)
1184 {
1185         node_bsdf_glossy(color, roughness, N, -1, result);
1186 }
1187
1188 void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result)
1189 {
1190         N = normalize(N);
1191         vec3 out_spec, out_refr, ssr_spec;
1192         vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb : color.rgb; /* Simulate 2 transmission event */
1193         eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
1194         out_refr *= refr_color;
1195         out_spec *= color.rgb;
1196         float fresnel = F_eta(ior, dot(N, cameraVec));
1197         vec3 vN = mat3(ViewMatrix) * N;
1198         result = CLOSURE_DEFAULT;
1199         result.radiance = mix(out_refr, out_spec, fresnel);
1200         result.ssr_data = vec4(ssr_spec * color.rgb * fresnel, roughness);
1201         result.ssr_normal = normal_encode(vN, viewCameraVec);
1202         result.ssr_id = int(ssr_id);
1203 }
1204
1205 void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
1206 {
1207         node_bsdf_diffuse(color, 0.0, N, result);
1208 }
1209
1210 void node_bsdf_principled(
1211         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1212         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1213         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1214         float sss_id, vec3 sss_scale, out Closure result)
1215 {
1216         N = normalize(N);
1217         ior = max(ior, 1e-5);
1218         metallic = saturate(metallic);
1219         transmission = saturate(transmission);
1220         float dielectric = 1.0 - metallic;
1221         transmission *= dielectric;
1222         sheen *= dielectric;
1223         subsurface_color *= dielectric;
1224
1225         vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec;
1226         vec3 ctint = tint_from_color(base_color.rgb);
1227         convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
1228
1229         float NV = dot(N, cameraVec);
1230         vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
1231
1232         /* Far from being accurate, but 2 glossy evaluation is too expensive.
1233          * Most noticeable difference is at grazing angles since the bsdf lut
1234          * f0 color interpolation is done on top of this interpolation. */
1235         vec3 f0_glass = mix(vec3(1.0), base_color.rgb, specular_tint);
1236         float fresnel = F_eta(ior, NV);
1237         vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
1238         f0 = mix(f0, spec_col, transmission);
1239
1240         vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
1241
1242         float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
1243         eevee_closure_principled(N, mixed_ss_base_color, f0, int(ssr_id), roughness,
1244                                  CN, clearcoat * 0.25, clearcoat_roughness, 1.0, sss_scalef, ior,
1245                                  out_diff, out_trans, out_spec, out_refr, ssr_spec);
1246
1247         vec3 refr_color = base_color.rgb;
1248         refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */
1249         out_refr *= refr_color * (1.0 - fresnel) * transmission;
1250
1251         vec3 vN = mat3(ViewMatrix) * N;
1252         result = CLOSURE_DEFAULT;
1253         result.radiance = out_spec + out_refr;
1254         result.radiance += out_diff * out_sheen; /* Coarse approx. */
1255 #ifndef USE_SSS
1256         result.radiance += (out_diff + out_trans) * mixed_ss_base_color *  (1.0 - transmission);
1257 #endif
1258         result.ssr_data = vec4(ssr_spec, roughness);
1259         result.ssr_normal = normal_encode(vN, viewCameraVec);
1260         result.ssr_id = int(ssr_id);
1261 #ifdef USE_SSS
1262         result.sss_data.a = sss_scalef;
1263         result.sss_data.rgb = out_diff + out_trans;
1264 #  ifdef USE_SSS_ALBEDO
1265         result.sss_albedo.rgb = mixed_ss_base_color;
1266 #  else
1267         result.sss_data.rgb *= mixed_ss_base_color;
1268 #  endif
1269         result.sss_data.rgb *= (1.0 - transmission);
1270 #endif
1271 }
1272
1273 void node_bsdf_principled_dielectric(
1274         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1275         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1276         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1277         float sss_id, vec3 sss_scale, out Closure result)
1278 {
1279         N = normalize(N);
1280         metallic = saturate(metallic);
1281         float dielectric = 1.0 - metallic;
1282
1283         vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
1284         vec3 ctint = tint_from_color(base_color.rgb);
1285         convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
1286
1287         float NV = dot(N, cameraVec);
1288         vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
1289
1290         eevee_closure_default(N, diffuse, f0, int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec);
1291
1292         vec3 vN = mat3(ViewMatrix) * N;
1293         result = CLOSURE_DEFAULT;
1294         result.radiance = out_spec + out_diff * (diffuse + out_sheen);
1295         result.ssr_data = vec4(ssr_spec, roughness);
1296         result.ssr_normal = normal_encode(vN, viewCameraVec);
1297         result.ssr_id = int(ssr_id);
1298 }
1299
1300 void node_bsdf_principled_metallic(
1301         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1302         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1303         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1304         float sss_id, vec3 sss_scale, out Closure result)
1305 {
1306         N = normalize(N);
1307         vec3 out_spec, ssr_spec;
1308
1309         eevee_closure_glossy(N, base_color.rgb, int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
1310
1311         vec3 vN = mat3(ViewMatrix) * N;
1312         result = CLOSURE_DEFAULT;
1313         result.radiance = out_spec;
1314         result.ssr_data = vec4(ssr_spec, roughness);
1315         result.ssr_normal = normal_encode(vN, viewCameraVec);
1316         result.ssr_id = int(ssr_id);
1317 }
1318
1319 void node_bsdf_principled_clearcoat(
1320         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1321         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1322         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1323         float sss_id, vec3 sss_scale, out Closure result)
1324 {
1325         vec3 out_spec, ssr_spec;
1326         N = normalize(N);
1327
1328         eevee_closure_clearcoat(N, base_color.rgb, int(ssr_id), roughness, CN, clearcoat * 0.25, clearcoat_roughness,
1329                                 1.0, out_spec, ssr_spec);
1330
1331         vec3 vN = mat3(ViewMatrix) * N;
1332         result = CLOSURE_DEFAULT;
1333         result.radiance = out_spec;
1334         result.ssr_data = vec4(ssr_spec, roughness);
1335         result.ssr_normal = normal_encode(vN, viewCameraVec);
1336         result.ssr_id = int(ssr_id);
1337 }
1338
1339 void node_bsdf_principled_subsurface(
1340         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1341         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1342         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1343         float sss_id, vec3 sss_scale, out Closure result)
1344 {
1345         metallic = saturate(metallic);
1346         N = normalize(N);
1347
1348         vec3 diffuse, f0, out_diff, out_spec, out_trans, ssr_spec;
1349         vec3 ctint = tint_from_color(base_color.rgb);
1350         convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
1351
1352         subsurface_color = subsurface_color * (1.0 - metallic);
1353         vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
1354         float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
1355
1356         float NV = dot(N, cameraVec);
1357         vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
1358
1359         eevee_closure_skin(N, mixed_ss_base_color, f0, int(ssr_id), roughness, 1.0, sss_scalef,
1360                            out_diff, out_trans, out_spec, ssr_spec);
1361
1362         vec3 vN = mat3(ViewMatrix) * N;
1363         result = CLOSURE_DEFAULT;
1364         result.radiance = out_spec;
1365         result.ssr_data = vec4(ssr_spec, roughness);
1366         result.ssr_normal = normal_encode(vN, viewCameraVec);
1367         result.ssr_id = int(ssr_id);
1368 #ifdef USE_SSS
1369         result.sss_data.a = sss_scalef;
1370         result.sss_data.rgb = out_diff + out_trans;
1371 #  ifdef USE_SSS_ALBEDO
1372         result.sss_albedo.rgb = mixed_ss_base_color;
1373 #  else
1374         result.sss_data.rgb *= mixed_ss_base_color;
1375 #  endif
1376 #else
1377         result.radiance += (out_diff + out_trans) * mixed_ss_base_color;
1378 #endif
1379         result.radiance += out_diff * out_sheen;
1380 }
1381
1382 void node_bsdf_principled_glass(
1383         vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
1384         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
1385         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
1386         float sss_id, vec3 sss_scale, out Closure result)
1387 {
1388         ior = max(ior, 1e-5);
1389         N = normalize(N);
1390
1391         vec3 f0, out_spec, out_refr, ssr_spec;
1392         f0 = mix(vec3(1.0), base_color.rgb, specular_tint);
1393
1394         eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
1395
1396         vec3 refr_color = base_color.rgb;
1397         refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission events */
1398         out_refr *= refr_color;
1399
1400         float fresnel = F_eta(ior, dot(N, cameraVec));
1401         vec3 spec_col = F_color_blend(ior, fresnel, f0);
1402         out_spec *= spec_col;
1403         ssr_spec *= spec_col * fresnel;
1404
1405         vec3 vN = mat3(ViewMatrix) * N;
1406         result = CLOSURE_DEFAULT;
1407         result.radiance = mix(out_refr, out_spec, fresnel);
1408         result.ssr_data = vec4(ssr_spec, roughness);
1409         result.ssr_normal = normal_encode(vN, viewCameraVec);
1410         result.ssr_id = int(ssr_id);
1411 }
1412
1413 void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
1414 {
1415         node_bsdf_diffuse(color, 0.0, -N, result);
1416 }
1417
1418 void node_bsdf_transparent(vec4 color, out Closure result)
1419 {
1420         /* this isn't right */
1421         result = CLOSURE_DEFAULT;
1422         result.radiance = vec3(0.0);
1423         result.opacity = clamp(1.0 - dot(color.rgb, vec3(0.3333334)), 0.0, 1.0);
1424         result.ssr_id = TRANSPARENT_CLOSURE_FLAG;
1425 }
1426
1427 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
1428 {
1429         node_bsdf_diffuse(color, 0.0, N, result);
1430 }
1431
1432 void node_subsurface_scattering(
1433         vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
1434         out Closure result)
1435 {
1436 #if defined(USE_SSS)
1437         N = normalize(N);
1438         vec3 out_diff, out_trans;
1439         vec3 vN = mat3(ViewMatrix) * N;
1440         result = CLOSURE_DEFAULT;
1441         result.ssr_data = vec4(0.0);
1442         result.ssr_normal = normal_encode(vN, viewCameraVec);
1443         result.ssr_id = -1;
1444         result.sss_data.a = scale;
1445         eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans);
1446         result.sss_data.rgb = out_diff + out_trans;
1447 #  ifdef USE_SSS_ALBEDO
1448         /* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */
1449         result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur);
1450         result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur);
1451 #  else
1452         result.sss_data.rgb *= color.rgb;
1453 #  endif
1454 #else
1455         node_bsdf_diffuse(color, 0.0, N, result);
1456 #endif
1457 }
1458
1459 void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
1460 {
1461         N = normalize(N);
1462         vec3 out_refr;
1463         color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
1464         eevee_closure_refraction(N, roughness, ior, out_refr);
1465         vec3 vN = mat3(ViewMatrix) * N;
1466         result = CLOSURE_DEFAULT;
1467         result.ssr_normal = normal_encode(vN, viewCameraVec);
1468         result.radiance = out_refr * color.rgb;
1469         result.ssr_id = REFRACT_CLOSURE_FLAG;
1470 }
1471
1472 void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
1473 {
1474         vec3 bent_normal;
1475         vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
1476         result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
1477         result_color = result_ao * color;
1478 }
1479
1480 #endif /* VOLUMETRICS */
1481
1482 /* emission */
1483
1484 void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
1485 {
1486 #ifndef VOLUMETRICS
1487         color *= strength;
1488         result = CLOSURE_DEFAULT;
1489         result.radiance = color.rgb;
1490         result.opacity = color.a;
1491         result.ssr_normal = normal_encode(vN, viewCameraVec);
1492 #else
1493         result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
1494 #endif
1495 }
1496
1497 void node_wireframe(float size, vec2 barycentric, vec3 barycentric_dist, out float fac)
1498 {
1499         vec3 barys = barycentric.xyy;
1500         barys.z = 1.0 - barycentric.x - barycentric.y;
1501
1502         size *= 0.5;
1503         vec3 s = step(-size, -barys * barycentric_dist);
1504
1505         fac = max(s.x, max(s.y, s.z));
1506 }
1507
1508 void node_wireframe_screenspace(float size, vec2 barycentric, out float fac)
1509 {
1510         vec3 barys = barycentric.xyy;
1511         barys.z = 1.0 - barycentric.x - barycentric.y;
1512
1513         size *= (1.0 / 3.0);
1514         vec3 dx = dFdx(barys);
1515         vec3 dy = dFdy(barys);
1516         vec3 deltas = sqrt(dx * dx + dy * dy);
1517
1518         vec3 s = step(-deltas * size, -barys);
1519
1520         fac = max(s.x, max(s.y, s.z));
1521 }
1522
1523 /* background */
1524
1525 void node_tex_environment_texco(vec3 viewvec, out vec3 worldvec)
1526 {
1527 #ifdef MESH_SHADER
1528         worldvec = worldPosition;
1529 #else
1530         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
1531         vec4 co_homogenous = (ProjectionMatrixInverse * v);
1532
1533         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
1534 #  if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
1535         worldvec = (ViewMatrixInverse * co).xyz;
1536 #  else
1537         worldvec = (ModelViewMatrixInverse * co).xyz;
1538 #  endif
1539 #endif
1540 }
1541
1542 void node_background(vec4 color, float strength, out Closure result)
1543 {
1544 #ifndef VOLUMETRICS
1545         color *= strength;
1546         result = CLOSURE_DEFAULT;
1547         result.radiance = color.rgb;
1548         result.opacity = color.a;
1549 #else
1550         result = CLOSURE_DEFAULT;
1551 #endif
1552 }
1553
1554 /* volumes */
1555
1556 void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result)
1557 {
1558 #ifdef VOLUMETRICS
1559         result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy);
1560 #else
1561         result = CLOSURE_DEFAULT;
1562 #endif
1563 }
1564
1565 void node_volume_absorption(vec4 color, float density, out Closure result)
1566 {
1567 #ifdef VOLUMETRICS
1568         result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0);
1569 #else
1570         result = CLOSURE_DEFAULT;
1571 #endif
1572 }
1573
1574 void node_blackbody(float temperature, sampler1DArray spectrummap, float layer, out vec4 color)
1575 {
1576     if (temperature >= 12000.0) {
1577         color = vec4(0.826270103, 0.994478524, 1.56626022, 1.0);
1578     }
1579     else if (temperature < 965.0) {
1580         color = vec4(4.70366907, 0.0, 0.0, 1.0);
1581     }
1582         else {
1583                 float t = (temperature - 965.0) / (12000.0 - 965.0);
1584                 color = vec4(texture(spectrummap, vec2(t, layer)).rgb, 1.0);
1585         }
1586 }
1587
1588 void node_volume_principled(
1589         vec4 color,
1590         float density,
1591         float anisotropy,
1592         vec4 absorption_color,
1593         float emission_strength,
1594         vec4 emission_color,
1595         float blackbody_intensity,
1596         vec4 blackbody_tint,
1597         float temperature,
1598         float density_attribute,
1599         vec4 color_attribute,
1600         float temperature_attribute,
1601         sampler1DArray spectrummap,
1602         float layer,
1603         out Closure result)
1604 {
1605 #ifdef VOLUMETRICS
1606         vec3 absorption_coeff = vec3(0.0);
1607         vec3 scatter_coeff = vec3(0.0);
1608         vec3 emission_coeff = vec3(0.0);
1609
1610         /* Compute density. */
1611         density = max(density, 0.0);
1612
1613         if (density > 1e-5) {
1614                 density = max(density * density_attribute, 0.0);
1615         }
1616
1617         if (density > 1e-5) {
1618                 /* Compute scattering and absorption coefficients. */
1619                 vec3 scatter_color = color.rgb * color_attribute.rgb;
1620
1621                 scatter_coeff = scatter_color * density;
1622                 absorption_color.rgb = sqrt(max(absorption_color.rgb, 0.0));
1623                 absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color.rgb, 0.0) * density;
1624         }
1625
1626         /* Compute emission. */
1627         emission_strength = max(emission_strength, 0.0);
1628
1629         if (emission_strength > 1e-5) {
1630                 emission_coeff += emission_strength * emission_color.rgb;
1631         }
1632
1633         if (blackbody_intensity > 1e-3) {
1634                 /* Add temperature from attribute. */
1635                 float T = max(temperature * max(temperature_attribute, 0.0), 0.0);
1636
1637                 /* Stefan-Boltzman law. */
1638                 float T2 = T * T;
1639                 float T4 = T2 * T2;
1640                 float sigma = 5.670373e-8 * 1e-6 / M_PI;
1641                 float intensity = sigma * mix(1.0, T4, blackbody_intensity);
1642
1643                 if (intensity > 1e-5) {
1644                         vec4 bb;
1645                         node_blackbody(T, spectrummap, layer, bb);
1646                         emission_coeff += bb.rgb * blackbody_tint.rgb * intensity;
1647                 }
1648         }
1649
1650         result = Closure(absorption_coeff, scatter_coeff, emission_coeff, anisotropy);
1651 #else
1652         result = CLOSURE_DEFAULT;
1653 #endif
1654 }
1655
1656 /* closures */
1657
1658 void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
1659 {
1660         shader = closure_mix(shader1, shader2, fac);
1661 }
1662
1663 void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
1664 {
1665         shader = closure_add(shader1, shader2);
1666 }
1667
1668 /* fresnel */
1669
1670 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
1671 {
1672         N = normalize(N);
1673         /* handle perspective/orthographic */
1674         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
1675
1676         float eta = max(ior, 0.00001);
1677         result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
1678 }
1679
1680 /* layer_weight */
1681
1682 void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
1683 {
1684         N = normalize(N);
1685
1686         /* fresnel */
1687         float eta = max(1.0 - blend, 0.00001);
1688         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
1689
1690         fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
1691
1692         /* facing */
1693         facing = abs(dot(I_view, N));
1694         if (blend != 0.5) {
1695                 blend = clamp(blend, 0.0, 0.99999);
1696                 blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
1697                 facing = pow(facing, blend);
1698         }
1699         facing = 1.0 - facing;
1700 }
1701
1702 /* gamma */
1703
1704 void node_gamma(vec4 col, float gamma, out vec4 outcol)
1705 {
1706         outcol = col;
1707
1708         if (col.r > 0.0)
1709                 outcol.r = compatible_pow(col.r, gamma);
1710         if (col.g > 0.0)
1711                 outcol.g = compatible_pow(col.g, gamma);
1712         if (col.b > 0.0)
1713                 outcol.b = compatible_pow(col.b, gamma);
1714 }
1715
1716 /* geometry */
1717
1718 void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
1719 {
1720 #if defined(MESH_SHADER) && defined(VOLUMETRICS)
1721         vec3 cos = volumeObjectLocalCoord;
1722 #else
1723         vec3 cos = vec3(0.0);
1724 #endif
1725         outvec = texture(tex, cos).aaa;
1726         outcol = vec4(outvec, 1.0);
1727         outf = dot(vec3(1.0 / 3.0), outvec);
1728 }
1729
1730 uniform vec3 volumeColor = vec3(1.0);
1731
1732 void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
1733 {
1734 #if defined(MESH_SHADER) && defined(VOLUMETRICS)
1735         vec3 cos = volumeObjectLocalCoord;
1736 #else
1737         vec3 cos = vec3(0.0);
1738 #endif
1739
1740         vec4 value = texture(tex, cos).rgba;
1741         /* Density is premultiplied for interpolation, divide it out here. */
1742         if (value.a > 1e-8)
1743                 value.rgb /= value.a;
1744
1745         outvec = value.rgb * volumeColor;
1746         outcol = vec4(outvec, 1.0);
1747         outf = dot(vec3(1.0 / 3.0), outvec);
1748 }
1749
1750 void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
1751 {
1752 #if defined(MESH_SHADER) && defined(VOLUMETRICS)
1753         vec3 cos = volumeObjectLocalCoord;
1754 #else
1755         vec3 cos = vec3(0.0);
1756 #endif
1757         outf = texture(tex, cos).r;
1758         outvec = vec3(outf, outf, outf);
1759         outcol = vec4(outf, outf, outf, 1.0);
1760 }
1761
1762 void node_attribute_volume_temperature(sampler3D tex, vec2 temperature, out vec4 outcol, out vec3 outvec, out float outf)
1763 {
1764 #if defined(MESH_SHADER) && defined(VOLUMETRICS)
1765         vec3 cos = volumeObjectLocalCoord;
1766 #else
1767         vec3 cos = vec3(0.0);
1768 #endif
1769         float flame = texture(tex, cos).r;
1770
1771         outf = (flame > 0.01) ? temperature.x + flame * (temperature.y - temperature.x): 0.0;
1772         outvec = vec3(outf, outf, outf);
1773         outcol = vec4(outf, outf, outf, 1.0);
1774 }
1775
1776 void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
1777 {
1778         outcol = vec4(attr, 1.0);
1779         outvec = attr;
1780         outf =  dot(vec3(1.0 / 3.0), attr);
1781 }
1782
1783 void node_uvmap(vec3 attr_uv, out vec3 outvec)
1784 {
1785         outvec = attr_uv;
1786 }
1787
1788 void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
1789 {
1790         orco_out = orco_in.xzy * vec3(0.0, -0.5, 0.5) + vec3(0.0, 0.25, -0.25);
1791 }
1792
1793 void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
1794 {
1795         orco_out = orco_in.zyx * vec3(-0.5, 0.0, 0.5) + vec3(0.25, 0.0, -0.25);
1796 }
1797
1798 void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
1799 {
1800         orco_out = orco_in.yxz * vec3(-0.5, 0.5, 0.0) + vec3(0.25, -0.25, 0.0);
1801 }
1802
1803 void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
1804 {
1805         tangent = normalize((toworld * vec4(attr_tangent.xyz, 0.0)).xyz);
1806 }
1807
1808 void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
1809 {
1810 #ifndef VOLUMETRICS
1811         N = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
1812 #else
1813         N = (toworld * vec4(N, 0.0)).xyz;
1814 #endif
1815         T = (objmat * vec4(orco, 0.0)).xyz;
1816         T = cross(N, normalize(cross(T, N)));
1817 }
1818
1819 void node_geometry(
1820         vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, vec2 barycentric,
1821         out vec3 position, out vec3 normal, out vec3 tangent,
1822         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
1823         out float backfacing, out float pointiness)
1824 {
1825         /* handle perspective/orthographic */
1826         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
1827         incoming = -(toworld * vec4(I_view, 0.0)).xyz;
1828
1829 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
1830         position = -incoming;
1831         true_normal = normal = incoming;
1832         tangent = parametric = vec3(0.0);
1833         vec3(0.0);
1834         backfacing = 0.0;
1835         pointiness = 0.0;
1836 #else
1837
1838         position = worldPosition;
1839 #  ifndef VOLUMETRICS
1840         normal = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
1841         vec3 B = dFdx(worldPosition);
1842         vec3 T = dFdy(worldPosition);
1843         true_normal = normalize(cross(B, T));
1844 #  else
1845         normal = (toworld * vec4(N, 0.0)).xyz;
1846         true_normal = normal;
1847 #  endif
1848         tangent_orco_z(orco, orco);
1849         node_tangent(N, orco, objmat, toworld, tangent);
1850
1851         parametric = vec3(barycentric, 0.0);
1852         backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
1853         pointiness = 0.5;
1854 #endif
1855 }
1856
1857 void generated_texco(vec3 I, vec3 attr_orco, out vec3 generated)
1858 {
1859         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
1860         vec4 co_homogenous = (ProjectionMatrixInverse * v);
1861         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
1862         co.xyz = normalize(co.xyz);
1863 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
1864         generated = (ViewMatrixInverse * co).xyz;
1865 #else
1866         generated_from_orco(attr_orco, generated);
1867 #endif
1868 }
1869
1870 void node_tex_coord(
1871         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
1872         vec3 attr_orco, vec3 attr_uv,
1873         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
1874         out vec3 camera, out vec3 window, out vec3 reflection)
1875 {
1876         generated = attr_orco;
1877         normal = normalize(NormalMatrixInverse * N);
1878         uv = attr_uv;
1879         object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
1880         camera = vec3(I.xy, -I.z);
1881         vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
1882         window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
1883
1884         vec3 shade_I = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
1885         vec3 view_reflection = reflect(shade_I, normalize(N));
1886         reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
1887 }
1888
1889 void node_tex_coord_background(
1890         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
1891         vec3 attr_orco, vec3 attr_uv,
1892         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
1893         out vec3 camera, out vec3 window, out vec3 reflection)
1894 {
1895         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
1896         vec4 co_homogenous = (ProjectionMatrixInverse * v);
1897
1898         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
1899
1900         co = normalize(co);
1901
1902 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
1903         vec3 coords = (ViewMatrixInverse * co).xyz;
1904 #else
1905         vec3 coords = (ModelViewMatrixInverse * co).xyz;
1906 #endif
1907
1908         generated = coords;
1909         normal = -coords;
1910         uv = vec3(attr_uv.xy, 0.0);
1911         object = coords;
1912
1913         camera = vec3(co.xy, -co.z);
1914         window = vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0);
1915
1916         reflection = -coords;
1917 }
1918
1919 #if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER))
1920 #define node_tex_coord node_tex_coord_background
1921 #endif
1922
1923 /* textures */
1924
1925 float calc_gradient(vec3 p, int gradient_type)
1926 {
1927         float x, y, z;
1928         x = p.x;
1929         y = p.y;
1930         z = p.z;
1931         if (gradient_type == 0) {  /* linear */
1932                 return x;
1933         }
1934         else if (gradient_type == 1) {  /* quadratic */
1935                 float r = max(x, 0.0);
1936                 return r * r;
1937         }
1938         else if (gradient_type == 2) {  /* easing */
1939                 float r = min(max(x, 0.0), 1.0);
1940                 float t = r * r;
1941                 return (3.0 * t - 2.0 * t * r);
1942         }
1943         else if (gradient_type == 3) {  /* diagonal */
1944                 return (x + y) * 0.5;
1945         }
1946         else if (gradient_type == 4) {  /* radial */
1947                 return atan(y, x) / (M_PI * 2) + 0.5;
1948         }
1949         else {
1950                 /* Bias a little bit for the case where p is a unit length vector,
1951                  * to get exactly zero instead of a small random value depending
1952                  * on float precision. */
1953                 float r = max(0.999999 - sqrt(x * x + y * y + z * z), 0.0);
1954                 if (gradient_type == 5) {  /* quadratic sphere */
1955                         return r * r;
1956                 }
1957                 else if (gradient_type == 6) {  /* sphere */
1958                         return r;
1959                 }
1960         }
1961         return 0.0;
1962 }
1963
1964 void node_tex_gradient(vec3 co, float gradient_type, out vec4 color, out float fac)
1965 {
1966         float f = calc_gradient(co, int(gradient_type));
1967         f = clamp(f, 0.0, 1.0);
1968
1969         color = vec4(f, f, f, 1.0);
1970         fac = f;
1971 }
1972
1973 void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
1974 {
1975         vec3 p = co * scale;
1976
1977         /* Prevent precision issues on unit coordinates. */
1978         p = (p + 0.000001) * 0.999999;
1979
1980         int xi = int(abs(floor(p.x)));
1981         int yi = int(abs(floor(p.y)));
1982         int zi = int(abs(floor(p.z)));
1983
1984         bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2)));
1985
1986         color = check ? color1 : color2;
1987         fac = check ? 1.0 : 0.0;
1988 }
1989
1990 vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
1991                         float brick_width, float row_height,
1992                         float offset_amount, int offset_frequency,
1993                         float squash_amount, int squash_frequency)
1994 {
1995         int bricknum, rownum;
1996         float offset = 0.0;
1997         float x, y;
1998
1999         rownum = floor_to_int(p.y / row_height);
2000
2001         if (offset_frequency != 0 && squash_frequency != 0) {
2002                 brick_width *= (rownum % squash_frequency != 0) ? 1.0 : squash_amount; /* squash */
2003                 offset = (rownum % offset_frequency != 0) ? 0.0 : (brick_width * offset_amount); /* offset */
2004         }
2005
2006         bricknum = floor_to_int((p.x + offset) / brick_width);
2007
2008         x = (p.x + offset) - brick_width * bricknum;
2009         y = p.y - row_height * rownum;
2010
2011         float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0);
2012
2013         float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
2014         if (min_dist >= mortar_size) {
2015                 return vec2(tint, 0.0);
2016         }
2017         else if (mortar_smooth == 0.0) {
2018                 return vec2(tint, 1.0);
2019         }
2020         else {
2021                 min_dist = 1.0 - min_dist/mortar_size;
2022                 return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
2023         }
2024 }
2025
2026 void node_tex_brick(vec3 co,
2027                     vec4 color1, vec4 color2,
2028                     vec4 mortar, float scale,
2029                     float mortar_size, float mortar_smooth, float bias,
2030                     float brick_width, float row_height,
2031                     float offset_amount, float offset_frequency,
2032                     float squash_amount, float squash_frequency,
2033                     out vec4 color, out float fac)
2034 {
2035         vec2 f2 = calc_brick_texture(co * scale,
2036                                      mortar_size, mortar_smooth, bias,
2037                                      brick_width, row_height,
2038                                      offset_amount, int(offset_frequency),
2039                                      squash_amount, int(squash_frequency));
2040         float tint = f2.x;
2041         float f = f2.y;
2042         if (f != 1.0) {
2043                 float facm = 1.0 - tint;
2044                 color1 = facm * color1 + tint * color2;
2045         }
2046         color = mix(color1, mortar, f);
2047         fac = f;
2048 }
2049
2050 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
2051 {
2052         color = vec4(1.0);
2053         fac = 1.0;
2054 }
2055
2056 void node_tex_environment_equirectangular(vec3 co, float clamp_size, sampler2D ima, out vec3 uv)
2057 {
2058         vec3 nco = normalize(co);
2059         uv.x = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
2060         uv.y = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
2061
2062         /* Fix pole bleeding */
2063         float half_height = clamp_size / float(textureSize(ima, 0).y);
2064         uv.y = clamp(uv.y, half_height, 1.0 - half_height);
2065         uv.z = 0.0;
2066 }
2067
2068 void node_tex_environment_mirror_ball(vec3 co, out vec3 uv)
2069 {
2070         vec3 nco = normalize(co);
2071         nco.y -= 1.0;
2072
2073         float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
2074         nco /= max(1e-8, div);
2075
2076         uv = 0.5 * nco.xzz + 0.5;
2077 }
2078
2079 void node_tex_environment_empty(vec3 co, out vec4 color)
2080 {
2081         color = vec4(1.0, 0.0, 1.0, 1.0);
2082 }
2083
2084 /* 16bits floats limits. Higher/Lower values produce +/-inf. */
2085 #define safe_color(a) (clamp(a, -65520.0, 65520.0))
2086
2087 void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2088 {
2089         color = safe_color(texture(ima, co.xy));
2090         alpha = color.a;
2091 }
2092
2093 void node_tex_image_linear_no_mip(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2094 {
2095         color = safe_color(textureLod(ima, co.xy, 0.0));
2096         alpha = color.a;
2097 }
2098
2099 void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2100 {
2101         ivec2 pix = ivec2(fract(co.xy) * textureSize(ima, 0).xy);
2102         color = clamp(texelFetch(ima, pix, 0));
2103         alpha = color.a;
2104 }
2105
2106 /* @arg f: signed distance to texel center. */
2107 void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3)
2108 {
2109         vec2 f2 = f * f;
2110         vec2 f3 = f2 * f;
2111         /* Bspline coefs (optimized) */
2112         w3 =  f3 / 6.0;
2113         w0 = -w3       + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
2114         w1 =  f3 * 0.5 - f2 * 1.0           + 2.0 / 3.0;
2115         w2 = 1.0 - w0 - w1 - w3;
2116 }
2117
2118 void node_tex_image_cubic_ex(vec3 co, sampler2D ima, float do_extend, out vec4 color, out float alpha)
2119 {
2120         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2121
2122         co.xy *= tex_size;
2123         /* texel center */
2124         vec2 tc = floor(co.xy - 0.5) + 0.5;
2125         vec2 w0, w1, w2, w3;
2126         cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
2127
2128 #if 1 /* Optimized version using 4 filtered tap. */
2129         vec2 s0 = w0 + w1;
2130         vec2 s1 = w2 + w3;
2131
2132         vec2 f0 = w1 / (w0 + w1);
2133         vec2 f1 = w3 / (w2 + w3);
2134
2135         vec4 final_co;
2136         final_co.xy = tc - 1.0 + f0;
2137         final_co.zw = tc + 1.0 + f1;
2138
2139         if (do_extend == 1.0) {
2140                 final_co = clamp(final_co, vec4(0.5), tex_size.xyxy - 0.5);
2141         }
2142         final_co /= tex_size.xyxy;
2143
2144         color  = safe_color(textureLod(ima, final_co.xy, 0.0)) * s0.x * s0.y;
2145         color += safe_color(textureLod(ima, final_co.zy, 0.0)) * s1.x * s0.y;
2146         color += safe_color(textureLod(ima, final_co.xw, 0.0)) * s0.x * s1.y;
2147         color += safe_color(textureLod(ima, final_co.zw, 0.0)) * s1.x * s1.y;
2148
2149 #else /* Reference bruteforce 16 tap. */
2150         color  = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y;
2151         color += texelFetch(ima, ivec2(tc + vec2( 0.0, -1.0)), 0) * w1.x * w0.y;
2152         color += texelFetch(ima, ivec2(tc + vec2( 1.0, -1.0)), 0) * w2.x * w0.y;
2153         color += texelFetch(ima, ivec2(tc + vec2( 2.0, -1.0)), 0) * w3.x * w0.y;
2154
2155         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y;
2156         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 0.0)), 0) * w1.x * w1.y;
2157         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 0.0)), 0) * w2.x * w1.y;
2158         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 0.0)), 0) * w3.x * w1.y;
2159
2160         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y;
2161         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 1.0)), 0) * w1.x * w2.y;
2162         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 1.0)), 0) * w2.x * w2.y;
2163         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 1.0)), 0) * w3.x * w2.y;
2164
2165         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y;
2166         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 2.0)), 0) * w1.x * w3.y;
2167         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 2.0)), 0) * w2.x * w3.y;
2168         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 2.0)), 0) * w3.x * w3.y;
2169 #endif
2170
2171         alpha = color.a;
2172 }
2173
2174 void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2175 {
2176         node_tex_image_cubic_ex(co, ima, 0.0, color, alpha);
2177 }
2178
2179 void node_tex_image_cubic_extend(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2180 {
2181         node_tex_image_cubic_ex(co, ima, 1.0, color, alpha);
2182 }
2183
2184 void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2185 {
2186         /* use cubic for now */
2187         node_tex_image_cubic_ex(co, ima, 0.0, color, alpha);
2188 }
2189
2190 void tex_box_sample_linear(vec3 texco,
2191                     vec3 N,
2192                     sampler2D ima,
2193                     out vec4 color1,
2194                     out vec4 color2,
2195                     out vec4 color3)
2196 {
2197         /* X projection */
2198         vec2 uv = texco.yz;
2199         if (N.x < 0.0) {
2200                 uv.x = 1.0 - uv.x;
2201         }
2202         color1 = texture(ima, uv);
2203         /* Y projection */
2204         uv = texco.xz;
2205         if (N.y > 0.0) {
2206                 uv.x = 1.0 - uv.x;
2207         }
2208         color2 = texture(ima, uv);
2209         /* Z projection */
2210         uv = texco.yx;
2211         if (N.z > 0.0) {
2212                 uv.x = 1.0 - uv.x;
2213         }
2214         color3 = texture(ima, uv);
2215 }
2216
2217 void tex_box_sample_nearest(vec3 texco,
2218                     vec3 N,
2219                     sampler2D ima,
2220                     out vec4 color1,
2221                     out vec4 color2,
2222                     out vec4 color3)
2223 {
2224         /* X projection */
2225         vec2 uv = texco.yz;
2226         if (N.x < 0.0) {
2227                 uv.x = 1.0 - uv.x;
2228         }
2229         ivec2 pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2230         color1 = texelFetch(ima, pix, 0);
2231         /* Y projection */
2232         uv = texco.xz;
2233         if (N.y > 0.0) {
2234                 uv.x = 1.0 - uv.x;
2235         }
2236         pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2237         color2 = texelFetch(ima, pix, 0);
2238         /* Z projection */
2239         uv = texco.yx;
2240         if (N.z > 0.0) {
2241                 uv.x = 1.0 - uv.x;
2242         }
2243         pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2244         color3 = texelFetch(ima, pix, 0);
2245 }
2246
2247 void tex_box_sample_cubic(vec3 texco,
2248                     vec3 N,
2249                     sampler2D ima,
2250                     out vec4 color1,
2251                     out vec4 color2,
2252                     out vec4 color3)
2253 {
2254         float alpha;
2255         /* X projection */
2256         vec2 uv = texco.yz;
2257         if (N.x < 0.0) {
2258                 uv.x = 1.0 - uv.x;
2259         }
2260         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color1, alpha);
2261         /* Y projection */
2262         uv = texco.xz;
2263         if (N.y > 0.0) {
2264                 uv.x = 1.0 - uv.x;
2265         }
2266         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color2, alpha);
2267         /* Z projection */
2268         uv = texco.yx;
2269         if (N.z > 0.0) {
2270                 uv.x = 1.0 - uv.x;
2271         }
2272         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color3, alpha);
2273 }
2274
2275 void tex_box_sample_smart(vec3 texco,
2276                     vec3 N,
2277                     sampler2D ima,
2278                     out vec4 color1,
2279                     out vec4 color2,
2280                     out vec4 color3)
2281 {
2282         tex_box_sample_cubic(texco, N, ima, color1, color2, color3);
2283 }
2284
2285 void node_tex_image_box(vec3 texco,
2286                         vec3 N,
2287                         vec4 color1,
2288                         vec4 color2,
2289                         vec4 color3,
2290                         sampler2D ima,
2291                         float blend,
2292                         out vec4 color,
2293                         out float alpha)
2294 {
2295         /* project from direction vector to barycentric coordinates in triangles */
2296         N = abs(N);
2297         N /= dot(N, vec3(1.0));
2298
2299         /* basic idea is to think of this as a triangle, each corner representing
2300          * one of the 3 faces of the cube. in the corners we have single textures,
2301          * in between we blend between two textures, and in the middle we a blend
2302          * between three textures.
2303          *
2304          * the Nxyz values are the barycentric coordinates in an equilateral
2305          * triangle, which in case of blending, in the middle has a smaller
2306          * equilateral triangle where 3 textures blend. this divides things into
2307          * 7 zones, with an if () test for each zone
2308          * EDIT: Now there is only 4 if's. */
2309
2310         float limit = 0.5 + 0.5 * blend;
2311
2312         vec3 weight;
2313         weight = N.xyz / (N.xyx + N.yzz);
2314         weight = clamp((weight - 0.5 * (1.0 - blend)) / max(1e-8, blend), 0.0, 1.0);
2315
2316         /* test for mixes between two textures */
2317         if (N.z < (1.0 - limit) * (N.y + N.x)) {
2318                 weight.z = 0.0;
2319                 weight.y = 1.0 - weight.x;
2320         }
2321         else if (N.x < (1.0 - limit) * (N.y + N.z)) {
2322                 weight.x = 0.0;
2323                 weight.z = 1.0 - weight.y;
2324         }
2325         else if (N.y < (1.0 - limit) * (N.x + N.z)) {
2326                 weight.y = 0.0;
2327                 weight.x = 1.0 - weight.z;
2328         }
2329         else {
2330                 /* last case, we have a mix between three */
2331                 weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, blend);
2332         }
2333
2334         color = weight.x * color1 + weight.y * color2 + weight.z * color3;
2335         alpha = color.a;
2336 }
2337
2338 void tex_clip_linear(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2339 {
2340         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2341         vec2 minco = min(co.xy, 1.0 - co.xy);
2342         minco = clamp(minco * tex_size + 0.5, 0.0, 1.0);
2343         float fac = minco.x * minco.y;
2344
2345         color = mix(vec4(0.0), icolor, fac);
2346         alpha = color.a;
2347 }
2348
2349 void tex_clip_nearest(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2350 {
2351         vec4 minco = vec4(co.xy, 1.0 - co.xy);
2352         color = (any(lessThan(minco, vec4(0.0)))) ? vec4(0.0) : icolor;
2353         alpha = color.a;
2354 }
2355
2356 void tex_clip_cubic(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2357 {
2358         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2359
2360         co.xy *= tex_size;
2361         /* texel center */
2362         vec2 tc = floor(co.xy - 0.5) + 0.5;
2363         vec2 w0, w1, w2, w3;
2364         cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
2365
2366         /* TODO Optimize this part. I'm sure there is a smarter way to do that.
2367          * Could do that when sampling? */
2368 #define CLIP_CUBIC_SAMPLE(samp, size) (float(all(greaterThan(samp, vec2(-0.5)))) * float(all(lessThan(ivec2(samp), itex_size))))
2369         ivec2 itex_size = textureSize(ima, 0).xy;
2370         float fac;
2371         fac  = CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, -1.0), itex_size) * w0.x * w0.y;
2372         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0, -1.0), itex_size) * w1.x * w0.y;
2373         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0, -1.0), itex_size) * w2.x * w0.y;
2374         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0, -1.0), itex_size) * w3.x * w0.y;
2375
2376         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  0.0), itex_size) * w0.x * w1.y;
2377         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  0.0), itex_size) * w1.x * w1.y;
2378         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  0.0), itex_size) * w2.x * w1.y;
2379         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  0.0), itex_size) * w3.x * w1.y;
2380
2381         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  1.0), itex_size) * w0.x * w2.y;
2382         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  1.0), itex_size) * w1.x * w2.y;
2383         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  1.0), itex_size) * w2.x * w2.y;
2384         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  1.0), itex_size) * w3.x * w2.y;
2385
2386         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  2.0), itex_size) * w0.x * w3.y;
2387         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  2.0), itex_size) * w1.x * w3.y;
2388         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  2.0), itex_size) * w2.x * w3.y;
2389         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  2.0), itex_size) * w3.x * w3.y;
2390 #undef CLIP_CUBIC_SAMPLE
2391
2392         color = mix(vec4(0.0), icolor, fac);
2393         alpha = color.a;
2394 }
2395
2396 void tex_clip_smart(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2397 {
2398         tex_clip_cubic(co, ima, icolor, color, alpha);
2399 }
2400
2401 void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
2402 {
2403         color = vec4(0.0);
2404         alpha = 0.0;
2405 }
2406
2407 void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
2408 {
2409         vec3 p = co * scale;
2410         float x = sin((p.x + p.y + p.z) * 5.0);
2411         float y = cos((-p.x + p.y - p.z) * 5.0);
2412         float z = -cos((-p.x - p.y + p.z) * 5.0);
2413
2414         if (depth > 0) {
2415                 x *= distortion;
2416                 y *= distortion;
2417                 z *= distortion;
2418                 y = -cos(x - y + z);
2419                 y *= distortion;
2420                 if (depth > 1) {
2421                         x = cos(x - y - z);
2422                         x *= distortion;
2423                         if (depth > 2) {
2424                                 z = sin(-x - y - z);
2425                                 z *= distortion;
2426                                 if (depth > 3) {
2427                                         x = -cos(-x + y - z);
2428                                         x *= distortion;
2429                                         if (depth > 4) {
2430                                                 y = -sin(-x + y + z);
2431                                                 y *= distortion;
2432                                                 if (depth > 5) {
2433                                                         y = -cos(-x + y + z);
2434                                                         y *= distortion;
2435                                                         if (depth > 6) {
2436                                                                 x = cos(x + y + z);
2437                                                                 x *= distortion;
2438                                                                 if (depth > 7) {
2439                                                                         z = sin(x + y - z);
2440                                                                         z *= distortion;
2441                                                                         if (depth > 8) {
2442                                                                                 x = -cos(-x - y + z);
2443                                                                                 x *= distortion;
2444                                                                                 if (depth > 9) {
2445                                                                                         y = -sin(x - y + z);
2446                                                                                         y *= distortion;
2447                                                                                 }
2448                                                                         }
2449                                                                 }
2450                                                         }
2451                                                 }
2452                                         }
2453                                 }
2454                         }
2455                 }
2456         }
2457         if (distortion != 0.0) {
2458                 distortion *= 2.0;
2459                 x /= distortion;
2460                 y /= distortion;
2461                 z /= distortion;
2462         }
2463
2464         color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
2465         fac = (color.x + color.y + color.z) / 3.0;
2466 }
2467
2468 float noise_fade(float t)
2469 {
2470         return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
2471 }
2472
2473 float noise_scale3(float result)
2474 {
2475         return 0.9820 * result;
2476 }
2477
2478 float noise_nerp(float t, float a, float b)
2479 {
2480         return (1.0 - t) * a + t * b;
2481 }
2482
2483 float noise_grad(uint hash, float x, float y, float z)
2484 {
2485         uint h = hash & 15u;
2486         float u = h < 8u ? x : y;
2487         float vt = ((h == 12u) || (h == 14u)) ? x : z;
2488         float v = h < 4u ? y : vt;
2489         return (((h & 1u) != 0u) ? -u : u) + (((h & 2u) != 0u) ? -v : v);
2490 }
2491
2492 float noise_perlin(float x, float y, float z)
2493 {
2494         int X; float fx = floorfrac(x, X);
2495         int Y; float fy = floorfrac(y, Y);
2496         int Z; float fz = floorfrac(z, Z);
2497
2498         float u = noise_fade(fx);
2499         float v = noise_fade(fy);
2500         float w = noise_fade(fz);
2501
2502         float noise_u[2], noise_v[2];
2503
2504         noise_u[0] = noise_nerp(u,
2505                 noise_grad(hash(X, Y, Z), fx, fy, fz),
2506                 noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz));
2507
2508         noise_u[1] = noise_nerp(u,
2509                 noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
2510                 noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz));
2511
2512         noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]);
2513
2514         noise_u[0] = noise_nerp(u,
2515                 noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
2516                 noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0));
2517
2518         noise_u[1] = noise_nerp(u,
2519                 noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
2520                 noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0));
2521
2522         noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]);
2523
2524         return noise_scale3(noise_nerp(w, noise_v[0], noise_v[1]));
2525 }
2526
2527 float noise(vec3 p)
2528 {
2529         return 0.5 * noise_perlin(p.x, p.y, p.z) + 0.5;
2530 }
2531
2532 float snoise(vec3 p)
2533 {
2534         return noise_perlin(p.x, p.y, p.z);
2535 }
2536
2537 float noise_turbulence(vec3 p, float octaves, int hard)
2538 {
2539         float fscale = 1.0;
2540         float amp = 1.0;
2541         float sum = 0.0;
2542         octaves = clamp(octaves, 0.0, 16.0);
2543         int n = int(octaves);
2544         for (int i = 0; i <= n; i++) {
2545                 float t = noise(fscale * p);
2546                 if (hard != 0) {
2547                         t = abs(2.0 * t - 1.0);
2548                 }
2549                 sum += t * amp;
2550                 amp *= 0.5;
2551                 fscale *= 2.0;
2552         }
2553         float rmd = octaves - floor(octaves);
2554         if (rmd != 0.0) {
2555                 float t = noise(fscale * p);
2556                 if (hard != 0) {
2557                         t = abs(2.0 * t - 1.0);
2558                 }
2559                 float sum2 = sum + t * amp;
2560                 sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
2561                 sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
2562                 return (1.0 - rmd) * sum + rmd * sum2;
2563         }
2564         else {
2565                 sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
2566                 return sum;
2567         }
2568 }
2569
2570 void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
2571 {
2572         vec3 p = co * scale;
2573         int hard = 0;
2574         if (distortion != 0.0) {
2575                 vec3 r, offset = vec3(13.5, 13.5, 13.5);
2576                 r.x = noise(p + offset) * distortion;
2577                 r.y = noise(p) * distortion;
2578                 r.z = noise(p - offset) * distortion;
2579                 p += r;
2580         }
2581
2582         fac = noise_turbulence(p, detail, hard);
2583         color = vec4(fac,
2584                      noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
2585                      noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
2586                      1);
2587 }
2588
2589 /* Musgrave fBm
2590  *
2591  * H: fractal increment parameter
2592  * lacunarity: gap between successive frequencies
2593  * octaves: number of frequencies in the fBm
2594  *
2595  * from "Texturing and Modelling: A procedural approach"
2596  */
2597
2598 float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
2599 {
2600         float rmd;
2601         float value = 0.0;
2602         float pwr = 1.0;
2603         float pwHL = pow(lacunarity, -H);
2604
2605         for (int i = 0; i < int(octaves); i++) {
2606                 value += snoise(p) * pwr;
2607                 pwr *= pwHL;
2608                 p *= lacunarity;
2609         }
2610
2611         rmd = octaves - floor(octaves);
2612         if (rmd != 0.0)
2613                 value += rmd * snoise(p) * pwr;
2614
2615         return value;
2616 }
2617
2618 /* Musgrave Multifractal
2619  *
2620  * H: highest fractal dimension
2621  * lacunarity: gap between successive frequencies
2622  * octaves: number of frequencies in the fBm
2623  */
2624
2625 float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octaves)
2626 {
2627         float rmd;
2628         float value = 1.0;
2629         float pwr = 1.0;
2630         float pwHL = pow(lacunarity, -H);
2631
2632         for (int i = 0; i < int(octaves); i++) {
2633                 value *= (pwr * snoise(p) + 1.0);
2634                 pwr *= pwHL;
2635                 p *= lacunarity;
2636         }
2637
2638         rmd = octaves - floor(octaves);
2639         if (rmd != 0.0)
2640                 value *= (rmd * pwr * snoise(p) + 1.0); /* correct? */
2641
2642         return value;
2643 }
2644
2645 /* Musgrave Heterogeneous Terrain
2646  *
2647  * H: fractal dimension of the roughest area
2648  * lacunarity: gap between successive frequencies
2649  * octaves: number of frequencies in the fBm
2650  * offset: raises the terrain from `sea level'
2651  */
2652
2653 float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float octaves, float offset)
2654 {
2655         float value, increment, rmd;
2656         float pwHL = pow(lacunarity, -H);
2657         float pwr = pwHL;
2658
2659         /* first unscaled octave of function; later octaves are scaled */
2660         value = offset + snoise(p);
2661         p *= lacunarity;
2662
2663         for (int i = 1; i < int(octaves); i++) {
2664                 increment = (snoise(p) + offset) * pwr * value;
2665                 value += increment;
2666                 pwr *= pwHL;
2667                 p *= lacunarity;
2668         }
2669
2670         rmd = octaves - floor(octaves);
2671         if (rmd != 0.0) {
2672                 increment = (snoise(p) + offset) * pwr * value;
2673                 value += rmd * increment;
2674         }
2675
2676         return value;
2677 }
2678
2679 /* Hybrid Additive/Multiplicative Multifractal Terrain
2680  *
2681  * H: fractal dimension of the roughest area
2682  * lacunarity: gap between successive frequencies
2683  * octaves: number of frequencies in the fBm
2684  * offset: raises the terrain from `sea level'
2685  */
2686
2687 float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
2688 {
2689         float result, signal, weight, rmd;
2690         float pwHL = pow(lacunarity, -H);
2691         float pwr = pwHL;
2692
2693         result = snoise(p) + offset;
2694         weight = gain * result;
2695         p *= lacunarity;
2696
2697         for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
2698                 if (weight > 1.0)
2699                         weight = 1.0;
2700
2701                 signal = (snoise(p) + offset) * pwr;
2702                 pwr *= pwHL;
2703                 result += weight * signal;
2704                 weight *= gain * signal;
2705                 p *= lacunarity;
2706         }
2707
2708         rmd = octaves - floor(octaves);
2709         if (rmd != 0.0)
2710                 result += rmd * ((snoise(p) + offset) * pwr);
2711
2712         return result;
2713 }
2714
2715 /* Ridged Multifractal Terrain
2716  *
2717  * H: fractal dimension of the roughest area
2718  * lacunarity: gap between successive frequencies
2719  * octaves: number of frequencies in the fBm
2720  * offset: raises the terrain from `sea level'
2721  */
2722
2723 float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
2724 {
2725         float result, signal, weight;
2726         float pwHL = pow(lacunarity, -H);
2727         float pwr = pwHL;
2728
2729         signal = offset - abs(snoise(p));
2730         signal *= signal;
2731         result = signal;
2732         weight = 1.0;
2733
2734         for (int i = 1; i < int(octaves); i++) {
2735                 p *= lacunarity;
2736                 weight = clamp(signal * gain, 0.0, 1.0);
2737                 signal = offset - abs(snoise(p));
2738                 signal *= signal;
2739                 signal *= weight;
2740                 result += signal * pwr;
2741                 pwr *= pwHL;
2742         }
2743
2744         return result;
2745 }
2746
2747 float svm_musgrave(int type,
2748                    float dimension,
2749                    float lacunarity,
2750                    float octaves,
2751                    float offset,
2752                    float intensity,
2753                    float gain,
2754                    vec3 p)
2755 {
2756         if (type == 0 /* NODE_MUSGRAVE_MULTIFRACTAL */)
2757                 return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
2758         else if (type == 1 /* NODE_MUSGRAVE_FBM */)
2759                 return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
2760         else if (type == 2 /* NODE_MUSGRAVE_HYBRID_MULTIFRACTAL */)
2761                 return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
2762         else if (type == 3 /* NODE_MUSGRAVE_RIDGED_MULTIFRACTAL */)
2763                 return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
2764         else if (type == 4 /* NODE_MUSGRAVE_HETERO_TERRAIN */)
2765                 return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
2766         return 0.0;
2767 }
2768
2769 void node_tex_musgrave(vec3 co,
2770                        float scale,
2771                        float detail,
2772                        float dimension,
2773                        float lacunarity,
2774                        float offset,
2775                        float gain,
2776                        float type,
2777                        out vec4 color,
2778                        out float fac)
2779 {
2780         fac = svm_musgrave(int(type),
2781                            dimension,
2782                            lacunarity,
2783                            detail,
2784                            offset,
2785                            1.0,
2786                            gain,
2787                            co * scale);
2788
2789         color = vec4(fac, fac, fac, 1.0);
2790 }
2791
2792 void node_tex_sky(vec3 co, out vec4 color)
2793 {
2794         color = vec4(1.0);
2795 }
2796
2797 void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, float metric, float feature, out vec4 color, out float fac)
2798 {
2799         vec3 p = co * scale;
2800         int xx, yy, zz, xi, yi, zi;
2801         vec4 da = vec4(1e10);
2802         vec3 pa[4] = vec3[4](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
2803
2804         xi = floor_to_int(p[0]);
2805         yi = floor_to_int(p[1]);
2806         zi = floor_to_int(p[2]);
2807
2808         for (xx = xi - 1; xx <= xi + 1; xx++) {
2809                 for (yy = yi - 1; yy <= yi + 1; yy++) {
2810                         for (zz = zi - 1; zz <= zi + 1; zz++) {
2811                                 vec3 ip = vec3(xx, yy, zz);
2812                                 vec3 vp = cellnoise_color(ip);
2813                                 vec3 pd = p - (vp + ip);
2814
2815                                 float d = 0.0;
2816                                 if (metric == 0.0) { /* SHD_VORONOI_DISTANCE 0 */
2817                                         d = dot(pd, pd);
2818                                 }
2819                                 else if (metric == 1.0) { /* SHD_VORONOI_MANHATTAN 1 */
2820                                         d = abs(pd[0]) + abs(pd[1]) + abs(pd[2]);
2821                                 }
2822                                 else if (metric == 2.0) { /* SHD_VORONOI_CHEBYCHEV 2 */
2823                                         d = max(abs(pd[0]), max(abs(pd[1]), abs(pd[2])));
2824                                 }
2825                                 else if (metric == 3.0) { /* SHD_VORONOI_MINKOWSKI 3 */
2826                                         d = pow(pow(abs(pd[0]), exponent) + pow(abs(pd[1]), exponent) + pow(abs(pd[2]), exponent), 1.0/exponent);
2827                                 }
2828
2829                                 vp += vec3(xx, yy, zz);
2830                                 if (d < da[0]) {
2831                                         da.yzw = da.xyz;
2832                                         da[0] = d;
2833
2834                                         pa[3] = pa[2];
2835                                         pa[2] = pa[1];
2836                                         pa[1] = pa[0];
2837                                         pa[0] = vp;
2838                                 }
2839                                 else if (d < da[1]) {
2840                                         da.zw = da.yz;
2841                                         da[1] = d;
2842
2843                                         pa[3] = pa[2];
2844                                         pa[2] = pa[1];
2845                                         pa[1] = vp;
2846                                 }
2847                                 else if (d < da[2]) {
2848                                         da[3] = da[2];
2849                                         da[2] = d;
2850
2851                                         pa[3] = pa[2];
2852                                         pa[2] = vp;
2853                                 }
2854                                 else if (d < da[3]) {
2855                                         da[3] = d;
2856                                         pa[3] = vp;
2857                                 }
2858                         }
2859                 }
2860         }
2861
2862         if (coloring == 0.0) {
2863                 /* Intensity output */
2864                 if (feature == 0.0) { /* F1 */
2865                         fac = abs(da[0]);
2866                 }
2867                 else if (feature == 1.0) { /* F2 */
2868                         fac = abs(da[1]);
2869                 }
2870                 else if (feature == 2.0) { /* F3 */
2871                         fac = abs(da[2]);
2872                 }
2873                 else if (feature == 3.0) { /* F4 */
2874                         fac = abs(da[3]);
2875                 }
2876                 else if (feature == 4.0) { /* F2F1 */
2877                         fac = abs(da[1] - da[0]);
2878                 }
2879                 color = vec4(fac, fac, fac, 1.0);
2880         }
2881         else {
2882                 /* Color output */
2883                 vec3 col = vec3(fac, fac, fac);
2884                 if (feature == 0.0) { /* F1 */
2885                         col = pa[0];
2886                 }
2887                 else if (feature == 1.0) { /* F2 */
2888                         col = pa[1];
2889                 }
2890                 else if (feature == 2.0) { /* F3 */
2891                         col = pa[2];
2892                 }
2893                 else if (feature == 3.0) { /* F4 */
2894                         col = pa[3];
2895                 }
2896                 else if (feature == 4.0) { /* F2F1 */
2897                         col = abs(pa[1] - pa[0]);
2898                 }
2899
2900                 color = vec4(cellnoise_color(col), 1.0);
2901                 fac = (color.x + color.y + color.z) * (1.0 / 3.0);
2902         }
2903 }
2904
2905 float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
2906 {
2907         float n;
2908
2909         if (wave_type == 0) /* type bands */
2910                 n = (p.x + p.y + p.z) * 10.0;
2911         else /* type rings */
2912                 n = length(p) * 20.0;
2913
2914         if (distortion != 0.0)
2915                 n += distortion * noise_turbulence(p * detail_scale, detail, 0);
2916
2917         if (wave_profile == 0) { /* profile sin */
2918                 return 0.5 + 0.5 * sin(n);
2919         }
2920         else { /* profile saw */
2921                 n /= 2.0 * M_PI;
2922                 n -= int(n);
2923                 return (n < 0.0) ? n + 1.0 : n;
2924         }
2925 }
2926
2927 void node_tex_wave(
2928         vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
2929         out vec4 color, out float fac)
2930 {
2931         float f;
2932         f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
2933
2934         color = vec4(f, f, f, 1.0);
2935         fac = f;
2936 }
2937
2938 /* light path */
2939
2940 void node_light_path(
2941         out float is_camera_ray,
2942         out float is_shadow_ray,
2943         out float is_diffuse_ray,
2944         out float is_glossy_ray,
2945         out float is_singular_ray,
2946         out float is_reflection_ray,
2947         out float is_transmission_ray,
2948         out float ray_length,
2949         out float ray_depth,
2950         out float diffuse_depth,
2951         out float glossy_depth,
2952         out float transparent_depth,
2953         out float transmission_depth)
2954 {
2955         /* Supported. */
2956         is_camera_ray = (rayType == EEVEE_RAY_CAMERA) ? 1.0 : 0.0;
2957         is_shadow_ray = (rayType == EEVEE_RAY_SHADOW) ? 1.0 : 0.0;
2958         is_diffuse_ray = (rayType == EEVEE_RAY_DIFFUSE) ? 1.0 : 0.0;
2959         is_glossy_ray = (rayType == EEVEE_RAY_GLOSSY) ? 1.0 : 0.0;
2960         /* Kind of supported. */
2961         is_singular_ray = is_glossy_ray;
2962         is_reflection_ray = is_glossy_ray;
2963         is_transmission_ray = is_glossy_ray;
2964         ray_depth = rayDepth;
2965         diffuse_depth = (is_diffuse_ray == 1.0) ? rayDepth : 0.0;
2966         glossy_depth = (is_glossy_ray == 1.0) ? rayDepth : 0.0;
2967         transmission_depth = (is_transmission_ray == 1.0) ? glossy_depth : 0.0;
2968         /* Not supported. */
2969         ray_length = 1.0;
2970         transparent_depth = 0.0;
2971 }
2972
2973 void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
2974 {
2975         quadratic = strength;
2976         linear = strength;
2977         constant = strength;
2978 }
2979
2980 void node_object_info(mat4 obmat, vec4 info, out vec3 location, out float object_index, out float material_index, out float random)
2981 {
2982         location = obmat[3].xyz;
2983         object_index = info.x;
2984         material_index = info.y;
2985         random = info.z;
2986 }
2987
2988 void node_normal_map(vec4 info, vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
2989 {
2990         if (all(equal(tangent, vec4(0.0, 0.0, 0.0, 1.0)))) {
2991                 outnormal = normal;
2992                 return;
2993         }
2994         tangent *= (gl_FrontFacing ? 1.0 : -1.0);
2995         vec3 B = tangent.w * cross(normal, tangent.xyz) * info.w;
2996
2997         outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
2998         outnormal = normalize(outnormal);
2999 }
3000
3001 void node_bump(float strength, float dist, float height, vec3 N, vec3 surf_pos, float invert, out vec3 result)
3002 {
3003         N = mat3(ViewMatrix) * normalize(N);
3004         dist *= invert;
3005
3006         vec3 dPdx = dFdx(surf_pos);
3007         vec3 dPdy = dFdy(surf_pos);
3008
3009         /* Get surface tangents from normal. */
3010         vec3 Rx = cross(dPdy, N);
3011         vec3 Ry = cross(N, dPdx);
3012
3013         /* Compute surface gradient and determinant. */
3014         float det = dot(dPdx, Rx);
3015
3016         float dHdx = dFdx(height);
3017         float dHdy = dFdy(height);
3018         vec3 surfgrad = dHdx * Rx + dHdy * Ry;
3019
3020         strength = max(strength, 0.0);
3021
3022         result = normalize(abs(det) * N - dist * sign(det) * surfgrad);
3023         result = normalize(mix(N, result, strength));
3024
3025         result = mat3(ViewMatrixInverse) * result;
3026 }
3027
3028 void node_bevel(float radius, vec3 N, out vec3 result)
3029 {
3030         result = N;
3031 }
3032
3033 void node_hair_info(out float is_strand, out float intercept, out float thickness, out vec3 tangent, out float random)
3034 {
3035 #ifdef HAIR_SHADER
3036         is_strand = 1.0;
3037         intercept = hairTime;
3038         thickness = hairThickness;
3039         tangent = normalize(hairTangent);
3040         random = wang_hash_noise(uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */
3041 #else
3042         is_strand = 0.0;
3043         intercept = 0.0;
3044         thickness = 0.0;
3045         tangent = vec3(1.0);
3046         random = 0.0;
3047 #endif
3048 }
3049
3050 void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result)
3051 {
3052         N = (vec4(N, 0.0) * obmat).xyz;
3053         result = (height - midlevel) * scale * normalize(N);
3054         result = (obmat * vec4(result, 0.0)).xyz;
3055 }
3056
3057 void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result)
3058 {
3059         result = (height - midlevel) * scale * normalize(N);
3060 }
3061
3062 void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result)
3063 {
3064         vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz);
3065         vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz);
3066         vec3 B_object = tangent.w * normalize(cross(N_object, T_object));
3067
3068         vec3 offset = (vector.xyz - vec3(midlevel)) * scale;
3069         result = offset.x * T_object + offset.y * N_object + offset.z * B_object;
3070         result = (obmat * vec4(result, 0.0)).xyz;
3071 }
3072
3073 void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result)
3074 {
3075         result = (vector.xyz - vec3(midlevel)) * scale;
3076         result = (obmat * vec4(result, 0.0)).xyz;
3077 }
3078
3079 void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result)
3080 {
3081         result = (vector.xyz - vec3(midlevel)) * scale;
3082 }
3083
3084 /* output */
3085
3086 void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result)
3087 {
3088 #ifdef VOLUMETRICS
3089         result = volume;
3090 #else
3091         result = surface;
3092 #endif
3093 }
3094
3095 uniform float backgroundAlpha;
3096
3097 void node_output_world(Closure surface, Closure volume, out Closure result)
3098 {
3099 #ifndef VOLUMETRICS
3100         result.radiance = surface.radiance * backgroundAlpha;
3101         result.opacity = backgroundAlpha;
3102 #else
3103         result = volume;
3104 #endif /* VOLUMETRICS */
3105 }
3106
3107 #ifndef VOLUMETRICS
3108 /* TODO : clean this ifdef mess */
3109 /* EEVEE output */
3110 void world_normals_get(out vec3 N)
3111 {
3112 #ifdef HAIR_SHADER
3113         vec3 B = normalize(cross(worldNormal, hairTangent));
3114         float cos_theta;
3115         if (hairThicknessRes == 1) {
3116                 vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
3117                 /* Random cosine normal distribution on the hair surface. */
3118                 cos_theta = rand.x * 2.0 - 1.0;
3119         }
3120         else {
3121                 /* Shade as a cylinder. */
3122                 cos_theta = hairThickTime / hairThickness;
3123         }
3124         float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));
3125         N = normalize(worldNormal * sin_theta + B * cos_theta);
3126 #else
3127         N = gl_FrontFacing ? worldNormal : -worldNormal;
3128 #endif
3129 }
3130
3131 void node_eevee_specular(
3132         vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
3133         float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
3134         float occlusion, float ssr_id, out Closure result)
3135 {
3136         vec3 out_diff, out_spec, ssr_spec;
3137         eevee_closure_default(normal, diffuse.rgb, specular.rgb, int(ssr_id), roughness, occlusion,
3138                               out_diff, out_spec, ssr_spec);
3139
3140         vec3 vN = normalize(mat3(ViewMatrix) * normal);
3141         result = CLOSURE_DEFAULT;
3142         result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
3143         result.opacity = 1.0 - transp;
3144         result.ssr_data = vec4(ssr_spec, roughness);
3145         result.ssr_normal = normal_encode(vN, viewCameraVec);
3146         result.ssr_id = int(ssr_id);
3147 }
3148
3149 void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha)
3150 {
3151         vec4 spec_accum = vec4(0.0);
3152         if (ssrToggle && cl.ssr_id == outputSsrId) {
3153                 vec3 V = cameraVec;
3154                 vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec);
3155                 vec3 N = transform_direction(ViewMatrixInverse, vN);
3156                 float roughness = cl.ssr_data.a;
3157                 float roughnessSquared = max(1e-3, roughness * roughness);
3158                 fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum);
3159         }
3160
3161         outalpha = cl.opacity;
3162         outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0);
3163
3164 #   ifdef USE_SSS
3165 #               ifdef USE_SSS_ALBEDO
3166         outcol.rgb += cl.sss_data.rgb * cl.sss_albedo;
3167 #       else
3168         outcol.rgb += cl.sss_data.rgb;
3169 #               endif
3170 #       endif
3171 }
3172
3173 #endif /* VOLUMETRICS */