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