Fix T62178 Eevee: Texture Box mapping not matching Cycles if object is scaled
[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 void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2085 {
2086         color = texture(ima, co.xy);
2087         alpha = color.a;
2088 }
2089
2090 void node_tex_image_linear_no_mip(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2091 {
2092         color = textureLod(ima, co.xy, 0.0);
2093         alpha = color.a;
2094 }
2095
2096 void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2097 {
2098         ivec2 pix = ivec2(fract(co.xy) * textureSize(ima, 0).xy);
2099         color = texelFetch(ima, pix, 0);
2100         alpha = color.a;
2101 }
2102
2103 /* @arg f: signed distance to texel center. */
2104 void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3)
2105 {
2106         vec2 f2 = f * f;
2107         vec2 f3 = f2 * f;
2108         /* Bspline coefs (optimized) */
2109         w3 =  f3 / 6.0;
2110         w0 = -w3       + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
2111         w1 =  f3 * 0.5 - f2 * 1.0           + 2.0 / 3.0;
2112         w2 = 1.0 - w0 - w1 - w3;
2113 }
2114
2115 void node_tex_image_cubic_ex(vec3 co, sampler2D ima, float do_extend, out vec4 color, out float alpha)
2116 {
2117         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2118
2119         co.xy *= tex_size;
2120         /* texel center */
2121         vec2 tc = floor(co.xy - 0.5) + 0.5;
2122         vec2 w0, w1, w2, w3;
2123         cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
2124
2125 #if 1 /* Optimized version using 4 filtered tap. */
2126         vec2 s0 = w0 + w1;
2127         vec2 s1 = w2 + w3;
2128
2129         vec2 f0 = w1 / (w0 + w1);
2130         vec2 f1 = w3 / (w2 + w3);
2131
2132         vec4 final_co;
2133         final_co.xy = tc - 1.0 + f0;
2134         final_co.zw = tc + 1.0 + f1;
2135
2136         if (do_extend == 1.0) {
2137                 final_co = clamp(final_co, vec4(0.5), tex_size.xyxy - 0.5);
2138         }
2139         final_co /= tex_size.xyxy;
2140
2141         color  = textureLod(ima, final_co.xy, 0.0) * s0.x * s0.y;
2142         color += textureLod(ima, final_co.zy, 0.0) * s1.x * s0.y;
2143         color += textureLod(ima, final_co.xw, 0.0) * s0.x * s1.y;
2144         color += textureLod(ima, final_co.zw, 0.0) * s1.x * s1.y;
2145
2146 #else /* Reference bruteforce 16 tap. */
2147         color  = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y;
2148         color += texelFetch(ima, ivec2(tc + vec2( 0.0, -1.0)), 0) * w1.x * w0.y;
2149         color += texelFetch(ima, ivec2(tc + vec2( 1.0, -1.0)), 0) * w2.x * w0.y;
2150         color += texelFetch(ima, ivec2(tc + vec2( 2.0, -1.0)), 0) * w3.x * w0.y;
2151
2152         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y;
2153         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 0.0)), 0) * w1.x * w1.y;
2154         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 0.0)), 0) * w2.x * w1.y;
2155         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 0.0)), 0) * w3.x * w1.y;
2156
2157         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y;
2158         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 1.0)), 0) * w1.x * w2.y;
2159         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 1.0)), 0) * w2.x * w2.y;
2160         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 1.0)), 0) * w3.x * w2.y;
2161
2162         color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y;
2163         color += texelFetch(ima, ivec2(tc + vec2( 0.0, 2.0)), 0) * w1.x * w3.y;
2164         color += texelFetch(ima, ivec2(tc + vec2( 1.0, 2.0)), 0) * w2.x * w3.y;
2165         color += texelFetch(ima, ivec2(tc + vec2( 2.0, 2.0)), 0) * w3.x * w3.y;
2166 #endif
2167
2168         alpha = color.a;
2169 }
2170
2171 void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2172 {
2173         node_tex_image_cubic_ex(co, ima, 0.0, color, alpha);
2174 }
2175
2176 void node_tex_image_cubic_extend(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2177 {
2178         node_tex_image_cubic_ex(co, ima, 1.0, color, alpha);
2179 }
2180
2181 void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2182 {
2183         /* use cubic for now */
2184         node_tex_image_cubic_ex(co, ima, 0.0, color, alpha);
2185 }
2186
2187 void tex_box_sample_linear(vec3 texco,
2188                     vec3 N,
2189                     sampler2D ima,
2190                     out vec4 color1,
2191                     out vec4 color2,
2192                     out vec4 color3)
2193 {
2194         /* X projection */
2195         vec2 uv = texco.yz;
2196         if (N.x < 0.0) {
2197                 uv.x = 1.0 - uv.x;
2198         }
2199         color1 = texture(ima, uv);
2200         /* Y projection */
2201         uv = texco.xz;
2202         if (N.y > 0.0) {
2203                 uv.x = 1.0 - uv.x;
2204         }
2205         color2 = texture(ima, uv);
2206         /* Z projection */
2207         uv = texco.yx;
2208         if (N.z > 0.0) {
2209                 uv.x = 1.0 - uv.x;
2210         }
2211         color3 = texture(ima, uv);
2212 }
2213
2214 void tex_box_sample_nearest(vec3 texco,
2215                     vec3 N,
2216                     sampler2D ima,
2217                     out vec4 color1,
2218                     out vec4 color2,
2219                     out vec4 color3)
2220 {
2221         /* X projection */
2222         vec2 uv = texco.yz;
2223         if (N.x < 0.0) {
2224                 uv.x = 1.0 - uv.x;
2225         }
2226         ivec2 pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2227         color1 = texelFetch(ima, pix, 0);
2228         /* Y projection */
2229         uv = texco.xz;
2230         if (N.y > 0.0) {
2231                 uv.x = 1.0 - uv.x;
2232         }
2233         pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2234         color2 = texelFetch(ima, pix, 0);
2235         /* Z projection */
2236         uv = texco.yx;
2237         if (N.z > 0.0) {
2238                 uv.x = 1.0 - uv.x;
2239         }
2240         pix = ivec2(uv.xy * textureSize(ima, 0).xy);
2241         color3 = texelFetch(ima, pix, 0);
2242 }
2243
2244 void tex_box_sample_cubic(vec3 texco,
2245                     vec3 N,
2246                     sampler2D ima,
2247                     out vec4 color1,
2248                     out vec4 color2,
2249                     out vec4 color3)
2250 {
2251         float alpha;
2252         /* X projection */
2253         vec2 uv = texco.yz;
2254         if (N.x < 0.0) {
2255                 uv.x = 1.0 - uv.x;
2256         }
2257         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color1, alpha);
2258         /* Y projection */
2259         uv = texco.xz;
2260         if (N.y > 0.0) {
2261                 uv.x = 1.0 - uv.x;
2262         }
2263         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color2, alpha);
2264         /* Z projection */
2265         uv = texco.yx;
2266         if (N.z > 0.0) {
2267                 uv.x = 1.0 - uv.x;
2268         }
2269         node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color3, alpha);
2270 }
2271
2272 void tex_box_sample_smart(vec3 texco,
2273                     vec3 N,
2274                     sampler2D ima,
2275                     out vec4 color1,
2276                     out vec4 color2,
2277                     out vec4 color3)
2278 {
2279         tex_box_sample_cubic(texco, N, ima, color1, color2, color3);
2280 }
2281
2282 void node_tex_image_box(vec3 texco,
2283                         vec3 N,
2284                         vec4 color1,
2285                         vec4 color2,
2286                         vec4 color3,
2287                         sampler2D ima,
2288                         float blend,
2289                         out vec4 color,
2290                         out float alpha)
2291 {
2292         /* project from direction vector to barycentric coordinates in triangles */
2293         N = abs(N);
2294         N /= dot(N, vec3(1.0));
2295
2296         /* basic idea is to think of this as a triangle, each corner representing
2297          * one of the 3 faces of the cube. in the corners we have single textures,
2298          * in between we blend between two textures, and in the middle we a blend
2299          * between three textures.
2300          *
2301          * the Nxyz values are the barycentric coordinates in an equilateral
2302          * triangle, which in case of blending, in the middle has a smaller
2303          * equilateral triangle where 3 textures blend. this divides things into
2304          * 7 zones, with an if () test for each zone
2305          * EDIT: Now there is only 4 if's. */
2306
2307         float limit = 0.5 + 0.5 * blend;
2308
2309         vec3 weight;
2310         weight = N.xyz / (N.xyx + N.yzz);
2311         weight = clamp((weight - 0.5 * (1.0 - blend)) / max(1e-8, blend), 0.0, 1.0);
2312
2313         /* test for mixes between two textures */
2314         if (N.z < (1.0 - limit) * (N.y + N.x)) {
2315                 weight.z = 0.0;
2316                 weight.y = 1.0 - weight.x;
2317         }
2318         else if (N.x < (1.0 - limit) * (N.y + N.z)) {
2319                 weight.x = 0.0;
2320                 weight.z = 1.0 - weight.y;
2321         }
2322         else if (N.y < (1.0 - limit) * (N.x + N.z)) {
2323                 weight.y = 0.0;
2324                 weight.x = 1.0 - weight.z;
2325         }
2326         else {
2327                 /* last case, we have a mix between three */
2328                 weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, blend);
2329         }
2330
2331         color = weight.x * color1 + weight.y * color2 + weight.z * color3;
2332         alpha = color.a;
2333 }
2334
2335 void tex_clip_linear(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2336 {
2337         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2338         vec2 minco = min(co.xy, 1.0 - co.xy);
2339         minco = clamp(minco * tex_size + 0.5, 0.0, 1.0);
2340         float fac = minco.x * minco.y;
2341
2342         color = mix(vec4(0.0), icolor, fac);
2343         alpha = color.a;
2344 }
2345
2346 void tex_clip_nearest(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2347 {
2348         vec4 minco = vec4(co.xy, 1.0 - co.xy);
2349         color = (any(lessThan(minco, vec4(0.0)))) ? vec4(0.0) : icolor;
2350         alpha = color.a;
2351 }
2352
2353 void tex_clip_cubic(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2354 {
2355         vec2 tex_size = vec2(textureSize(ima, 0).xy);
2356
2357         co.xy *= tex_size;
2358         /* texel center */
2359         vec2 tc = floor(co.xy - 0.5) + 0.5;
2360         vec2 w0, w1, w2, w3;
2361         cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
2362
2363         /* TODO Optimize this part. I'm sure there is a smarter way to do that.
2364          * Could do that when sampling? */
2365 #define CLIP_CUBIC_SAMPLE(samp, size) (float(all(greaterThan(samp, vec2(-0.5)))) * float(all(lessThan(ivec2(samp), itex_size))))
2366         ivec2 itex_size = textureSize(ima, 0).xy;
2367         float fac;
2368         fac  = CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, -1.0), itex_size) * w0.x * w0.y;
2369         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0, -1.0), itex_size) * w1.x * w0.y;
2370         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0, -1.0), itex_size) * w2.x * w0.y;
2371         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0, -1.0), itex_size) * w3.x * w0.y;
2372
2373         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  0.0), itex_size) * w0.x * w1.y;
2374         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  0.0), itex_size) * w1.x * w1.y;
2375         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  0.0), itex_size) * w2.x * w1.y;
2376         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  0.0), itex_size) * w3.x * w1.y;
2377
2378         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  1.0), itex_size) * w0.x * w2.y;
2379         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  1.0), itex_size) * w1.x * w2.y;
2380         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  1.0), itex_size) * w2.x * w2.y;
2381         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  1.0), itex_size) * w3.x * w2.y;
2382
2383         fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0,  2.0), itex_size) * w0.x * w3.y;
2384         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 0.0,  2.0), itex_size) * w1.x * w3.y;
2385         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 1.0,  2.0), itex_size) * w2.x * w3.y;
2386         fac += CLIP_CUBIC_SAMPLE(tc + vec2( 2.0,  2.0), itex_size) * w3.x * w3.y;
2387 #undef CLIP_CUBIC_SAMPLE
2388
2389         color = mix(vec4(0.0), icolor, fac);
2390         alpha = color.a;
2391 }
2392
2393 void tex_clip_smart(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha)
2394 {
2395         tex_clip_cubic(co, ima, icolor, color, alpha);
2396 }
2397
2398 void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
2399 {
2400         color = vec4(0.0);
2401         alpha = 0.0;
2402 }
2403
2404 void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec4 color, out float fac)
2405 {
2406         vec3 p = co * scale;
2407         float x = sin((p.x + p.y + p.z) * 5.0);
2408         float y = cos((-p.x + p.y - p.z) * 5.0);
2409         float z = -cos((-p.x - p.y + p.z) * 5.0);
2410
2411         if (depth > 0) {
2412                 x *= distortion;
2413                 y *= distortion;
2414                 z *= distortion;
2415                 y = -cos(x - y + z);
2416                 y *= distortion;
2417                 if (depth > 1) {
2418                         x = cos(x - y - z);
2419                         x *= distortion;
2420                         if (depth > 2) {
2421                                 z = sin(-x - y - z);
2422                                 z *= distortion;
2423                                 if (depth > 3) {
2424                                         x = -cos(-x + y - z);
2425                                         x *= distortion;
2426                                         if (depth > 4) {
2427                                                 y = -sin(-x + y + z);
2428                                                 y *= distortion;
2429                                                 if (depth > 5) {
2430                                                         y = -cos(-x + y + z);
2431                                                         y *= distortion;
2432                                                         if (depth > 6) {
2433                                                                 x = cos(x + y + z);
2434                                                                 x *= distortion;
2435                                                                 if (depth > 7) {
2436                                                                         z = sin(x + y - z);
2437                                                                         z *= distortion;
2438                                                                         if (depth > 8) {
2439                                                                                 x = -cos(-x - y + z);
2440                                                                                 x *= distortion;
2441                                                                                 if (depth > 9) {
2442                                                                                         y = -sin(x - y + z);
2443                                                                                         y *= distortion;
2444                                                                                 }
2445                                                                         }
2446                                                                 }
2447                                                         }
2448                                                 }
2449                                         }
2450                                 }
2451                         }
2452                 }
2453         }
2454         if (distortion != 0.0) {
2455                 distortion *= 2.0;
2456                 x /= distortion;
2457                 y /= distortion;
2458                 z /= distortion;
2459         }
2460
2461         color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
2462         fac = (color.x + color.y + color.z) / 3.0;
2463 }
2464
2465 float noise_fade(float t)
2466 {
2467         return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
2468 }
2469
2470 float noise_scale3(float result)
2471 {
2472         return 0.9820 * result;
2473 }
2474
2475 float noise_nerp(float t, float a, float b)
2476 {
2477         return (1.0 - t) * a + t * b;
2478 }
2479
2480 float noise_grad(uint hash, float x, float y, float z)
2481 {
2482         uint h = hash & 15u;
2483         float u = h < 8u ? x : y;
2484         float vt = ((h == 12u) || (h == 14u)) ? x : z;
2485         float v = h < 4u ? y : vt;
2486         return (((h & 1u) != 0u) ? -u : u) + (((h & 2u) != 0u) ? -v : v);
2487 }
2488
2489 float noise_perlin(float x, float y, float z)
2490 {
2491         int X; float fx = floorfrac(x, X);
2492         int Y; float fy = floorfrac(y, Y);
2493         int Z; float fz = floorfrac(z, Z);
2494
2495         float u = noise_fade(fx);
2496         float v = noise_fade(fy);
2497         float w = noise_fade(fz);
2498
2499         float noise_u[2], noise_v[2];
2500
2501         noise_u[0] = noise_nerp(u,
2502                 noise_grad(hash(X, Y, Z), fx, fy, fz),
2503                 noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz));
2504
2505         noise_u[1] = noise_nerp(u,
2506                 noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
2507                 noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz));
2508
2509         noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]);
2510
2511         noise_u[0] = noise_nerp(u,
2512                 noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
2513                 noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0));
2514
2515         noise_u[1] = noise_nerp(u,
2516                 noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
2517                 noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0));
2518
2519         noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]);
2520
2521         return noise_scale3(noise_nerp(w, noise_v[0], noise_v[1]));
2522 }
2523
2524 float noise(vec3 p)
2525 {
2526         return 0.5 * noise_perlin(p.x, p.y, p.z) + 0.5;
2527 }
2528
2529 float snoise(vec3 p)
2530 {
2531         return noise_perlin(p.x, p.y, p.z);
2532 }
2533
2534 float noise_turbulence(vec3 p, float octaves, int hard)
2535 {
2536         float fscale = 1.0;
2537         float amp = 1.0;
2538         float sum = 0.0;
2539         octaves = clamp(octaves, 0.0, 16.0);
2540         int n = int(octaves);
2541         for (int i = 0; i <= n; i++) {
2542                 float t = noise(fscale * p);
2543                 if (hard != 0) {
2544                         t = abs(2.0 * t - 1.0);
2545                 }
2546                 sum += t * amp;
2547                 amp *= 0.5;
2548                 fscale *= 2.0;
2549         }
2550         float rmd = octaves - floor(octaves);
2551         if (rmd != 0.0) {
2552                 float t = noise(fscale * p);
2553                 if (hard != 0) {
2554                         t = abs(2.0 * t - 1.0);
2555                 }
2556                 float sum2 = sum + t * amp;
2557                 sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
2558                 sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
2559                 return (1.0 - rmd) * sum + rmd * sum2;
2560         }
2561         else {
2562                 sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
2563                 return sum;
2564         }
2565 }
2566
2567 void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
2568 {
2569         vec3 p = co * scale;
2570         int hard = 0;
2571         if (distortion != 0.0) {
2572                 vec3 r, offset = vec3(13.5, 13.5, 13.5);
2573                 r.x = noise(p + offset) * distortion;
2574                 r.y = noise(p) * distortion;
2575                 r.z = noise(p - offset) * distortion;
2576                 p += r;
2577         }
2578
2579         fac = noise_turbulence(p, detail, hard);
2580         color = vec4(fac,
2581                      noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
2582                      noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
2583                      1);
2584 }
2585
2586 /* Musgrave fBm
2587  *
2588  * H: fractal increment parameter
2589  * lacunarity: gap between successive frequencies
2590  * octaves: number of frequencies in the fBm
2591  *
2592  * from "Texturing and Modelling: A procedural approach"
2593  */
2594
2595 float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
2596 {
2597         float rmd;
2598         float value = 0.0;
2599         float pwr = 1.0;
2600         float pwHL = pow(lacunarity, -H);
2601
2602         for (int i = 0; i < int(octaves); i++) {
2603                 value += snoise(p) * pwr;
2604                 pwr *= pwHL;
2605                 p *= lacunarity;
2606         }
2607
2608         rmd = octaves - floor(octaves);
2609         if (rmd != 0.0)
2610                 value += rmd * snoise(p) * pwr;
2611
2612         return value;
2613 }
2614
2615 /* Musgrave Multifractal
2616  *
2617  * H: highest fractal dimension
2618  * lacunarity: gap between successive frequencies
2619  * octaves: number of frequencies in the fBm
2620  */
2621
2622 float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octaves)
2623 {
2624         float rmd;
2625         float value = 1.0;
2626         float pwr = 1.0;
2627         float pwHL = pow(lacunarity, -H);
2628
2629         for (int i = 0; i < int(octaves); i++) {
2630                 value *= (pwr * snoise(p) + 1.0);
2631                 pwr *= pwHL;
2632                 p *= lacunarity;
2633         }
2634
2635         rmd = octaves - floor(octaves);
2636         if (rmd != 0.0)
2637                 value *= (rmd * pwr * snoise(p) + 1.0); /* correct? */
2638
2639         return value;
2640 }
2641
2642 /* Musgrave Heterogeneous Terrain
2643  *
2644  * H: fractal dimension of the roughest area
2645  * lacunarity: gap between successive frequencies
2646  * octaves: number of frequencies in the fBm
2647  * offset: raises the terrain from `sea level'
2648  */
2649
2650 float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float octaves, float offset)
2651 {
2652         float value, increment, rmd;
2653         float pwHL = pow(lacunarity, -H);
2654         float pwr = pwHL;
2655
2656         /* first unscaled octave of function; later octaves are scaled */
2657         value = offset + snoise(p);
2658         p *= lacunarity;
2659
2660         for (int i = 1; i < int(octaves); i++) {
2661                 increment = (snoise(p) + offset) * pwr * value;
2662                 value += increment;
2663                 pwr *= pwHL;
2664                 p *= lacunarity;
2665         }
2666
2667         rmd = octaves - floor(octaves);
2668         if (rmd != 0.0) {
2669                 increment = (snoise(p) + offset) * pwr * value;
2670                 value += rmd * increment;
2671         }
2672
2673         return value;
2674 }
2675
2676 /* Hybrid Additive/Multiplicative Multifractal Terrain
2677  *
2678  * H: fractal dimension of the roughest area
2679  * lacunarity: gap between successive frequencies
2680  * octaves: number of frequencies in the fBm
2681  * offset: raises the terrain from `sea level'
2682  */
2683
2684 float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
2685 {
2686         float result, signal, weight, rmd;
2687         float pwHL = pow(lacunarity, -H);
2688         float pwr = pwHL;
2689
2690         result = snoise(p) + offset;
2691         weight = gain * result;
2692         p *= lacunarity;
2693
2694         for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
2695                 if (weight > 1.0)
2696                         weight = 1.0;
2697
2698                 signal = (snoise(p) + offset) * pwr;
2699                 pwr *= pwHL;
2700                 result += weight * signal;
2701                 weight *= gain * signal;
2702                 p *= lacunarity;
2703         }
2704
2705         rmd = octaves - floor(octaves);
2706         if (rmd != 0.0)
2707                 result += rmd * ((snoise(p) + offset) * pwr);
2708
2709         return result;
2710 }
2711
2712 /* Ridged Multifractal Terrain
2713  *
2714  * H: fractal dimension of the roughest area
2715  * lacunarity: gap between successive frequencies
2716  * octaves: number of frequencies in the fBm
2717  * offset: raises the terrain from `sea level'
2718  */
2719
2720 float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, float octaves, float offset, float gain)
2721 {
2722         float result, signal, weight;
2723         float pwHL = pow(lacunarity, -H);
2724         float pwr = pwHL;
2725
2726         signal = offset - abs(snoise(p));
2727         signal *= signal;
2728         result = signal;
2729         weight = 1.0;
2730
2731         for (int i = 1; i < int(octaves); i++) {
2732                 p *= lacunarity;
2733                 weight = clamp(signal * gain, 0.0, 1.0);
2734                 signal = offset - abs(snoise(p));
2735                 signal *= signal;
2736                 signal *= weight;
2737                 result += signal * pwr;
2738                 pwr *= pwHL;
2739         }
2740
2741         return result;
2742 }
2743
2744 float svm_musgrave(int type,
2745                    float dimension,
2746                    float lacunarity,
2747                    float octaves,
2748                    float offset,
2749                    float intensity,
2750                    float gain,
2751                    vec3 p)
2752 {
2753         if (type == 0 /* NODE_MUSGRAVE_MULTIFRACTAL */)
2754                 return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
2755         else if (type == 1 /* NODE_MUSGRAVE_FBM */)
2756                 return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
2757         else if (type == 2 /* NODE_MUSGRAVE_HYBRID_MULTIFRACTAL */)
2758                 return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
2759         else if (type == 3 /* NODE_MUSGRAVE_RIDGED_MULTIFRACTAL */)
2760                 return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
2761         else if (type == 4 /* NODE_MUSGRAVE_HETERO_TERRAIN */)
2762                 return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
2763         return 0.0;
2764 }
2765
2766 void node_tex_musgrave(vec3 co,
2767                        float scale,
2768                        float detail,
2769                        float dimension,
2770                        float lacunarity,
2771                        float offset,
2772                        float gain,
2773                        float type,
2774                        out vec4 color,
2775                        out float fac)
2776 {
2777         fac = svm_musgrave(int(type),
2778                            dimension,
2779                            lacunarity,
2780                            detail,
2781                            offset,
2782                            1.0,
2783                            gain,
2784                            co * scale);
2785
2786         color = vec4(fac, fac, fac, 1.0);
2787 }
2788
2789 void node_tex_sky(vec3 co, out vec4 color)
2790 {
2791         color = vec4(1.0);
2792 }
2793
2794 void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, float metric, float feature, out vec4 color, out float fac)
2795 {
2796         vec3 p = co * scale;
2797         int xx, yy, zz, xi, yi, zi;
2798         vec4 da = vec4(1e10);
2799         vec3 pa[4] = vec3[4](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
2800
2801         xi = floor_to_int(p[0]);
2802         yi = floor_to_int(p[1]);
2803         zi = floor_to_int(p[2]);
2804
2805         for (xx = xi - 1; xx <= xi + 1; xx++) {
2806                 for (yy = yi - 1; yy <= yi + 1; yy++) {
2807                         for (zz = zi - 1; zz <= zi + 1; zz++) {
2808                                 vec3 ip = vec3(xx, yy, zz);
2809                                 vec3 vp = cellnoise_color(ip);
2810                                 vec3 pd = p - (vp + ip);
2811
2812                                 float d = 0.0;
2813                                 if (metric == 0.0) { /* SHD_VORONOI_DISTANCE 0 */
2814                                         d = dot(pd, pd);
2815                                 }
2816                                 else if (metric == 1.0) { /* SHD_VORONOI_MANHATTAN 1 */
2817                                         d = abs(pd[0]) + abs(pd[1]) + abs(pd[2]);
2818                                 }
2819                                 else if (metric == 2.0) { /* SHD_VORONOI_CHEBYCHEV 2 */
2820                                         d = max(abs(pd[0]), max(abs(pd[1]), abs(pd[2])));
2821                                 }
2822                                 else if (metric == 3.0) { /* SHD_VORONOI_MINKOWSKI 3 */
2823                                         d = pow(pow(abs(pd[0]), exponent) + pow(abs(pd[1]), exponent) + pow(abs(pd[2]), exponent), 1.0/exponent);
2824                                 }
2825
2826                                 vp += vec3(xx, yy, zz);
2827                                 if (d < da[0]) {
2828                                         da.yzw = da.xyz;
2829                                         da[0] = d;
2830
2831                                         pa[3] = pa[2];
2832                                         pa[2] = pa[1];
2833                                         pa[1] = pa[0];
2834                                         pa[0] = vp;
2835                                 }
2836                                 else if (d < da[1]) {
2837                                         da.zw = da.yz;
2838                                         da[1] = d;
2839
2840                                         pa[3] = pa[2];
2841                                         pa[2] = pa[1];
2842                                         pa[1] = vp;
2843                                 }
2844                                 else if (d < da[2]) {
2845                                         da[3] = da[2];
2846                                         da[2] = d;
2847
2848                                         pa[3] = pa[2];
2849                                         pa[2] = vp;
2850                                 }
2851                                 else if (d < da[3]) {
2852                                         da[3] = d;
2853                                         pa[3] = vp;
2854                                 }
2855                         }
2856                 }
2857         }
2858
2859         if (coloring == 0.0) {
2860                 /* Intensity output */
2861                 if (feature == 0.0) { /* F1 */
2862                         fac = abs(da[0]);
2863                 }
2864                 else if (feature == 1.0) { /* F2 */
2865                         fac = abs(da[1]);
2866                 }
2867                 else if (feature == 2.0) { /* F3 */
2868                         fac = abs(da[2]);
2869                 }
2870                 else if (feature == 3.0) { /* F4 */
2871                         fac = abs(da[3]);
2872                 }
2873                 else if (feature == 4.0) { /* F2F1 */
2874                         fac = abs(da[1] - da[0]);
2875                 }
2876                 color = vec4(fac, fac, fac, 1.0);
2877         }
2878         else {
2879                 /* Color output */
2880                 vec3 col = vec3(fac, fac, fac);
2881                 if (feature == 0.0) { /* F1 */
2882                         col = pa[0];
2883                 }
2884                 else if (feature == 1.0) { /* F2 */
2885                         col = pa[1];
2886                 }
2887                 else if (feature == 2.0) { /* F3 */
2888                         col = pa[2];
2889                 }
2890                 else if (feature == 3.0) { /* F4 */
2891                         col = pa[3];
2892                 }
2893                 else if (feature == 4.0) { /* F2F1 */
2894                         col = abs(pa[1] - pa[0]);
2895                 }
2896
2897                 color = vec4(cellnoise_color(col), 1.0);
2898                 fac = (color.x + color.y + color.z) * (1.0 / 3.0);
2899         }
2900 }
2901
2902 float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
2903 {
2904         float n;
2905
2906         if (wave_type == 0) /* type bands */
2907                 n = (p.x + p.y + p.z) * 10.0;
2908         else /* type rings */
2909                 n = length(p) * 20.0;
2910
2911         if (distortion != 0.0)
2912                 n += distortion * noise_turbulence(p * detail_scale, detail, 0);
2913
2914         if (wave_profile == 0) { /* profile sin */
2915                 return 0.5 + 0.5 * sin(n);
2916         }
2917         else { /* profile saw */
2918                 n /= 2.0 * M_PI;
2919                 n -= int(n);
2920                 return (n < 0.0) ? n + 1.0 : n;
2921         }
2922 }
2923
2924 void node_tex_wave(
2925         vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
2926         out vec4 color, out float fac)
2927 {
2928         float f;
2929         f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
2930
2931         color = vec4(f, f, f, 1.0);
2932         fac = f;
2933 }
2934
2935 /* light path */
2936
2937 void node_light_path(
2938         out float is_camera_ray,
2939         out float is_shadow_ray,
2940         out float is_diffuse_ray,
2941         out float is_glossy_ray,
2942         out float is_singular_ray,
2943         out float is_reflection_ray,
2944         out float is_transmission_ray,
2945         out float ray_length,
2946         out float ray_depth,
2947         out float diffuse_depth,
2948         out float glossy_depth,
2949         out float transparent_depth,
2950         out float transmission_depth)
2951 {
2952         /* Supported. */
2953         is_camera_ray = (rayType == EEVEE_RAY_CAMERA) ? 1.0 : 0.0;
2954         is_shadow_ray = (rayType == EEVEE_RAY_SHADOW) ? 1.0 : 0.0;
2955         is_diffuse_ray = (rayType == EEVEE_RAY_DIFFUSE) ? 1.0 : 0.0;
2956         is_glossy_ray = (rayType == EEVEE_RAY_GLOSSY) ? 1.0 : 0.0;
2957         /* Kind of supported. */
2958         is_singular_ray = is_glossy_ray;
2959         is_reflection_ray = is_glossy_ray;
2960         is_transmission_ray = is_glossy_ray;
2961         ray_depth = rayDepth;
2962         diffuse_depth = (is_diffuse_ray == 1.0) ? rayDepth : 0.0;
2963         glossy_depth = (is_glossy_ray == 1.0) ? rayDepth : 0.0;
2964         transmission_depth = (is_transmission_ray == 1.0) ? glossy_depth : 0.0;
2965         /* Not supported. */
2966         ray_length = 1.0;
2967         transparent_depth = 0.0;
2968 }
2969
2970 void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
2971 {
2972         quadratic = strength;
2973         linear = strength;
2974         constant = strength;
2975 }
2976
2977 void node_object_info(mat4 obmat, vec4 info, out vec3 location, out float object_index, out float material_index, out float random)
2978 {
2979         location = obmat[3].xyz;
2980         object_index = info.x;
2981         material_index = info.y;
2982         random = info.z;
2983 }
2984
2985 void node_normal_map(vec4 info, vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
2986 {
2987         if (all(equal(tangent, vec4(0.0, 0.0, 0.0, 1.0)))) {
2988                 outnormal = normal;
2989                 return;
2990         }
2991         tangent *= (gl_FrontFacing ? 1.0 : -1.0);
2992         vec3 B = tangent.w * cross(normal, tangent.xyz) * info.w;
2993
2994         outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
2995         outnormal = normalize(outnormal);
2996 }
2997
2998 void node_bump(float strength, float dist, float height, vec3 N, vec3 surf_pos, float invert, out vec3 result)
2999 {
3000         N = mat3(ViewMatrix) * normalize(N);
3001         dist *= invert;
3002
3003         vec3 dPdx = dFdx(surf_pos);
3004         vec3 dPdy = dFdy(surf_pos);
3005
3006         /* Get surface tangents from normal. */
3007         vec3 Rx = cross(dPdy, N);
3008         vec3 Ry = cross(N, dPdx);
3009
3010         /* Compute surface gradient and determinant. */
3011         float det = dot(dPdx, Rx);
3012
3013         float dHdx = dFdx(height);
3014         float dHdy = dFdy(height);
3015         vec3 surfgrad = dHdx * Rx + dHdy * Ry;
3016
3017         strength = max(strength, 0.0);
3018
3019         result = normalize(abs(det) * N - dist * sign(det) * surfgrad);
3020         result = normalize(mix(N, result, strength));
3021
3022         result = mat3(ViewMatrixInverse) * result;
3023 }
3024
3025 void node_bevel(float radius, vec3 N, out vec3 result)
3026 {
3027         result = N;
3028 }
3029
3030 void node_hair_info(out float is_strand, out float intercept, out float thickness, out vec3 tangent, out float random)
3031 {
3032 #ifdef HAIR_SHADER
3033         is_strand = 1.0;
3034         intercept = hairTime;
3035         thickness = hairThickness;
3036         tangent = normalize(hairTangent);
3037         random = wang_hash_noise(uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */
3038 #else
3039         is_strand = 0.0;
3040         intercept = 0.0;
3041         thickness = 0.0;
3042         tangent = vec3(1.0);
3043         random = 0.0;
3044 #endif
3045 }
3046
3047 void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result)
3048 {
3049         N = (vec4(N, 0.0) * obmat).xyz;
3050         result = (height - midlevel) * scale * normalize(N);
3051         result = (obmat * vec4(result, 0.0)).xyz;
3052 }
3053
3054 void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result)
3055 {
3056         result = (height - midlevel) * scale * normalize(N);
3057 }
3058
3059 void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result)
3060 {
3061         vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz);
3062         vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz);
3063         vec3 B_object = tangent.w * normalize(cross(N_object, T_object));
3064
3065         vec3 offset = (vector.xyz - vec3(midlevel)) * scale;
3066         result = offset.x * T_object + offset.y * N_object + offset.z * B_object;
3067         result = (obmat * vec4(result, 0.0)).xyz;
3068 }
3069
3070 void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result)
3071 {
3072         result = (vector.xyz - vec3(midlevel)) * scale;
3073         result = (obmat * vec4(result, 0.0)).xyz;
3074 }
3075
3076 void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result)
3077 {
3078         result = (vector.xyz - vec3(midlevel)) * scale;
3079 }
3080
3081 /* output */
3082
3083 void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result)
3084 {
3085 #ifdef VOLUMETRICS
3086         result = volume;
3087 #else
3088         result = surface;
3089 #endif
3090 }
3091
3092 uniform float backgroundAlpha;
3093
3094 void node_output_world(Closure surface, Closure volume, out Closure result)
3095 {
3096 #ifndef VOLUMETRICS
3097         result.radiance = surface.radiance * backgroundAlpha;
3098         result.opacity = backgroundAlpha;
3099 #else
3100         result = volume;
3101 #endif /* VOLUMETRICS */
3102 }
3103
3104 #ifndef VOLUMETRICS
3105 /* TODO : clean this ifdef mess */
3106 /* EEVEE output */
3107 void world_normals_get(out vec3 N)
3108 {
3109 #ifdef HAIR_SHADER
3110         vec3 B = normalize(cross(worldNormal, hairTangent));
3111         float cos_theta;
3112         if (hairThicknessRes == 1) {
3113                 vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
3114                 /* Random cosine normal distribution on the hair surface. */
3115                 cos_theta = rand.x * 2.0 - 1.0;
3116         }
3117         else {
3118                 /* Shade as a cylinder. */
3119                 cos_theta = hairThickTime / hairThickness;
3120         }
3121         float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));
3122         N = normalize(worldNormal * sin_theta + B * cos_theta);
3123 #else
3124         N = gl_FrontFacing ? worldNormal : -worldNormal;
3125 #endif
3126 }
3127
3128 void node_eevee_specular(
3129         vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
3130         float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
3131         float occlusion, float ssr_id, out Closure result)
3132 {
3133         vec3 out_diff, out_spec, ssr_spec;
3134         eevee_closure_default(normal, diffuse.rgb, specular.rgb, int(ssr_id), roughness, occlusion,
3135                               out_diff, out_spec, ssr_spec);
3136
3137         vec3 vN = normalize(mat3(ViewMatrix) * normal);
3138         result = CLOSURE_DEFAULT;
3139         result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
3140         result.opacity = 1.0 - transp;
3141         result.ssr_data = vec4(ssr_spec, roughness);
3142         result.ssr_normal = normal_encode(vN, viewCameraVec);
3143         result.ssr_id = int(ssr_id);
3144 }
3145
3146 void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha)
3147 {
3148         vec4 spec_accum = vec4(0.0);
3149         if (ssrToggle && cl.ssr_id == outputSsrId) {
3150                 vec3 V = cameraVec;
3151                 vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec);
3152                 vec3 N = transform_direction(ViewMatrixInverse, vN);
3153                 float roughness = cl.ssr_data.a;
3154                 float roughnessSquared = max(1e-3, roughness * roughness);
3155                 fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum);
3156         }
3157
3158         outalpha = cl.opacity;
3159         outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0);
3160
3161 #   ifdef USE_SSS
3162 #               ifdef USE_SSS_ALBEDO
3163         outcol.rgb += cl.sss_data.rgb * cl.sss_albedo;
3164 #       else
3165         outcol.rgb += cl.sss_data.rgb;
3166 #               endif
3167 #       endif
3168 }
3169
3170 #endif /* VOLUMETRICS */