Merge branch 'master' into blender2.8
[blender.git] / source / blender / gpu / shaders / gpu_shader_material.glsl
1
2 uniform mat4 ModelViewMatrix;
3 #ifndef EEVEE_ENGINE
4 uniform mat4 ProjectionMatrix;
5 uniform mat4 ViewMatrixInverse;
6 uniform mat4 ViewMatrix;
7 #endif
8 uniform mat4 ModelMatrix;
9 uniform mat4 ModelMatrixInverse;
10 uniform mat4 ModelViewMatrixInverse;
11 uniform mat4 ProjectionMatrixInverse;
12 uniform mat3 NormalMatrix;
13 uniform vec4 CameraTexCoFactors;
14
15 /* Old glsl mode compat. */
16
17 #ifndef CLOSURE_DEFAULT
18
19 struct Closure {
20         vec3 radiance;
21         float opacity;
22 };
23
24 #define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0)
25
26 Closure closure_mix(Closure cl1, Closure cl2, float fac)
27 {
28         Closure cl;
29         cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
30         cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
31         return cl;
32 }
33
34 Closure closure_add(Closure cl1, Closure cl2)
35 {
36         Closure cl;
37         cl.radiance = cl1.radiance + cl2.radiance;
38         cl.opacity = cl1.opacity + cl2.opacity;
39         return cl;
40 }
41
42 Closure nodetree_exec(void); /* Prototype */
43
44 #endif /* CLOSURE_DEFAULT */
45
46
47 /* Converters */
48
49 float convert_rgba_to_float(vec4 color)
50 {
51 #ifdef USE_NEW_SHADING
52         return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
53 #else
54         return (color.r + color.g + color.b) * 0.333333;
55 #endif
56 }
57
58 float exp_blender(float f)
59 {
60         return pow(2.71828182846, f);
61 }
62
63 float compatible_pow(float x, float y)
64 {
65         if (y == 0.0) /* x^0 -> 1, including 0^0 */
66                 return 1.0;
67
68         /* glsl pow doesn't accept negative x */
69         if (x < 0.0) {
70                 if (mod(-y, 2.0) == 0.0)
71                         return pow(-x, y);
72                 else
73                         return -pow(-x, y);
74         }
75         else if (x == 0.0)
76                 return 0.0;
77
78         return pow(x, y);
79 }
80
81 void rgb_to_hsv(vec4 rgb, out vec4 outcol)
82 {
83         float cmax, cmin, h, s, v, cdelta;
84         vec3 c;
85
86         cmax = max(rgb[0], max(rgb[1], rgb[2]));
87         cmin = min(rgb[0], min(rgb[1], rgb[2]));
88         cdelta = cmax - cmin;
89
90         v = cmax;
91         if (cmax != 0.0)
92                 s = cdelta / cmax;
93         else {
94                 s = 0.0;
95                 h = 0.0;
96         }
97
98         if (s == 0.0) {
99                 h = 0.0;
100         }
101         else {
102                 c = (vec3(cmax) - rgb.xyz) / cdelta;
103
104                 if (rgb.x == cmax) h = c[2] - c[1];
105                 else if (rgb.y == cmax) h = 2.0 + c[0] -  c[2];
106                 else h = 4.0 + c[1] - c[0];
107
108                 h /= 6.0;
109
110                 if (h < 0.0)
111                         h += 1.0;
112         }
113
114         outcol = vec4(h, s, v, rgb.w);
115 }
116
117 void hsv_to_rgb(vec4 hsv, out vec4 outcol)
118 {
119         float i, f, p, q, t, h, s, v;
120         vec3 rgb;
121
122         h = hsv[0];
123         s = hsv[1];
124         v = hsv[2];
125
126         if (s == 0.0) {
127                 rgb = vec3(v, v, v);
128         }
129         else {
130                 if (h == 1.0)
131                         h = 0.0;
132
133                 h *= 6.0;
134                 i = floor(h);
135                 f = h - i;
136                 rgb = vec3(f, f, f);
137                 p = v * (1.0 - s);
138                 q = v * (1.0 - (s * f));
139                 t = v * (1.0 - (s * (1.0 - f)));
140
141                 if (i == 0.0) rgb = vec3(v, t, p);
142                 else if (i == 1.0) rgb = vec3(q, v, p);
143                 else if (i == 2.0) rgb = vec3(p, v, t);
144                 else if (i == 3.0) rgb = vec3(p, q, v);
145                 else if (i == 4.0) rgb = vec3(t, p, v);
146                 else rgb = vec3(v, p, q);
147         }
148
149         outcol = vec4(rgb, hsv.w);
150 }
151
152 float srgb_to_linearrgb(float c)
153 {
154         if (c < 0.04045)
155                 return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
156         else
157                 return pow((c + 0.055) * (1.0 / 1.055), 2.4);
158 }
159
160 float linearrgb_to_srgb(float c)
161 {
162         if (c < 0.0031308)
163                 return (c < 0.0) ? 0.0 : c * 12.92;
164         else
165                 return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
166 }
167
168 void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
169 {
170         col_to.r = srgb_to_linearrgb(col_from.r);
171         col_to.g = srgb_to_linearrgb(col_from.g);
172         col_to.b = srgb_to_linearrgb(col_from.b);
173         col_to.a = col_from.a;
174 }
175
176 void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
177 {
178         col_to.r = linearrgb_to_srgb(col_from.r);
179         col_to.g = linearrgb_to_srgb(col_from.g);
180         col_to.b = linearrgb_to_srgb(col_from.b);
181         col_to.a = col_from.a;
182 }
183
184 void color_to_normal(vec3 color, out vec3 normal)
185 {
186         normal.x =  2.0 * ((color.r) - 0.5);
187         normal.y = -2.0 * ((color.g) - 0.5);
188         normal.z =  2.0 * ((color.b) - 0.5);
189 }
190
191 void color_to_normal_new_shading(vec3 color, out vec3 normal)
192 {
193         normal.x =  2.0 * ((color.r) - 0.5);
194         normal.y =  2.0 * ((color.g) - 0.5);
195         normal.z =  2.0 * ((color.b) - 0.5);
196 }
197
198 void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
199 {
200         normal.x =  2.0 * ((color.r) - 0.5);
201         normal.y = -2.0 * ((color.g) - 0.5);
202         normal.z = -2.0 * ((color.b) - 0.5);
203 }
204 #ifndef M_PI
205 #define M_PI 3.14159265358979323846
206 #endif
207 #ifndef M_1_PI
208 #define M_1_PI 0.318309886183790671538
209 #endif
210
211 /*********** SHADER NODES ***************/
212
213 void vcol_attribute(vec4 attvcol, out vec4 vcol)
214 {
215         vcol = vec4(attvcol.xyz, 1.0);
216 }
217
218 void uv_attribute(vec2 attuv, out vec3 uv)
219 {
220         uv = vec3(attuv * 2.0 - vec2(1.0, 1.0), 0.0);
221 }
222
223 void geom(
224         vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 attvcol,
225         out vec3 global, out vec3 local, out vec3 view, out vec3 orco, out vec3 uv,
226         out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback)
227 {
228         local = co;
229         view = (ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
230         global = (viewinvmat * vec4(local, 1.0)).xyz;
231         orco = attorco;
232         uv_attribute(attuv, uv);
233         normal = -normalize(nor);   /* blender render normal is negated */
234         vcol_attribute(attvcol, vcol);
235         srgb_to_linearrgb(vcol, vcol);
236         vcol_alpha = attvcol.a;
237         frontback = (gl_FrontFacing) ? 1.0 : 0.0;
238 }
239
240 void particle_info(
241         vec4 sprops, vec3 loc, vec3 vel, vec3 avel,
242         out float index, out float age, out float life_time, out vec3 location,
243         out float size, out vec3 velocity, out vec3 angular_velocity)
244 {
245         index = sprops.x;
246         age = sprops.y;
247         life_time = sprops.z;
248         size = sprops.w;
249
250         location = loc;
251         velocity = vel;
252         angular_velocity = avel;
253 }
254
255 void vect_normalize(vec3 vin, out vec3 vout)
256 {
257         vout = normalize(vin);
258 }
259
260 void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
261 {
262         vout = (mat * vec4(vin, 0.0)).xyz;
263 }
264
265 void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
266 {
267         vout = (mat * vec4(vin, 1.0)).xyz;
268 }
269
270 void point_texco_remap_square(vec3 vin, out vec3 vout)
271 {
272         vout = vec3(vin - vec3(0.5, 0.5, 0.5)) * 2.0;
273 }
274
275 void point_map_to_sphere(vec3 vin, out vec3 vout)
276 {
277         float len = length(vin);
278         float v, u;
279         if (len > 0.0) {
280                 if (vin.x == 0.0 && vin.y == 0.0)
281                         u = 0.0;
282                 else
283                         u = (1.0 - atan(vin.x, vin.y) / M_PI) / 2.0;
284
285                 v = 1.0 - acos(vin.z / len) / M_PI;
286         }
287         else
288                 v = u = 0.0;
289
290         vout = vec3(u, v, 0.0);
291 }
292
293 void point_map_to_tube(vec3 vin, out vec3 vout)
294 {
295         float u, v;
296         v = (vin.z + 1.0) * 0.5;
297         float len = sqrt(vin.x * vin.x + vin.y * vin[1]);
298         if (len > 0.0)
299                 u = (1.0 - (atan(vin.x / len, vin.y / len) / M_PI)) * 0.5;
300         else
301                 v = u = 0.0;
302
303         vout = vec3(u, v, 0.0);
304 }
305
306 void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
307 {
308         outvec = (mat * vec4(vec, 1.0)).xyz;
309         if (domin == 1.0)
310                 outvec = max(outvec, minvec);
311         if (domax == 1.0)
312                 outvec = min(outvec, maxvec);
313 }
314
315 void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
316 {
317         outdepth = abs(co.z);
318         outdist = length(co);
319         outview = normalize(co);
320 }
321
322 void lamp(
323         vec4 col, float energy, vec3 lv, float dist, vec3 shadow, float visifac,
324         out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
325 {
326         outcol = col * energy;
327         outlv = lv;
328         outdist = dist;
329         outshadow = vec4(shadow, 1.0);
330         outvisifac = visifac;
331 }
332
333 void math_add(float val1, float val2, out float outval)
334 {
335         outval = val1 + val2;
336 }
337
338 void math_subtract(float val1, float val2, out float outval)
339 {
340         outval = val1 - val2;
341 }
342
343 void math_multiply(float val1, float val2, out float outval)
344 {
345         outval = val1 * val2;
346 }
347
348 void math_divide(float val1, float val2, out float outval)
349 {
350         if (val2 == 0.0)
351                 outval = 0.0;
352         else
353                 outval = val1 / val2;
354 }
355
356 void math_sine(float val, out float outval)
357 {
358         outval = sin(val);
359 }
360
361 void math_cosine(float val, out float outval)
362 {
363         outval = cos(val);
364 }
365
366 void math_tangent(float val, out float outval)
367 {
368         outval = tan(val);
369 }
370
371 void math_asin(float val, out float outval)
372 {
373         if (val <= 1.0 && val >= -1.0)
374                 outval = asin(val);
375         else
376                 outval = 0.0;
377 }
378
379 void math_acos(float val, out float outval)
380 {
381         if (val <= 1.0 && val >= -1.0)
382                 outval = acos(val);
383         else
384                 outval = 0.0;
385 }
386
387 void math_atan(float val, out float outval)
388 {
389         outval = atan(val);
390 }
391
392 void math_pow(float val1, float val2, out float outval)
393 {
394         if (val1 >= 0.0) {
395                 outval = compatible_pow(val1, val2);
396         }
397         else {
398                 float val2_mod_1 = mod(abs(val2), 1.0);
399
400                 if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
401                         outval = compatible_pow(val1, floor(val2 + 0.5));
402                 else
403                         outval = 0.0;
404         }
405 }
406
407 void math_log(float val1, float val2, out float outval)
408 {
409         if (val1 > 0.0  && val2 > 0.0)
410                 outval = log2(val1) / log2(val2);
411         else
412                 outval = 0.0;
413 }
414
415 void math_max(float val1, float val2, out float outval)
416 {
417         outval = max(val1, val2);
418 }
419
420 void math_min(float val1, float val2, out float outval)
421 {
422         outval = min(val1, val2);
423 }
424
425 void math_round(float val, out float outval)
426 {
427         outval = floor(val + 0.5);
428 }
429
430 void math_less_than(float val1, float val2, out float outval)
431 {
432         if (val1 < val2)
433                 outval = 1.0;
434         else
435                 outval = 0.0;
436 }
437
438 void math_greater_than(float val1, float val2, out float outval)
439 {
440         if (val1 > val2)
441                 outval = 1.0;
442         else
443                 outval = 0.0;
444 }
445
446 void math_modulo(float val1, float val2, out float outval)
447 {
448         if (val2 == 0.0)
449                 outval = 0.0;
450         else
451                 outval = mod(val1, val2);
452
453         /* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
454          * see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
455         outval = (val1 > 0.0) ? outval : outval - val2;
456 }
457
458 void math_abs(float val1, out float outval)
459 {
460         outval = abs(val1);
461 }
462
463 void squeeze(float val, float width, float center, out float outval)
464 {
465         outval = 1.0 / (1.0 + pow(2.71828183, -((val - center) * width)));
466 }
467
468 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
469 {
470         outvec = v1 + v2;
471         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
472 }
473
474 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
475 {
476         outvec = v1 - v2;
477         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
478 }
479
480 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
481 {
482         outvec = v1 + v2;
483         outval = length(outvec);
484         outvec = normalize(outvec);
485 }
486 void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec)
487 {
488         outvec = strength * v1 + (1 - strength) * v2;
489 }
490
491 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
492 {
493         outvec = vec3(0);
494         outval = dot(v1, v2);
495 }
496
497 void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
498 {
499         outvec = cross(v1, v2);
500         outval = length(outvec);
501         outvec /= outval;
502 }
503
504 void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
505 {
506         outval = length(v);
507         outvec = normalize(v);
508 }
509
510 void vec_math_negate(vec3 v, out vec3 outv)
511 {
512         outv = -v;
513 }
514
515 void invert_z(vec3 v, out vec3 outv)
516 {
517         v.z = -v.z;
518         outv = v;
519 }
520
521 void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
522 {
523         outnor = nor;
524         outdot = -dot(dir, nor);
525 }
526
527 void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
528 {
529         outnor = normalize(nor);
530         outdot = dot(normalize(dir), nor);
531 }
532
533 void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
534 {
535         outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
536         outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
537         outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
538
539         if (fac != 1.0)
540                 outvec = (outvec * fac) + (vec * (1.0 - fac));
541
542 }
543
544 void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
545 {
546         outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
547         outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
548         outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
549
550         if (fac != 1.0)
551                 outcol = (outcol * fac) + (col * (1.0 - fac));
552
553         outcol.a = col.a;
554 }
555
556 void set_value(float val, out float outval)
557 {
558         outval = val;
559 }
560
561 void set_rgb(vec3 col, out vec3 outcol)
562 {
563         outcol = col;
564 }
565
566 void set_rgba(vec4 col, out vec4 outcol)
567 {
568         outcol = col;
569 }
570
571 void set_value_zero(out float outval)
572 {
573         outval = 0.0;
574 }
575
576 void set_value_one(out float outval)
577 {
578         outval = 1.0;
579 }
580
581 void set_rgb_zero(out vec3 outval)
582 {
583         outval = vec3(0.0);
584 }
585
586 void set_rgb_one(out vec3 outval)
587 {
588         outval = vec3(1.0);
589 }
590
591 void set_rgba_zero(out vec4 outval)
592 {
593         outval = vec4(0.0);
594 }
595
596 void set_rgba_one(out vec4 outval)
597 {
598         outval = vec4(1.0);
599 }
600
601 void brightness_contrast(vec4 col, float brightness, float contrast, out vec4 outcol)
602 {
603         float a = 1.0 + contrast;
604         float b = brightness - contrast * 0.5;
605
606         outcol.r = max(a * col.r + b, 0.0);
607         outcol.g = max(a * col.g + b, 0.0);
608         outcol.b = max(a * col.b + b, 0.0);
609         outcol.a = col.a;
610 }
611
612 void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
613 {
614         fac = clamp(fac, 0.0, 1.0);
615         outcol = mix(col1, col2, fac);
616         outcol.a = col1.a;
617 }
618
619 void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
620 {
621         fac = clamp(fac, 0.0, 1.0);
622         outcol = mix(col1, col1 + col2, fac);
623         outcol.a = col1.a;
624 }
625
626 void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
627 {
628         fac = clamp(fac, 0.0, 1.0);
629         outcol = mix(col1, col1 * col2, fac);
630         outcol.a = col1.a;
631 }
632
633 void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
634 {
635         fac = clamp(fac, 0.0, 1.0);
636         float facm = 1.0 - fac;
637
638         outcol = vec4(1.0) - (vec4(facm) + fac * (vec4(1.0) - col2)) * (vec4(1.0) - col1);
639         outcol.a = col1.a;
640 }
641
642 void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
643 {
644         fac = clamp(fac, 0.0, 1.0);
645         float facm = 1.0 - fac;
646
647         outcol = col1;
648
649         if (outcol.r < 0.5)
650                 outcol.r *= facm + 2.0 * fac * col2.r;
651         else
652                 outcol.r = 1.0 - (facm + 2.0 * fac * (1.0 - col2.r)) * (1.0 - outcol.r);
653
654         if (outcol.g < 0.5)
655                 outcol.g *= facm + 2.0 * fac * col2.g;
656         else
657                 outcol.g = 1.0 - (facm + 2.0 * fac * (1.0 - col2.g)) * (1.0 - outcol.g);
658
659         if (outcol.b < 0.5)
660                 outcol.b *= facm + 2.0 * fac * col2.b;
661         else
662                 outcol.b = 1.0 - (facm + 2.0 * fac * (1.0 - col2.b)) * (1.0 - outcol.b);
663 }
664
665 void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
666 {
667         fac = clamp(fac, 0.0, 1.0);
668         outcol = mix(col1, col1 - col2, fac);
669         outcol.a = col1.a;
670 }
671
672 void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
673 {
674         fac = clamp(fac, 0.0, 1.0);
675         float facm = 1.0 - fac;
676
677         outcol = col1;
678
679         if (col2.r != 0.0) outcol.r = facm * outcol.r + fac * outcol.r / col2.r;
680         if (col2.g != 0.0) outcol.g = facm * outcol.g + fac * outcol.g / col2.g;
681         if (col2.b != 0.0) outcol.b = facm * outcol.b + fac * outcol.b / col2.b;
682 }
683
684 void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
685 {
686         fac = clamp(fac, 0.0, 1.0);
687         outcol = mix(col1, abs(col1 - col2), fac);
688         outcol.a = col1.a;
689 }
690
691 void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
692 {
693         fac = clamp(fac, 0.0, 1.0);
694         outcol.rgb = min(col1.rgb, col2.rgb * fac);
695         outcol.a = col1.a;
696 }
697
698 void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
699 {
700         fac = clamp(fac, 0.0, 1.0);
701         outcol.rgb = max(col1.rgb, col2.rgb * fac);
702         outcol.a = col1.a;
703 }
704
705 void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
706 {
707         fac = clamp(fac, 0.0, 1.0);
708         outcol = col1;
709
710         if (outcol.r != 0.0) {
711                 float tmp = 1.0 - fac * col2.r;
712                 if (tmp <= 0.0)
713                         outcol.r = 1.0;
714                 else if ((tmp = outcol.r / tmp) > 1.0)
715                         outcol.r = 1.0;
716                 else
717                         outcol.r = tmp;
718         }
719         if (outcol.g != 0.0) {
720                 float tmp = 1.0 - fac * col2.g;
721                 if (tmp <= 0.0)
722                         outcol.g = 1.0;
723                 else if ((tmp = outcol.g / tmp) > 1.0)
724                         outcol.g = 1.0;
725                 else
726                         outcol.g = tmp;
727         }
728         if (outcol.b != 0.0) {
729                 float tmp = 1.0 - fac * col2.b;
730                 if (tmp <= 0.0)
731                         outcol.b = 1.0;
732                 else if ((tmp = outcol.b / tmp) > 1.0)
733                         outcol.b = 1.0;
734                 else
735                         outcol.b = tmp;
736         }
737 }
738
739 void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
740 {
741         fac = clamp(fac, 0.0, 1.0);
742         float tmp, facm = 1.0 - fac;
743
744         outcol = col1;
745
746         tmp = facm + fac * col2.r;
747         if (tmp <= 0.0)
748                 outcol.r = 0.0;
749         else if ((tmp = (1.0 - (1.0 - outcol.r) / tmp)) < 0.0)
750                 outcol.r = 0.0;
751         else if (tmp > 1.0)
752                 outcol.r = 1.0;
753         else
754                 outcol.r = tmp;
755
756         tmp = facm + fac * col2.g;
757         if (tmp <= 0.0)
758                 outcol.g = 0.0;
759         else if ((tmp = (1.0 - (1.0 - outcol.g) / tmp)) < 0.0)
760                 outcol.g = 0.0;
761         else if (tmp > 1.0)
762                 outcol.g = 1.0;
763         else
764                 outcol.g = tmp;
765
766         tmp = facm + fac * col2.b;
767         if (tmp <= 0.0)
768                 outcol.b = 0.0;
769         else if ((tmp = (1.0 - (1.0 - outcol.b) / tmp)) < 0.0)
770                 outcol.b = 0.0;
771         else if (tmp > 1.0)
772                 outcol.b = 1.0;
773         else
774                 outcol.b = tmp;
775 }
776
777 void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
778 {
779         fac = clamp(fac, 0.0, 1.0);
780         float facm = 1.0 - fac;
781
782         outcol = col1;
783
784         vec4 hsv, hsv2, tmp;
785         rgb_to_hsv(col2, hsv2);
786
787         if (hsv2.y != 0.0) {
788                 rgb_to_hsv(outcol, hsv);
789                 hsv.x = hsv2.x;
790                 hsv_to_rgb(hsv, tmp);
791
792                 outcol = mix(outcol, tmp, fac);
793                 outcol.a = col1.a;
794         }
795 }
796
797 void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
798 {
799         fac = clamp(fac, 0.0, 1.0);
800         float facm = 1.0 - fac;
801
802         outcol = col1;
803
804         vec4 hsv, hsv2;
805         rgb_to_hsv(outcol, hsv);
806
807         if (hsv.y != 0.0) {
808                 rgb_to_hsv(col2, hsv2);
809
810                 hsv.y = facm * hsv.y + fac * hsv2.y;
811                 hsv_to_rgb(hsv, outcol);
812         }
813 }
814
815 void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
816 {
817         fac = clamp(fac, 0.0, 1.0);
818         float facm = 1.0 - fac;
819
820         vec4 hsv, hsv2;
821         rgb_to_hsv(col1, hsv);
822         rgb_to_hsv(col2, hsv2);
823
824         hsv.z = facm * hsv.z + fac * hsv2.z;
825         hsv_to_rgb(hsv, outcol);
826 }
827
828 void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
829 {
830         fac = clamp(fac, 0.0, 1.0);
831         float facm = 1.0 - fac;
832
833         outcol = col1;
834
835         vec4 hsv, hsv2, tmp;
836         rgb_to_hsv(col2, hsv2);
837
838         if (hsv2.y != 0.0) {
839                 rgb_to_hsv(outcol, hsv);
840                 hsv.x = hsv2.x;
841                 hsv.y = hsv2.y;
842                 hsv_to_rgb(hsv, tmp);
843
844                 outcol = mix(outcol, tmp, fac);
845                 outcol.a = col1.a;
846         }
847 }
848
849 void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
850 {
851         fac = clamp(fac, 0.0, 1.0);
852         float facm = 1.0 - fac;
853
854         vec4 one = vec4(1.0);
855         vec4 scr = one - (one - col2) * (one - col1);
856         outcol = facm * col1 + fac * ((one - col1) * col2 * col1 + col1 * scr);
857 }
858
859 void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
860 {
861         fac = clamp(fac, 0.0, 1.0);
862
863         outcol = col1 + fac * (2.0 * (col2 - vec4(0.5)));
864 }
865
866 void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
867 {
868         outcol = texture(colormap, vec2(fac, 0.0));
869         outalpha = outcol.a;
870 }
871
872 void rgbtobw(vec4 color, out float outval)
873 {
874 #ifdef USE_NEW_SHADING
875         vec3 factors = vec3(0.2126, 0.7152, 0.0722);
876 #else
877         vec3 factors = vec3(0.35, 0.45, 0.2); /* keep these factors in sync with texture.h:RGBTOBW */
878 #endif
879         outval = dot(color.rgb, factors);
880 }
881
882 void invert(float fac, vec4 col, out vec4 outcol)
883 {
884         outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac);
885         outcol.w = col.w;
886 }
887
888 void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
889 {
890         out_vec = clamp(vec, min, max);
891 }
892
893 void clamp_val(float value, float min, float max, out float out_value)
894 {
895         out_value = clamp(value, min, max);
896 }
897
898 void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
899 {
900         vec4 hsv;
901
902         rgb_to_hsv(col, hsv);
903
904         hsv[0] += (hue - 0.5);
905         if (hsv[0] > 1.0) hsv[0] -= 1.0; else if (hsv[0] < 0.0) hsv[0] += 1.0;
906         hsv[1] *= sat;
907         if (hsv[1] > 1.0) hsv[1] = 1.0; else if (hsv[1] < 0.0) hsv[1] = 0.0;
908         hsv[2] *= value;
909         if (hsv[2] > 1.0) hsv[2] = 1.0; else if (hsv[2] < 0.0) hsv[2] = 0.0;
910
911         hsv_to_rgb(hsv, outcol);
912
913         outcol = mix(col, outcol, fac);
914 }
915
916 void separate_rgb(vec4 col, out float r, out float g, out float b)
917 {
918         r = col.r;
919         g = col.g;
920         b = col.b;
921 }
922
923 void combine_rgb(float r, float g, float b, out vec4 col)
924 {
925         col = vec4(r, g, b, 1.0);
926 }
927
928 void separate_xyz(vec3 vec, out float x, out float y, out float z)
929 {
930         x = vec.r;
931         y = vec.g;
932         z = vec.b;
933 }
934
935 void combine_xyz(float x, float y, float z, out vec3 vec)
936 {
937         vec = vec3(x, y, z);
938 }
939
940 void separate_hsv(vec4 col, out float h, out float s, out float v)
941 {
942         vec4 hsv;
943
944         rgb_to_hsv(col, hsv);
945         h = hsv[0];
946         s = hsv[1];
947         v = hsv[2];
948 }
949
950 void combine_hsv(float h, float s, float v, out vec4 col)
951 {
952         hsv_to_rgb(vec4(h, s, v, 1.0), col);
953 }
954
955 void output_node(vec4 rgb, float alpha, out vec4 outrgb)
956 {
957         outrgb = vec4(rgb.rgb, alpha);
958 }
959
960 /*********** TEXTURES ***************/
961
962 void texture_flip_blend(vec3 vec, out vec3 outvec)
963 {
964         outvec = vec.yxz;
965 }
966
967 void texture_blend_lin(vec3 vec, out float outval)
968 {
969         outval = (1.0 + vec.x) * 0.5;
970 }
971
972 void texture_blend_quad(vec3 vec, out float outval)
973 {
974         outval = max((1.0 + vec.x) * 0.5, 0.0);
975         outval *= outval;
976 }
977
978 void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
979 {
980         float a = sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) * 20.0;
981         float wi = 0.5 + 0.5 * sin(a);
982
983         value = wi;
984         color = vec4(wi, wi, wi, 1.0);
985         normal = vec3(0.0);
986 }
987
988 void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
989 {
990         color = texture(ima, (vec.xy + vec2(1.0)) * 0.5);
991         value = color.a;
992
993         normal.x = 2.0 * (color.r - 0.5);
994         normal.y = 2.0 * (0.5 - color.g);
995         normal.z = 2.0 * (color.b - 0.5);
996 }
997
998 /************* MTEX *****************/
999
1000 void texco_orco(vec3 attorco, out vec3 orco)
1001 {
1002         orco = attorco;
1003 }
1004
1005 void texco_uv(vec2 attuv, out vec3 uv)
1006 {
1007         /* disabled for now, works together with leaving out mtex_2d_mapping
1008            uv = vec3(attuv * 2.0 - vec2(1.0), 0.0); */
1009         uv = vec3(attuv, 0.0);
1010 }
1011
1012 void texco_norm(vec3 normal, out vec3 outnormal)
1013 {
1014         /* corresponds to shi->orn, which is negated so cancels
1015            out blender normal negation */
1016         outnormal = normalize(normal);
1017 }
1018
1019 void texco_tangent(vec4 tangent, out vec3 outtangent)
1020 {
1021         outtangent = normalize(tangent.xyz);
1022 }
1023
1024 void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
1025 {
1026         global = (viewinvmat * vec4(co, 1.0)).xyz;
1027 }
1028
1029 void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
1030 {
1031         object = (obinvmat * (viewinvmat * vec4(co, 1.0))).xyz;
1032 }
1033
1034 void texco_refl(vec3 vn, vec3 view, out vec3 ref)
1035 {
1036         ref = view - 2.0 * dot(vn, view) * vn;
1037 }
1038
1039 void shade_norm(vec3 normal, out vec3 outnormal)
1040 {
1041         /* blender render normal is negated */
1042         outnormal = -normalize(normal);
1043 }
1044
1045 void mtex_mirror(vec3 tcol, vec4 refcol, float tin, float colmirfac, out vec4 outrefcol)
1046 {
1047         outrefcol = mix(refcol, vec4(1.0, tcol), tin * colmirfac);
1048 }
1049
1050 void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1051 {
1052         float facm;
1053
1054         fact *= facg;
1055         facm = 1.0 - fact;
1056
1057         incol = fact * texcol + facm * outcol;
1058 }
1059
1060 void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1061 {
1062         float facm;
1063
1064         fact *= facg;
1065         facm = 1.0 - fact;
1066
1067         incol = (facm + fact * texcol) * outcol;
1068 }
1069
1070 void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1071 {
1072         float facm;
1073
1074         fact *= facg;
1075         facm = 1.0 - fact;
1076
1077         incol = vec3(1.0) - (vec3(facm) + fact * (vec3(1.0) - texcol)) * (vec3(1.0) - outcol);
1078 }
1079
1080 void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1081 {
1082         float facm;
1083
1084         fact *= facg;
1085         facm = 1.0 - fact;
1086
1087         if (outcol.r < 0.5)
1088                 incol.r = outcol.r * (facm + 2.0 * fact * texcol.r);
1089         else
1090                 incol.r = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.r)) * (1.0 - outcol.r);
1091
1092         if (outcol.g < 0.5)
1093                 incol.g = outcol.g * (facm + 2.0 * fact * texcol.g);
1094         else
1095                 incol.g = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.g)) * (1.0 - outcol.g);
1096
1097         if (outcol.b < 0.5)
1098                 incol.b = outcol.b * (facm + 2.0 * fact * texcol.b);
1099         else
1100                 incol.b = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.b)) * (1.0 - outcol.b);
1101 }
1102
1103 void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1104 {
1105         incol = -fact * facg * texcol + outcol;
1106 }
1107
1108 void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1109 {
1110         incol = fact * facg * texcol + outcol;
1111 }
1112
1113 void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1114 {
1115         float facm;
1116
1117         fact *= facg;
1118         facm = 1.0 - fact;
1119
1120         if (texcol.r != 0.0) incol.r = facm * outcol.r + fact * outcol.r / texcol.r;
1121         if (texcol.g != 0.0) incol.g = facm * outcol.g + fact * outcol.g / texcol.g;
1122         if (texcol.b != 0.0) incol.b = facm * outcol.b + fact * outcol.b / texcol.b;
1123 }
1124
1125 void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1126 {
1127         float facm;
1128
1129         fact *= facg;
1130         facm = 1.0 - fact;
1131
1132         incol = facm * outcol + fact * abs(texcol - outcol);
1133 }
1134
1135 void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1136 {
1137         float facm, col;
1138
1139         fact *= facg;
1140         facm = 1.0 - fact;
1141
1142         incol.r = min(outcol.r, texcol.r) * fact + outcol.r * facm;
1143         incol.g = min(outcol.g, texcol.g) * fact + outcol.g * facm;
1144         incol.b = min(outcol.b, texcol.b) * fact + outcol.b * facm;
1145 }
1146
1147 void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1148 {
1149         float facm, col;
1150
1151         fact *= facg;
1152
1153         col = fact * texcol.r;
1154         if (col > outcol.r) incol.r = col; else incol.r = outcol.r;
1155         col = fact * texcol.g;
1156         if (col > outcol.g) incol.g = col; else incol.g = outcol.g;
1157         col = fact * texcol.b;
1158         if (col > outcol.b) incol.b = col; else incol.b = outcol.b;
1159 }
1160
1161 void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1162 {
1163         vec4 col;
1164
1165         mix_hue(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1166         incol.rgb = col.rgb;
1167 }
1168
1169 void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1170 {
1171         vec4 col;
1172
1173         mix_sat(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1174         incol.rgb = col.rgb;
1175 }
1176
1177 void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1178 {
1179         vec4 col;
1180
1181         mix_val(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1182         incol.rgb = col.rgb;
1183 }
1184
1185 void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1186 {
1187         vec4 col;
1188
1189         mix_color(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1190         incol.rgb = col.rgb;
1191 }
1192
1193 void mtex_rgb_soft(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1194 {
1195         vec4 col;
1196
1197         mix_soft(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1198         incol.rgb = col.rgb;
1199 }
1200
1201 void mtex_rgb_linear(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1202 {
1203         fact *= facg;
1204
1205         if (texcol.r > 0.5)
1206                 incol.r = outcol.r + fact * (2.0 * (texcol.r - 0.5));
1207         else
1208                 incol.r = outcol.r + fact * (2.0 * (texcol.r) - 1.0);
1209
1210         if (texcol.g > 0.5)
1211                 incol.g = outcol.g + fact * (2.0 * (texcol.g - 0.5));
1212         else
1213                 incol.g = outcol.g + fact * (2.0 * (texcol.g) - 1.0);
1214
1215         if (texcol.b > 0.5)
1216                 incol.b = outcol.b + fact * (2.0 * (texcol.b - 0.5));
1217         else
1218                 incol.b = outcol.b + fact * (2.0 * (texcol.b) - 1.0);
1219 }
1220
1221 void mtex_value_vars(inout float fact, float facg, out float facm)
1222 {
1223         fact *= abs(facg);
1224         facm = 1.0 - fact;
1225
1226         if (facg < 0.0) {
1227                 float tmp = fact;
1228                 fact = facm;
1229                 facm = tmp;
1230         }
1231 }
1232
1233 void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
1234 {
1235         float facm;
1236         mtex_value_vars(fact, facg, facm);
1237
1238         incol = fact * texcol + facm * outcol;
1239 }
1240
1241 void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
1242 {
1243         float facm;
1244         mtex_value_vars(fact, facg, facm);
1245
1246         facm = 1.0 - facg;
1247         incol = (facm + fact * texcol) * outcol;
1248 }
1249
1250 void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
1251 {
1252         float facm;
1253         mtex_value_vars(fact, facg, facm);
1254
1255         facm = 1.0 - facg;
1256         incol = 1.0 - (facm + fact * (1.0 - texcol)) * (1.0 - outcol);
1257 }
1258
1259 void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
1260 {
1261         float facm;
1262         mtex_value_vars(fact, facg, facm);
1263
1264         fact = -fact;
1265         incol = fact * texcol + outcol;
1266 }
1267
1268 void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
1269 {
1270         float facm;
1271         mtex_value_vars(fact, facg, facm);
1272
1273         fact = fact;
1274         incol = fact * texcol + outcol;
1275 }
1276
1277 void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
1278 {
1279         float facm;
1280         mtex_value_vars(fact, facg, facm);
1281
1282         if (texcol != 0.0)
1283                 incol = facm * outcol + fact * outcol / texcol;
1284         else
1285                 incol = 0.0;
1286 }
1287
1288 void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
1289 {
1290         float facm;
1291         mtex_value_vars(fact, facg, facm);
1292
1293         incol = facm * outcol + fact * abs(texcol - outcol);
1294 }
1295
1296 void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
1297 {
1298         float facm;
1299         mtex_value_vars(fact, facg, facm);
1300
1301         incol = facm * outcol + fact * min(outcol, texcol);
1302 }
1303
1304 void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
1305 {
1306         float facm;
1307         mtex_value_vars(fact, facg, facm);
1308
1309         float col = fact * texcol;
1310         if (col > outcol) incol = col; else incol = outcol;
1311 }
1312
1313 void mtex_value_clamp_positive(float fac, out float outfac)
1314 {
1315         outfac = max(fac, 0.0);
1316 }
1317
1318 void mtex_value_clamp(float fac, out float outfac)
1319 {
1320         outfac = clamp(fac, 0.0, 1.0);
1321 }
1322
1323 void mtex_har_divide(float har, out float outhar)
1324 {
1325         outhar = har / 128.0;
1326 }
1327
1328 void mtex_har_multiply_clamp(float har, out float outhar)
1329 {
1330         outhar = clamp(har * 128.0, 1.0, 511.0);
1331 }
1332
1333 void mtex_alpha_from_col(vec4 col, out float alpha)
1334 {
1335         alpha = col.a;
1336 }
1337
1338 void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
1339 {
1340         outcol = vec4(col.rgb, alpha);
1341 }
1342
1343 void mtex_alpha_multiply_value(vec4 col, float value, out vec4 outcol)
1344 {
1345         outcol = vec4(col.rgb, col.a * value);
1346 }
1347
1348 void mtex_rgbtoint(vec4 rgb, out float intensity)
1349 {
1350         intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
1351 }
1352
1353 void mtex_value_invert(float invalue, out float outvalue)
1354 {
1355         outvalue = 1.0 - invalue;
1356 }
1357
1358 void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
1359 {
1360         outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
1361 }
1362
1363 void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
1364 {
1365         float fact = intensity;
1366         outintensity = intensity * stencil;
1367         outstencil = stencil * fact;
1368 }
1369
1370 void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
1371 {
1372         float fact = rgb.a;
1373         outrgb = vec4(rgb.rgb, rgb.a * stencil);
1374         outstencil = stencil * fact;
1375 }
1376
1377 void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
1378 {
1379         outtexco = texco + ofs;
1380 }
1381
1382 void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
1383 {
1384         outtexco = size * texco;
1385 }
1386
1387 void mtex_2d_mapping(vec3 vec, out vec3 outvec)
1388 {
1389         outvec = vec3(vec.xy * 0.5 + vec2(0.5), vec.z);
1390 }
1391
1392 vec3 mtex_2d_mapping(vec3 vec)
1393 {
1394         return vec3(vec.xy * 0.5 + vec2(0.5), vec.z);
1395 }
1396
1397 void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
1398 {
1399         color = texture(ima, co);
1400         value = 1.0;
1401 }
1402
1403 void mtex_cube_map_refl_from_refldir(
1404         samplerCube ima, vec3 reflecteddirection, out float value, out vec4 color)
1405 {
1406         color = texture(ima, reflecteddirection);
1407         value = color.a;
1408 }
1409
1410 void mtex_cube_map_refl(
1411         samplerCube ima, vec3 vp, vec3 vn, mat4 viewmatrixinverse, mat4 viewmatrix,
1412         out float value, out vec4 color)
1413 {
1414         vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0));
1415         vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix));
1416         vec3 reflecteddirection = reflect(viewdirection, normaldirection);
1417         color = texture(ima, reflecteddirection);
1418         value = 1.0;
1419 }
1420
1421 void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
1422 {
1423         color = texture(ima, texco.xy);
1424         value = 1.0;
1425 }
1426
1427 void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
1428 {
1429         // The invert of the red channel is to make
1430         // the normal map compliant with the outside world.
1431         // It needs to be done because in Blender
1432         // the normal used points inward.
1433         // Should this ever change this negate must be removed.
1434         vec4 color = texture(ima, texco.xy);
1435         normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
1436 }
1437
1438 void mtex_bump_normals_init(vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude)
1439 {
1440         vNorg = vN;
1441         vNacc = vN;
1442         fPrevMagnitude = 1.0;
1443 }
1444
1445 /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
1446 mat3 to_mat3(mat4 m4)
1447 {
1448         mat3 m3;
1449         m3[0] = m4[0].xyz;
1450         m3[1] = m4[1].xyz;
1451         m3[2] = m4[2].xyz;
1452         return m3;
1453 }
1454
1455 void mtex_bump_init_objspace(
1456         vec3 surf_pos, vec3 surf_norm,
1457         mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv,
1458         float fPrevMagnitude_in, vec3 vNacc_in,
1459         out float fPrevMagnitude_out, out vec3 vNacc_out,
1460         out vec3 vR1, out vec3 vR2, out float fDet)
1461 {
1462         mat3 obj2view = to_mat3(ModelViewMatrix);
1463         mat3 view2obj = to_mat3(ModelViewMatrixInverse);
1464
1465         vec3 vSigmaS = view2obj * dFdx(surf_pos);
1466         vec3 vSigmaT = view2obj * dFdy(surf_pos);
1467         vec3 vN = normalize(surf_norm * obj2view);
1468
1469         vR1 = cross(vSigmaT, vN);
1470         vR2 = cross(vN, vSigmaS);
1471         fDet = dot(vSigmaS, vR1);
1472
1473         /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */
1474         vR1 = vR1 * view2obj;
1475         vR2 = vR2 * view2obj;
1476         vN = vN * view2obj;
1477
1478         float fMagnitude = abs(fDet) * length(vN);
1479         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1480         fPrevMagnitude_out = fMagnitude;
1481 }
1482
1483 void mtex_bump_init_texturespace(
1484         vec3 surf_pos, vec3 surf_norm,
1485         float fPrevMagnitude_in, vec3 vNacc_in,
1486         out float fPrevMagnitude_out, out vec3 vNacc_out,
1487         out vec3 vR1, out vec3 vR2, out float fDet)
1488 {
1489         vec3 vSigmaS = dFdx(surf_pos);
1490         vec3 vSigmaT = dFdy(surf_pos);
1491         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1492
1493         vR1 = normalize(cross(vSigmaT, vN));
1494         vR2 = normalize(cross(vN, vSigmaS));
1495         fDet = sign(dot(vSigmaS, vR1));
1496
1497         float fMagnitude = abs(fDet);
1498         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1499         fPrevMagnitude_out = fMagnitude;
1500 }
1501
1502 void mtex_bump_init_viewspace(
1503         vec3 surf_pos, vec3 surf_norm,
1504         float fPrevMagnitude_in, vec3 vNacc_in,
1505         out float fPrevMagnitude_out, out vec3 vNacc_out,
1506         out vec3 vR1, out vec3 vR2, out float fDet)
1507 {
1508         vec3 vSigmaS = dFdx(surf_pos);
1509         vec3 vSigmaT = dFdy(surf_pos);
1510         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1511
1512         vR1 = cross(vSigmaT, vN);
1513         vR2 = cross(vN, vSigmaS);
1514         fDet = dot(vSigmaS, vR1);
1515
1516         float fMagnitude = abs(fDet);
1517         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1518         fPrevMagnitude_out = fMagnitude;
1519 }
1520
1521 void mtex_bump_tap3(
1522         vec3 texco, sampler2D ima, float hScale,
1523         out float dBs, out float dBt)
1524 {
1525         vec2 STll = texco.xy;
1526         vec2 STlr = texco.xy + dFdx(texco.xy);
1527         vec2 STul = texco.xy + dFdy(texco.xy);
1528
1529         float Hll, Hlr, Hul;
1530         rgbtobw(texture(ima, STll), Hll);
1531         rgbtobw(texture(ima, STlr), Hlr);
1532         rgbtobw(texture(ima, STul), Hul);
1533
1534         dBs = hScale * (Hlr - Hll);
1535         dBt = hScale * (Hul - Hll);
1536 }
1537
1538 #ifdef BUMP_BICUBIC
1539
1540 void mtex_bump_bicubic(
1541         vec3 texco, sampler2D ima, float hScale,
1542         out float dBs, out float dBt )
1543 {
1544         float Hl;
1545         float Hr;
1546         float Hd;
1547         float Hu;
1548
1549         vec2 TexDx = dFdx(texco.xy);
1550         vec2 TexDy = dFdy(texco.xy);
1551
1552         vec2 STl = texco.xy - 0.5 * TexDx;
1553         vec2 STr = texco.xy + 0.5 * TexDx;
1554         vec2 STd = texco.xy - 0.5 * TexDy;
1555         vec2 STu = texco.xy + 0.5 * TexDy;
1556
1557         rgbtobw(texture(ima, STl), Hl);
1558         rgbtobw(texture(ima, STr), Hr);
1559         rgbtobw(texture(ima, STd), Hd);
1560         rgbtobw(texture(ima, STu), Hu);
1561
1562         vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
1563         float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
1564         if (fBlend != 0.0) {
1565                 // the derivative of the bicubic sampling of level 0
1566                 ivec2 vDim;
1567                 vDim = textureSize(ima, 0);
1568
1569                 // taking the fract part of the texture coordinate is a hardcoded wrap mode.
1570                 // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender.
1571                 // this is done so that we can still get a valid texel with uvs outside the 0,1 range
1572                 // by texelFetch below, as coordinates are clamped when using this function.
1573                 vec2 fTexLoc = vDim * fract(texco.xy) - vec2(0.5, 0.5);
1574                 ivec2 iTexLoc = ivec2(floor(fTexLoc));
1575                 vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0);        // sat just to be pedantic
1576
1577 /*******************************************************************************************
1578  * This block will replace the one below when one channel textures are properly supported. *
1579  *******************************************************************************************
1580                 vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim);
1581                 vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim);
1582                 vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim);
1583                 vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim);
1584
1585                 mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
1586                             vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
1587                             vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
1588                             vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
1589  */
1590                 ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
1591
1592                 mat4 H;
1593
1594                 for (int i = 0; i < 4; i++) {
1595                         for (int j = 0; j < 4; j++) {
1596                                 ivec2 iTexTmp = iTexLocMod + ivec2(i, j);
1597
1598                                 // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range.
1599                                 // this is guaranteed to work since we take the fractional part of the uv above.
1600                                 iTexTmp.x = (iTexTmp.x < 0) ? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x) ? iTexTmp.x - vDim.x : iTexTmp.x);
1601                                 iTexTmp.y = (iTexTmp.y < 0) ? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y) ? iTexTmp.y - vDim.y : iTexTmp.y);
1602
1603                                 rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]);
1604                         }
1605                 }
1606
1607                 float x = t.x, y = t.y;
1608                 float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y;
1609
1610                 vec4 X  = vec4(-0.5 * (x3 + x) + x2,    1.5 * x3 - 2.5 * x2 + 1, -1.5 * x3 + 2 * x2 + 0.5 * x, 0.5 * (x3 - x2));
1611                 vec4 Y  = vec4(-0.5 * (y3 + y) + y2,    1.5 * y3 - 2.5 * y2 + 1, -1.5 * y3 + 2 * y2 + 0.5 * y, 0.5 * (y3 - y2));
1612                 vec4 dX = vec4(-1.5 * x2 + 2 * x - 0.5, 4.5 * x2 - 5 * x,        -4.5 * x2 + 4 * x + 0.5,      1.5 * x2 - x);
1613                 vec4 dY = vec4(-1.5 * y2 + 2 * y - 0.5, 4.5 * y2 - 5 * y,        -4.5 * y2 + 4 * y + 0.5,      1.5 * y2 - y);
1614
1615                 // complete derivative in normalized coordinates (mul by vDim)
1616                 vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X));
1617
1618                 // transform derivative to screen-space
1619                 vec2 dHdxy_bicubic = vec2(dHdST.x * TexDx.x + dHdST.y * TexDx.y,
1620                                           dHdST.x * TexDy.x + dHdST.y * TexDy.y);
1621
1622                 // blend between the two
1623                 dHdxy = dHdxy * (1 - fBlend) + dHdxy_bicubic * fBlend;
1624         }
1625
1626         dBs = hScale * dHdxy.x;
1627         dBt = hScale * dHdxy.y;
1628 }
1629
1630 #endif
1631
1632 void mtex_bump_tap5(
1633         vec3 texco, sampler2D ima, float hScale,
1634         out float dBs, out float dBt)
1635 {
1636         vec2 TexDx = dFdx(texco.xy);
1637         vec2 TexDy = dFdy(texco.xy);
1638
1639         vec2 STc = texco.xy;
1640         vec2 STl = texco.xy - 0.5 * TexDx;
1641         vec2 STr = texco.xy + 0.5 * TexDx;
1642         vec2 STd = texco.xy - 0.5 * TexDy;
1643         vec2 STu = texco.xy + 0.5 * TexDy;
1644
1645         float Hc, Hl, Hr, Hd, Hu;
1646         rgbtobw(texture(ima, STc), Hc);
1647         rgbtobw(texture(ima, STl), Hl);
1648         rgbtobw(texture(ima, STr), Hr);
1649         rgbtobw(texture(ima, STd), Hd);
1650         rgbtobw(texture(ima, STu), Hu);
1651
1652         dBs = hScale * (Hr - Hl);
1653         dBt = hScale * (Hu - Hd);
1654 }
1655
1656 void mtex_bump_deriv(
1657         vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale,
1658         out float dBs, out float dBt)
1659 {
1660         float s = 1.0;      // negate this if flipped texture coordinate
1661         vec2 TexDx = dFdx(texco.xy);
1662         vec2 TexDy = dFdy(texco.xy);
1663
1664         // this variant using a derivative map is described here
1665         // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
1666         vec2 dim = vec2(ima_x, ima_y);
1667         vec2 dBduv = hScale * dim * (2.0 * texture(ima, texco.xy).xy - 1.0);
1668
1669         dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y;
1670         dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y;
1671 }
1672
1673 void mtex_bump_apply(
1674         float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
1675         out vec3 vNacc_out, out vec3 perturbed_norm)
1676 {
1677         vec3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2);
1678
1679         vNacc_out = vNacc_in - vSurfGrad;
1680         perturbed_norm = normalize(vNacc_out);
1681 }
1682
1683 void mtex_bump_apply_texspace(
1684         float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
1685         sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
1686         out vec3 vNacc_out, out vec3 perturbed_norm)
1687 {
1688         vec2 TexDx = dFdx(texco.xy);
1689         vec2 TexDy = dFdy(texco.xy);
1690
1691         vec3 vSurfGrad = sign(fDet) * (
1692                 dBs / length(vec2(ima_x * TexDx.x, ima_y * TexDx.y)) * vR1 +
1693                 dBt / length(vec2(ima_x * TexDy.x, ima_y * TexDy.y)) * vR2);
1694
1695         vNacc_out = vNacc_in - vSurfGrad;
1696         perturbed_norm = normalize(vNacc_out);
1697 }
1698
1699 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1700 {
1701         outnormal = vec3(-normal.x, -normal.y, normal.z);
1702 }
1703
1704 void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1705 {
1706         vec3 B = tangent.w * cross(normal, tangent.xyz);
1707
1708         outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
1709         outnormal = normalize(outnormal);
1710 }
1711
1712 void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
1713 {
1714         outnormal = normalize((viewmat * vec4(texnormal, 0.0)).xyz);
1715 }
1716
1717 void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
1718 {
1719         outnormal = normalize(NormalMatrix * texnormal);
1720 }
1721
1722 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1723 {
1724         outnormal = (1.0 - norfac) * normal + norfac * newnormal;
1725         outnormal = normalize(outnormal);
1726 }
1727
1728 /******* MATERIAL *********/
1729
1730 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1731 {
1732         lv = lampvec;
1733         dist = 1.0;
1734         visifac = 1.0;
1735 }
1736
1737 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1738 {
1739         lv = co - lampco;
1740         dist = length(lv);
1741         lv = normalize(lv);
1742         visifac = 1.0;
1743 }
1744
1745 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1746 {
1747         visifac = lampdist / (lampdist + dist);
1748 }
1749
1750 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1751 {
1752         visifac = lampdist / (lampdist + dist * dist);
1753 }
1754
1755 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1756 {
1757         float lampdistkw = lampdist * lampdist;
1758
1759         visifac = lampdist / (lampdist + ld1 * dist);
1760         visifac *= lampdistkw / (lampdistkw + ld2 * dist * dist);
1761 }
1762
1763 void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coeff_quad, float dist, out float visifac)
1764 {
1765         vec3 coeff = vec3(coeff_const, coeff_lin, coeff_quad);
1766         vec3 d_coeff = vec3(1.0, dist, dist * dist);
1767         float visifac_r = dot(coeff, d_coeff);
1768         if (visifac_r > 0.0)
1769                 visifac = 1.0 / visifac_r;
1770         else
1771                 visifac = 0.0;
1772 }
1773
1774 void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
1775 {
1776         visifac = texture(curvemap, vec2(dist / lampdist, 0.0)).x;
1777 }
1778
1779 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1780 {
1781         float t = lampdist - dist;
1782
1783         outvisifac = visifac * max(t, 0.0) / lampdist;
1784 }
1785
1786 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
1787 {
1788         if (dot(lv, lampvec) > 0.0) {
1789                 vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz;
1790                 /* without clever non-uniform scale, we could do: */
1791                 // float x = max(abs(lvrot.x / lvrot.z), abs(lvrot.y / lvrot.z));
1792                 float x = max(abs((lvrot.x / scale.x) / lvrot.z), abs((lvrot.y / scale.y) / lvrot.z));
1793
1794                 inpr = 1.0 / sqrt(1.0 + x * x);
1795         }
1796         else
1797                 inpr = 0.0;
1798 }
1799
1800 void lamp_visibility_spot_circle(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
1801 {
1802         /* without clever non-uniform scale, we could do: */
1803         // inpr = dot(lv, lampvec);
1804         if (dot(lv, lampvec) > 0.0) {
1805                 vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz;
1806                 float x = abs(lvrot.x / lvrot.z);
1807                 float y = abs(lvrot.y / lvrot.z);
1808
1809                 float ellipse = abs((x * x) / (scale.x * scale.x) + (y * y) / (scale.y * scale.y));
1810
1811                 inpr = 1.0 / sqrt(1.0 + ellipse);
1812         }
1813         else
1814                 inpr = 0.0;
1815 }
1816
1817 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1818 {
1819         float t = spotsi;
1820
1821         if (inpr <= t) {
1822                 outvisifac = 0.0;
1823         }
1824         else {
1825                 t = inpr - t;
1826
1827                 /* soft area */
1828                 if (spotbl != 0.0)
1829                         inpr *= smoothstep(0.0, 1.0, t / spotbl);
1830
1831                 outvisifac = visifac * inpr;
1832         }
1833 }
1834
1835 void lamp_visibility_clamp(float visifac, out float outvisifac)
1836 {
1837         outvisifac = (visifac < 0.001) ? 0.0 : visifac;
1838 }
1839
1840 void world_paper_view(vec3 vec, out vec3 outvec)
1841 {
1842         vec3 nvec = normalize(vec);
1843         outvec = (ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
1844 }
1845
1846 void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
1847 {
1848         if (view.z >= 0.0)
1849                 zenfac = zenup;
1850         else
1851                 zenfac = zendown;
1852 }
1853
1854 void world_blend_paper_real(vec3 vec, out float blend)
1855 {
1856         blend = abs(vec.y);
1857 }
1858
1859 void world_blend_paper(vec3 vec, out float blend)
1860 {
1861         blend = (vec.y + 1.0) * 0.5;
1862 }
1863
1864 void world_blend_real(vec3 vec, out float blend)
1865 {
1866         blend = abs(normalize(vec).z);
1867 }
1868
1869 void world_blend(vec3 vec, out float blend)
1870 {
1871         blend = (normalize(vec).z + 1) * 0.5;
1872 }
1873
1874 void shade_view(vec3 co, out vec3 view)
1875 {
1876         /* handle perspective/orthographic */
1877         view = (ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
1878 }
1879
1880 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1881 {
1882         vec3 c = cross(lv, tang);
1883         vec3 vnor = cross(c, tang);
1884
1885         vn = -normalize(vnor);
1886 }
1887
1888 void shade_inp(vec3 vn, vec3 lv, out float inp)
1889 {
1890         inp = dot(vn, lv);
1891 }
1892
1893 void shade_is_no_diffuse(out float is)
1894 {
1895         is = 0.0;
1896 }
1897
1898 void shade_is_hemi(float inp, out float is)
1899 {
1900         is = 0.5 * inp + 0.5;
1901 }
1902
1903 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1904 {
1905         vec3 vec[4], c[4];
1906         float rad[4], fac;
1907
1908         vec[0] = normalize(co - area[0].xyz);
1909         vec[1] = normalize(co - area[1].xyz);
1910         vec[2] = normalize(co - area[2].xyz);
1911         vec[3] = normalize(co - area[3].xyz);
1912
1913         c[0] = normalize(cross(vec[0], vec[1]));
1914         c[1] = normalize(cross(vec[1], vec[2]));
1915         c[2] = normalize(cross(vec[2], vec[3]));
1916         c[3] = normalize(cross(vec[3], vec[0]));
1917
1918         rad[0] = acos(dot(vec[0], vec[1]));
1919         rad[1] = acos(dot(vec[1], vec[2]));
1920         rad[2] = acos(dot(vec[2], vec[3]));
1921         rad[3] = acos(dot(vec[3], vec[0]));
1922
1923         fac =  rad[0] * dot(vn, c[0]);
1924         fac += rad[1] * dot(vn, c[1]);
1925         fac += rad[2] * dot(vn, c[2]);
1926         fac += rad[3] * dot(vn, c[3]);
1927
1928         return max(fac, 0.0);
1929 }
1930
1931 void shade_inp_area(
1932         vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k,
1933         out float inp)
1934 {
1935         vec3 co = position;
1936         vec3 vec = co - lampco;
1937
1938         if (dot(vec, lampvec) < 0.0) {
1939                 inp = 0.0;
1940         }
1941         else {
1942                 float intens = area_lamp_energy(area, co, vn);
1943
1944                 inp = pow(intens * areasize, k);
1945         }
1946 }
1947
1948 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1949 {
1950         vec3 h = normalize(v + l);
1951         float nh = max(dot(n, h), 0.0);
1952         float nv = max(dot(n, v), 0.0);
1953         float realnl = dot(n, l);
1954
1955         if (realnl < 0.0) {
1956                 is = 0.0;
1957         }
1958         else if (nl < 0.0) {
1959                 is = 0.0;
1960         }
1961         else {
1962                 float vh = max(dot(v, h), 0.0);
1963                 float Lit_A = acos(realnl);
1964                 float View_A = acos(nv);
1965
1966                 vec3 Lit_B = normalize(l - realnl * n);
1967                 vec3 View_B = normalize(v - nv * n);
1968
1969                 float t = max(dot(Lit_B, View_B), 0.0);
1970
1971                 float a, b;
1972
1973                 if (Lit_A > View_A) {
1974                         a = Lit_A;
1975                         b = View_A;
1976                 }
1977                 else {
1978                         a = View_A;
1979                         b = Lit_A;
1980                 }
1981
1982                 float A = 1.0 - (0.5 * ((rough * rough) / ((rough * rough) + 0.33)));
1983                 float B = 0.45 * ((rough * rough) / ((rough * rough) + 0.09));
1984
1985                 b *= 0.95;
1986                 is = nl * (A + (B * t * sin(a) * tan(b)));
1987         }
1988 }
1989
1990 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1991 {
1992         float rslt = dot(n, l);
1993         float ang = acos(rslt);
1994
1995         if (ang < size) is = 1.0;
1996         else if (ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1997         else is = 1.0 - ((ang - size) / tsmooth);
1998 }
1999
2000 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
2001 {
2002         if (nl <= 0.0) {
2003                 is = 0.0;
2004         }
2005         else {
2006                 float nv = max(dot(n, v), 0.0);
2007
2008                 if (darkness <= 1.0)
2009                         is = nl * pow(max(nv * nl, 0.1), darkness - 1.0);
2010                 else
2011                         is = nl * pow(1.0001 - nv, darkness - 1.0);
2012         }
2013 }
2014
2015 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
2016 {
2017         float t1, t2;
2018         float ffac;
2019
2020         if (fac == 0.0) {
2021                 ffac = 1.0;
2022         }
2023         else {
2024                 t1 = dot(view, vn);
2025                 if (t1 > 0.0) t2 = 1.0 + t1;
2026                 else t2 = 1.0 - t1;
2027
2028                 t2 = grad + (1.0 - grad) * pow(t2, fac);
2029
2030                 if (t2 < 0.0) ffac = 0.0;
2031                 else if (t2 > 1.0) ffac = 1.0;
2032                 else ffac = t2;
2033         }
2034
2035         return ffac;
2036 }
2037
2038 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
2039 {
2040         is = fresnel_fac(lv, vn, fac_i, fac);
2041 }
2042
2043 void shade_cubic(float is, out float outis)
2044 {
2045         if (is > 0.0 && is < 1.0)
2046                 outis = smoothstep(0.0, 1.0, is);
2047         else
2048                 outis = is;
2049 }
2050
2051 void shade_visifac(float i, float visifac, float refl, out float outi)
2052 {
2053         /*if (i > 0.0)*/
2054         outi = max(i * visifac * refl, 0.0);
2055         /*else
2056             outi = i;*/
2057 }
2058
2059 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
2060 {
2061         vn = tang;
2062 }
2063
2064 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
2065 {
2066         if (i > 0.0)
2067                 outcol = i * lampcol * col;
2068         else
2069                 outcol = vec3(0.0);
2070 }
2071
2072 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
2073 {
2074         lv += view;
2075         lv = normalize(lv);
2076
2077         t = dot(vn, lv);
2078         t = 0.5 * t + 0.5;
2079
2080         t = visifac * spec * pow(t, hard);
2081 }
2082
2083 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
2084 {
2085         vec3 h = normalize(l + v);
2086         float rslt = max(dot(h, n), 0.0);
2087
2088         specfac = pow(rslt, hard);
2089 }
2090
2091 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
2092 {
2093         vec3 h = normalize(v + l);
2094         float nh = dot(n, h);
2095
2096         if (nh < 0.0) {
2097                 specfac = 0.0;
2098         }
2099         else {
2100                 float nv = max(dot(n, v), 0.0);
2101                 float i = pow(nh, hard);
2102
2103                 i = i / (0.1 + nv);
2104                 specfac = i;
2105         }
2106 }
2107
2108 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
2109 {
2110         if (refrac < 1.0) {
2111                 specfac = 0.0;
2112         }
2113         else if (spec_power == 0.0) {
2114                 specfac = 0.0;
2115         }
2116         else {
2117                 if (spec_power < 100.0)
2118                         spec_power = sqrt(1.0 / spec_power);
2119                 else
2120                         spec_power = 10.0 / spec_power;
2121
2122                 vec3 h = normalize(v + l);
2123                 float nh = dot(n, h);
2124                 if (nh < 0.0) {
2125                         specfac = 0.0;
2126                 }
2127                 else {
2128                         float nv = max(dot(n, v), 0.01);
2129                         float nl = dot(n, l);
2130                         if (nl <= 0.01) {
2131                                 specfac = 0.0;
2132                         }
2133                         else {
2134                                 float vh = max(dot(v, h), 0.01);
2135
2136                                 float a = 1.0;
2137                                 float b = (2.0 * nh * nv) / vh;
2138                                 float c = (2.0 * nh * nl) / vh;
2139
2140                                 float g = 0.0;
2141
2142                                 if (a < b && a < c) g = a;
2143                                 else if (b < a && b < c) g = b;
2144                                 else if (c < a && c < b) g = c;
2145
2146                                 float p = sqrt(((refrac * refrac) + (vh * vh) - 1.0));
2147                                 float f = ((((p - vh) * (p - vh)) / ((p + vh) * (p + vh))) *
2148                                            (1.0 + ((((vh * (p + vh)) - 1.0) * ((vh * (p + vh)) - 1.0)) /
2149                                                    (((vh * (p - vh)) + 1.0) * ((vh * (p - vh)) + 1.0)))));
2150                                 float ang = acos(nh);
2151
2152                                 specfac = max(f * g * exp_blender((-(ang * ang) / (2.0 * spec_power * spec_power))), 0.0);
2153                         }
2154                 }
2155         }
2156 }
2157
2158 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
2159 {
2160         vec3 h = normalize(l + v);
2161         float nh = max(dot(n, h), 0.001);
2162         float nv = max(dot(n, v), 0.001);
2163         float nl = max(dot(n, l), 0.001);
2164         float angle = tan(acos(nh));
2165         float alpha = max(rms, 0.001);
2166
2167         specfac = nl * (1.0 / (4.0 * M_PI * alpha * alpha)) * (exp_blender(-(angle * angle) / (alpha * alpha)) / (sqrt(nv * nl)));
2168 }
2169
2170 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
2171 {
2172         vec3 h = normalize(l + v);
2173         float rslt = dot(h, n);
2174         float ang = acos(rslt);
2175
2176         if (ang < size) rslt = 1.0;
2177         else if (ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
2178         else rslt = 1.0 - ((ang - size) / tsmooth);
2179
2180         specfac = rslt;
2181 }
2182
2183 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
2184 {
2185         outspecfac = specfac * inp;
2186 }
2187
2188 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
2189 {
2190         t = shadfac * spec * visifac * specfac;
2191 }
2192
2193 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
2194 {
2195         outcol = t * lampcol * speccol;
2196 }
2197
2198 void shade_add_mirror(vec3 mir, vec4 refcol, vec3 combined, out vec3 result)
2199 {
2200         result = mir * refcol.gba + (vec3(1.0) - mir * refcol.rrr) * combined;
2201 }
2202
2203 void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha)
2204 {
2205         if (spectra > 0.0) {
2206                 float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0);
2207                 outalpha = (1.0 - t) * alpha + t;
2208         }
2209         else {
2210                 outalpha = alpha;
2211         }
2212 }
2213
2214 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
2215 {
2216         outcol = col1 + col2;
2217 }
2218
2219 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
2220 {
2221         outcol = col + col1 * col2;
2222 }
2223
2224 void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
2225 {
2226         outcol = col1 + max(col2, vec4(0.0));
2227 }
2228
2229 void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
2230 {
2231         outcol = col + max(col1 * col2, vec4(0.0));
2232 }
2233
2234 void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol)
2235 {
2236         vec3 vv = normalize(vm[2].xyz);
2237         float skyfac = 0.5 * (1.0 + dot(vn, -vv));
2238         outcol = col + f * vec4(mix(hor, zen, skyfac), 0);
2239 }
2240
2241 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
2242 {
2243         outcol = col + f * col1;
2244 }
2245
2246 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
2247 {
2248         outcol = col1 * col2;
2249 }
2250
2251 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
2252 {
2253         outcol = col * fac;
2254 }
2255
2256 void shade_mul_value_v3(float fac, vec3 col, out vec3 outcol)
2257 {
2258         outcol = col * fac;
2259 }
2260
2261 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
2262 {
2263         outcol = vec4(col.rgb * obcol.rgb, col.a);
2264 }
2265
2266 void ramp_rgbtobw(vec3 color, out float outval)
2267 {
2268         outval = dot(color, vec3(0.3, 0.58, 0.12));
2269 }
2270
2271 void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb)
2272 {
2273         outshadrgb = i * energy * (1.0 - shadfac) * (vec3(1.0) - shadcol);
2274 }
2275
2276 void shade_only_shadow_diffuse(vec3 shadrgb, vec3 rgb, vec4 diff, out vec4 outdiff)
2277 {
2278         outdiff = diff - vec4(rgb * shadrgb, 0.0);
2279 }
2280
2281 void shade_only_shadow_specular(vec3 shadrgb, vec3 specrgb, vec4 spec, out vec4 outspec)
2282 {
2283         outspec = spec - vec4(specrgb * shadrgb, 0.0);
2284 }
2285
2286 void shade_clamp_positive(vec4 col, out vec4 outcol)
2287 {
2288         outcol = max(col, vec4(0.0));
2289 }
2290
2291 void test_shadowbuf(
2292         vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp,
2293         out float result)
2294 {
2295         if (inp <= 0.0) {
2296                 result = 0.0;
2297         }
2298         else {
2299                 vec4 co = shadowpersmat * vec4(rco, 1.0);
2300
2301                 //float bias = (1.5 - inp*inp)*shadowbias;
2302                 co.z -= shadowbias * co.w;
2303
2304                 if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
2305                         result = textureProj(shadowmap, co);
2306                 }
2307                 else {
2308                         result = 1.0;
2309                 }
2310         }
2311 }
2312
2313 void test_shadowbuf_vsm(
2314         vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, float inp,
2315         out float result)
2316 {
2317         if (inp <= 0.0) {
2318                 result = 0.0;
2319         }
2320         else {
2321                 vec4 co = shadowpersmat * vec4(rco, 1.0);
2322                 if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
2323                         vec2 moments = textureProj(shadowmap, co).rg;
2324                         float dist = co.z / co.w;
2325                         float p = 0.0;
2326
2327                         if (dist <= moments.x)
2328                                 p = 1.0;
2329
2330                         float variance = moments.y - (moments.x * moments.x);
2331                         variance = max(variance, shadowbias / 10.0);
2332
2333                         float d = moments.x - dist;
2334                         float p_max = variance / (variance + d * d);
2335
2336                         // Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1]
2337                         p_max = clamp((p_max - bleedbias) / (1.0 - bleedbias), 0.0, 1.0);
2338
2339                         result = max(p, p_max);
2340                 }
2341                 else {
2342                         result = 1.0;
2343                 }
2344         }
2345 }
2346
2347 void shadows_only(
2348         vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat,
2349         float shadowbias, vec3 shadowcolor, float inp,
2350         out vec3 result)
2351 {
2352         result = vec3(1.0);
2353
2354         if (inp > 0.0) {
2355                 float shadfac;
2356
2357                 test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac);
2358                 result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
2359         }
2360 }
2361
2362 void shadows_only_vsm(
2363         vec3 rco, sampler2D shadowmap, mat4 shadowpersmat,
2364         float shadowbias, float bleedbias, vec3 shadowcolor, float inp,
2365         out vec3 result)
2366 {
2367         result = vec3(1.0);
2368
2369         if (inp > 0.0) {
2370                 float shadfac;
2371
2372                 test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac);
2373                 result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
2374         }
2375 }
2376
2377 void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result)
2378 {
2379
2380         vec4 co = shadowpersmat * vec4(rco, 1.0);
2381
2382         result = textureProj(cookie, co);
2383 }
2384
2385 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
2386 {
2387         outcol = linfac * (1.0 - exp(col * logfac));
2388 }
2389
2390 void shade_mist_factor(
2391         vec3 co, float enable, float miststa, float mistdist, float misttype, float misi,
2392         out float outfac)
2393 {
2394         if (enable == 1.0) {
2395                 float fac, zcor;
2396
2397                 zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
2398
2399                 fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
2400                 if (misttype == 0.0) fac *= fac;
2401                 else if (misttype == 1.0) ;
2402                 else fac = sqrt(fac);
2403
2404                 outfac = 1.0 - (1.0 - fac) * (1.0 - misi);
2405         }
2406         else {
2407                 outfac = 0.0;
2408         }
2409 }
2410
2411 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
2412 {
2413         float fac = clamp(col.a, 0.0, 1.0);
2414         outcol = vec4(mix(hor, col.rgb, fac), col.a);
2415 }
2416
2417 void shade_alpha_opaque(vec4 col, out vec4 outcol)
2418 {
2419         outcol = vec4(col.rgb, 1.0);
2420 }
2421
2422 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
2423 {
2424         outcol = vec4(col.rgb, col.a * obcol.a);
2425 }
2426
2427 /*********** NEW SHADER UTILITIES **************/
2428
2429 float fresnel_dielectric_0(float eta)
2430 {
2431         /* compute fresnel reflactance at normal incidence => cosi = 1.0 */
2432         float A = (eta - 1.0) / (eta + 1.0);
2433
2434         return A * A;
2435 }
2436
2437 float fresnel_dielectric_cos(float cosi, float eta)
2438 {
2439         /* compute fresnel reflectance without explicitly computing
2440          * the refracted direction */
2441         float c = abs(cosi);
2442         float g = eta * eta - 1.0 + c * c;
2443         float result;
2444
2445         if (g > 0.0) {
2446                 g = sqrt(g);
2447                 float A = (g - c) / (g + c);
2448                 float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
2449                 result = 0.5 * A * A * (1.0 + B * B);
2450         }
2451         else {
2452                 result = 1.0;  /* TIR (no refracted component) */
2453         }
2454
2455         return result;
2456 }
2457
2458 float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
2459 {
2460         /* compute fresnel reflectance without explicitly computing
2461          * the refracted direction */
2462         return fresnel_dielectric_cos(dot(Incoming, Normal), eta);
2463 }
2464
2465 float hypot(float x, float y)
2466 {
2467         return sqrt(x * x + y * y);
2468 }
2469
2470 void generated_from_orco(vec3 orco, out vec3 generated)
2471 {
2472 #ifdef VOLUMETRICS
2473 #ifdef MESH_SHADER
2474         generated = volumeObjectLocalCoord;
2475 #else
2476         generated = worldPosition;
2477 #endif
2478 #else
2479         generated = orco;
2480 #endif
2481 }
2482
2483 int floor_to_int(float x)
2484 {
2485         return int(floor(x));
2486 }
2487
2488 int quick_floor(float x)
2489 {
2490         return int(x) - ((x < 0) ? 1 : 0);
2491 }
2492
2493 float integer_noise(int n)
2494 {
2495         int nn;
2496         n = (n + 1013) & 0x7fffffff;
2497         n = (n >> 13) ^ n;
2498         nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
2499         return 0.5 * (float(nn) / 1073741824.0);
2500 }
2501
2502 uint hash(uint kx, uint ky, uint kz)
2503 {
2504 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
2505 #define final(a, b, c) \
2506 { \
2507         c ^= b; c -= rot(b, 14); \
2508         a ^= c; a -= rot(c, 11); \
2509         b ^= a; b -= rot(a, 25); \
2510         c ^= b; c -= rot(b, 16); \
2511         a ^= c; a -= rot(c, 4);  \
2512         b ^= a; b -= rot(a, 14); \
2513         c ^= b; c -= rot(b, 24); \
2514 }
2515         // now hash the data!
2516         uint a, b, c, len = 3u;
2517         a = b = c = 0xdeadbeefu + (len << 2u) + 13u;
2518
2519         c += kz;
2520         b += ky;
2521         a += kx;
2522         final (a, b, c);
2523
2524         return c;
2525 #undef rot
2526 #undef final
2527 }
2528
2529 uint hash(int kx, int ky, int kz)
2530 {
2531         return hash(uint(kx), uint(ky), uint(kz));
2532 }
2533
2534 float bits_to_01(uint bits)
2535 {
2536         float x = float(bits) * (1.0 / float(0xffffffffu));
2537         return x;
2538 }
2539
2540 float cellnoise(vec3 p)
2541 {
2542         int ix = quick_floor(p.x);
2543         int iy = quick_floor(p.y);
2544         int iz = quick_floor(p.z);
2545
2546         return bits_to_01(hash(uint(ix), uint(iy), uint(iz)));
2547 }
2548
2549 vec3 cellnoise_color(vec3 p)
2550 {
2551         float r = cellnoise(p);
2552         float g = cellnoise(vec3(p.y, p.x, p.z));
2553         float b = cellnoise(vec3(p.y, p.z, p.x));
2554
2555         return vec3(r, g, b);
2556 }
2557
2558 float floorfrac(float x, out int i)
2559 {
2560         i = floor_to_int(x);
2561         return x - i;
2562 }
2563
2564
2565 /* Principled BSDF operations */
2566
2567 float sqr(float a)
2568 {
2569         return a*a;
2570 }
2571
2572 float schlick_fresnel(float u)
2573 {
2574         float m = clamp(1.0 - u, 0.0, 1.0);
2575         float m2 = m * m;
2576         return m2 * m2 * m; // pow(m,5)
2577 }
2578
2579 float GTR1(float NdotH, float a)
2580 {
2581         if (a >= 1.0) {
2582                 return M_1_PI;
2583         }
2584
2585         a = max(a, 0.001);
2586         float a2 = a*a;
2587         float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
2588         return (a2 - 1.0) / (M_PI * log(a2) * t);
2589 }
2590
2591 float GTR2(float NdotH, float a)
2592 {
2593         float a2 = a*a;
2594         float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
2595         return a2 / (M_PI * t*t);
2596 }
2597
2598 float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
2599 {
2600         return 1.0 / (M_PI * ax*ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH*NdotH));
2601 }
2602
2603 float smithG_GGX(float NdotV, float alphaG)
2604 {
2605         float a = alphaG*alphaG;
2606         float b = NdotV*NdotV;
2607         return 1.0 / (NdotV + sqrt(a + b - a * b));
2608 }
2609
2610 vec3 rotate_vector(vec3 p, vec3 n, float theta) {
2611         return (
2612                    p * cos(theta) + cross(n, p) *
2613                    sin(theta) + n * dot(p, n) *
2614                    (1.0 - cos(theta))
2615                );
2616 }
2617
2618 void prepare_tangent(
2619         float anisotropic, float anisotropic_rotation, float roughness, vec3 N, vec3 T,
2620         out vec3 X, out vec3 Y, out float ax, out float ay)
2621 {
2622         /* rotate tangent */
2623         if (anisotropic_rotation != 0.0) {
2624                 T = rotate_vector(T, N, anisotropic_rotation * 2.0 * M_PI);
2625         }
2626
2627         Y = normalize(cross(T, N));
2628
2629         float aspect = sqrt(1.0 - anisotropic * 0.9);
2630         float a = sqr(roughness);
2631         ax = max(0.001, a / aspect);
2632         ay = max(0.001, a * aspect);
2633 }
2634
2635 void convert_metallic_to_specular(vec3 basecol, float metallic, float specular_fac, out vec3 diffuse, out vec3 f0)
2636 {
2637         vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
2638         diffuse = mix(basecol, vec3(0.0), metallic);
2639         f0 = mix(dielectric, basecol, metallic);
2640 }
2641
2642 void convert_metallic_to_specular_tinted(
2643         vec3 basecol, float metallic, float specular_fac, float specular_tint,
2644         out vec3 diffuse, out vec3 f0)
2645 {
2646         vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
2647         float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
2648         vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */
2649         f0 = mix(dielectric * mix(vec3(1.0), tint, specular_tint), basecol, metallic);
2650         diffuse = mix(basecol, vec3(0.0), metallic);
2651 }
2652
2653 /*********** NEW SHADER NODES ***************/
2654
2655 #define NUM_LIGHTS 3
2656
2657 struct glLight {
2658         vec4 position;
2659         vec4 diffuse;
2660         vec4 specular;
2661         vec4 halfVector;
2662 };
2663
2664 layout(std140) uniform lightSource {
2665         glLight glLightSource[NUM_LIGHTS];
2666 };
2667
2668 #ifndef VOLUMETRICS
2669 /* bsdfs */
2670 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
2671 {
2672 #ifdef EEVEE_ENGINE
2673         vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
2674         vec3 vN = normalize(mat3(ViewMatrix) * N);
2675         result = CLOSURE_DEFAULT;
2676         result.radiance = L * color.rgb;
2677         result.ssr_normal = normal_encode(vN, viewCameraVec);
2678 #else
2679         /* ambient light */
2680         vec3 L = vec3(0.2);
2681
2682         /* directional lights */
2683         for (int i = 0; i < NUM_LIGHTS; i++) {
2684                 vec3 light_position = glLightSource[i].position.xyz;
2685                 vec3 light_diffuse = glLightSource[i].diffuse.rgb;
2686
2687                 float bsdf = max(dot(N, light_position), 0.0);
2688                 L += light_diffuse * bsdf;
2689         }
2690
2691         result = Closure(L * color.rgb, 1.0);
2692 #endif
2693 }
2694
2695 void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
2696 {
2697 #ifdef EEVEE_ENGINE
2698         vec3 ssr_spec;
2699         roughness = sqrt(roughness);
2700         vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0, int(ssr_id), ssr_spec);
2701         vec3 vN = normalize(mat3(ViewMatrix) * N);
2702         result = CLOSURE_DEFAULT;
2703         result.radiance = L * color.rgb;
2704         result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
2705         result.ssr_normal = normal_encode(vN, viewCameraVec);
2706         result.ssr_id = int(ssr_id);
2707 #else
2708         /* ambient light */
2709         vec3 L = vec3(0.2);
2710
2711         direction_transform_m4v3(N, ViewMatrix, N);
2712
2713         /* directional lights */
2714         for (int i = 0; i < NUM_LIGHTS; i++) {
2715                 vec3 light_position = glLightSource[i].position.xyz;
2716                 vec3 H = glLightSource[i].halfVector.xyz;
2717                 vec3 light_diffuse = glLightSource[i].diffuse.rgb;
2718                 vec3 light_specular = glLightSource[i].specular.rgb;
2719
2720                 /* we mix in some diffuse so low roughness still shows up */
2721                 float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness);
2722                 bsdf += 0.5 * max(dot(N, light_position), 0.0);
2723                 L += light_specular * bsdf;
2724         }
2725
2726         result = Closure(L * color.rgb, 1.0);
2727 #endif
2728 }
2729
2730 void node_bsdf_anisotropic(
2731         vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
2732         out Closure result)
2733 {
2734         node_bsdf_diffuse(color, 0.0, N, result);
2735 }
2736
2737 void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result)
2738 {
2739 #ifdef EEVEE_ENGINE
2740         vec3 ssr_spec;
2741         roughness = sqrt(roughness);
2742         vec3 L = eevee_surface_glass(N, (refractionDepth > 0.0) ? color.rgb : vec3(1.0), roughness, ior, int(ssr_id), ssr_spec);
2743         vec3 vN = normalize(mat3(ViewMatrix) * N);
2744         result = CLOSURE_DEFAULT;
2745         result.radiance = L * color.rgb;
2746         result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
2747         result.ssr_normal = normal_encode(vN, viewCameraVec);
2748         result.ssr_id = int(ssr_id);
2749 #else
2750         node_bsdf_diffuse(color, 0.0, N, result);
2751 #endif
2752 }
2753
2754 void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
2755 {
2756         node_bsdf_diffuse(color, 0.0, N, result);
2757 }
2758
2759 #ifndef EEVEE_ENGINE
2760 void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
2761         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
2762         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
2763 {
2764         vec3 X, Y;
2765         float ax, ay;
2766         prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, Y, ax, ay);
2767
2768         /* ambient light */
2769         // TODO: set ambient light to an appropriate value
2770         vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic));
2771
2772         float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0;
2773
2774         /* set the viewing vector */
2775         vec3 V = (ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0);
2776
2777         /* fresnel normalization parameters */
2778         float F0 = fresnel_dielectric_0(eta);
2779         float F0_norm = 1.0 / (1.0 - F0);
2780
2781         /* directional lights */
2782         for (int i = 0; i < NUM_LIGHTS; i++) {
2783                 vec3 light_position_world = glLightSource[i].position.xyz;
2784                 vec3 light_position = normalize(light_position_world);
2785
2786                 vec3 H = normalize(light_position + V);
2787
2788                 vec3 light_diffuse = glLightSource[i].diffuse.rgb;
2789                 vec3 light_specular = glLightSource[i].specular.rgb;
2790
2791                 float NdotL = dot(N, light_position);
2792                 float NdotV = dot(N, V);
2793                 float LdotH = dot(light_position, H);
2794
2795                 vec3 diffuse_and_specular_bsdf = vec3(0.0);
2796                 if (NdotL >= 0.0 && NdotV >= 0.0) {
2797                         float NdotH = dot(N, H);
2798
2799                         float Cdlum = dot(base_color.rgb, vec3(0.3, 0.6, 0.1)); // luminance approx.
2800
2801                         vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat
2802                         vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic);
2803                         vec3 Csheen = mix(vec3(1.0), Ctint, sheen_tint);
2804
2805                         // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
2806                         // and mix in diffuse retro-reflection based on roughness
2807
2808                         float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
2809                         float Fd90 = 0.5 + 2.0 * LdotH*LdotH * roughness;
2810                         float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV);
2811
2812                         // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
2813                         // 1.25 scale is used to (roughly) preserve albedo
2814                         // Fss90 used to "flatten" retroreflection based on roughness
2815                         float Fss90 = LdotH*LdotH * roughness;
2816                         float Fss = mix(1.0, Fss90, FL) * mix(1.0, Fss90, FV);
2817                         float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5);
2818
2819                         // specular
2820                         float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay); //GTR2(NdotH, a);
2821                         float FH = (fresnel_dielectric_cos(LdotH, eta) - F0) * F0_norm;
2822                         vec3 Fs = mix(Cspec0, vec3(1.0), FH);
2823                         float roughg = sqr(roughness * 0.5 + 0.5);
2824                         float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);
2825
2826                         // sheen
2827                         vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen;
2828
2829                         vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse;
2830                         vec3 specular_bsdf = Gs * Fs * Ds * light_specular;
2831                         diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf;
2832                 }
2833                 diffuse_and_specular_bsdf *= max(NdotL, 0.0);
2834
2835                 float CNdotL = dot(CN, light_position);
2836                 float CNdotV = dot(CN, V);
2837
2838                 vec3 clearcoat_bsdf = vec3(0.0);
2839                 if (CNdotL >= 0.0 && CNdotV >= 0.0 && clearcoat > 0.0) {
2840                         float CNdotH = dot(CN, H);
2841                         //float FH = schlick_fresnel(LdotH);
2842
2843                         // clearcoat (ior = 1.5 -> F0 = 0.04)
2844                         float Dr = GTR1(CNdotH, sqr(clearcoat_roughness));
2845                         float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH);
2846                         float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25);
2847
2848                         clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular;
2849                 }
2850                 clearcoat_bsdf *= max(CNdotL, 0.0);
2851
2852                 L += diffuse_and_specular_bsdf + clearcoat_bsdf;
2853         }
2854
2855         result = Closure(L, 1.0);
2856 }
2857 #endif
2858
2859 void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
2860         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
2861         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, out Closure result)
2862 {
2863 #ifdef EEVEE_ENGINE
2864         vec3 diffuse, f0, ssr_spec;
2865         convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
2866
2867 #ifdef USE_SSS
2868         diffuse = mix(diffuse, vec3(0.0), subsurface);
2869 #else
2870         diffuse = mix(diffuse, subsurface_color.rgb, subsurface);
2871 #endif
2872
2873         vec3 L = eevee_surface_lit(N, diffuse, f0, roughness, 1.0, int(ssr_id), ssr_spec);
2874         vec3 vN = normalize(mat3(ViewMatrix) * N);
2875         result = CLOSURE_DEFAULT;
2876         result.radiance = L;
2877         result.ssr_data = vec4(ssr_spec, roughness);
2878         result.ssr_normal = normal_encode(vN, viewCameraVec);
2879         result.ssr_id = int(ssr_id);
2880
2881 #ifdef USE_SSS
2882         /* OPTI : Make irradiance computation shared with the diffuse. */
2883         result.sss_data.rgb = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
2884         result.sss_data.rgb += eevee_surface_translucent_lit(N, vec3(1.0), 1.0);
2885         result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface);
2886         result.sss_data.a = 1.0; /* TODO Find a parametrization */
2887 #endif
2888 #else
2889         node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
2890                 specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
2891                 clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, result);
2892 #endif
2893 }
2894
2895 void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
2896         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
2897         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
2898         float sss_id, out Closure result)
2899 {
2900 #ifdef EEVEE_ENGINE
2901         if (clearcoat == 0.0) {
2902                 node_bsdf_principled_simple(
2903                         base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
2904                         specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
2905                         clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, ssr_id, result);
2906                 return;
2907         }
2908
2909         vec3 diffuse, f0, ssr_spec;
2910         convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
2911
2912         clearcoat *= 0.25;
2913 #if 0 /* Wait until temporal AA (aka. denoising) */
2914
2915         vec3 X, Y;
2916         float ax, ay;
2917         prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, Y, ax, ay);
2918
2919         /* Distribute N in anisotropy direction. */
2920         vec4 surface_color = vec4(0.0);
2921         for (float i = 0.0; i < 5.0; ++i) {
2922                 vec4 rand = texture(utilTex, vec3((gl_FragCoord.xy + i) / LUT_SIZE, 2.0));
2923
2924                 float tmp = sqrt( rand.x / (1.0 - rand.x) );
2925                 float x = (ax > ay ? ax : 0.0) * tmp * rand.z;
2926                 float y = (ay > ax ? ay : 0.0) * tmp * rand.w;
2927                 vec3 Ht = normalize(vec3(x, y, 1.0));
2928                 N = tangent_to_world(Ht, N, Y, X);
2929
2930                 if (dot(N, cameraVec) > 0) {
2931                         surface_color.rgb += eevee_surface_clearcoat_lit(N, diffuse, f0, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 1.0, ssr_id);
2932                         surface_color.a += 1.0;
2933                 }
2934         }
2935         result = Closure(surface_color.rgb / surface_color.a, 1.0);
2936 #else
2937
2938 #ifdef USE_SSS
2939         diffuse = mix(diffuse, vec3(0.0), subsurface);
2940 #else
2941         diffuse = mix(diffuse, subsurface_color.rgb, subsurface);
2942 #endif
2943
2944         vec3 L_trans = (transmission <= 0.0) ? vec3(0.0) : eevee_surface_glass(N, base_color.rgb * ((refractionDepth > 0.0) ? base_color.rgb : vec3(1.0)), roughness, ior, REFRACT_CLOSURE_FLAG, ssr_spec);
2945         vec3 L = eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, int(ssr_id), ssr_spec);
2946         L = mix(L, L_trans, transmission);
2947         vec3 vN = normalize(mat3(ViewMatrix) * N);
2948         result = CLOSURE_DEFAULT;
2949         result.radiance = L;
2950         result.ssr_data = vec4(ssr_spec, roughness);
2951         result.ssr_normal = normal_encode(vN, viewCameraVec);
2952         result.ssr_id = int(ssr_id);
2953
2954 #ifdef USE_SSS
2955         /* OPTI : Make irradiance computation shared with the diffuse. */
2956         result.sss_data.rgb = eevee_surface_translucent_lit(N, subsurface_color.rgb, 1.0);
2957         result.sss_data.rgb += eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
2958         result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface);
2959         result.sss_data.a = 1.0; /* TODO Find a parametrization */
2960 #endif
2961
2962 #endif
2963
2964 #else
2965         node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
2966                 specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
2967                 clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, result);
2968 #endif
2969 }
2970
2971 void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
2972 {
2973         node_bsdf_diffuse(color, 0.0, -N, result);
2974 }
2975
2976 void node_bsdf_transparent(vec4 color, out Closure result)
2977 {
2978         /* this isn't right */
2979         result = CLOSURE_DEFAULT;
2980         result.radiance = vec3(0.0);
2981         result.opacity = 0.0;
2982 #ifdef EEVEE_ENGINE
2983         result.ssr_id = TRANSPARENT_CLOSURE_FLAG;
2984 #endif
2985 }
2986
2987 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
2988 {
2989         node_bsdf_diffuse(color, 0.0, N, result);
2990 }
2991
2992 void node_subsurface_scattering(
2993         vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
2994         out Closure result)
2995 {
2996 #if defined(EEVEE_ENGINE) && defined(USE_SSS)
2997         vec3 vN = normalize(mat3(ViewMatrix) * N);
2998         result = CLOSURE_DEFAULT;
2999         result.ssr_data = vec4(0.0);
3000         result.ssr_normal = normal_encode(vN, viewCameraVec);
3001         result.ssr_id = -1;
3002         result.sss_data.rgb = eevee_surface_translucent_lit(N, color.rgb, scale);
3003         result.sss_data.rgb += eevee_surface_diffuse_lit(N, color.rgb, 1.0);
3004         result.sss_data.a = scale;
3005 #else
3006         node_bsdf_diffuse(color, 0.0, N, result);
3007 #endif
3008 }
3009
3010 void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
3011 {
3012 #ifdef EEVEE_ENGINE
3013         color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
3014         roughness = sqrt(roughness);
3015         vec3 L = eevee_surface_refraction(N, vec3(1.0), roughness, ior);
3016         result = CLOSURE_DEFAULT;
3017         result.radiance = L * color.rgb;
3018         result.ssr_id = REFRACT_CLOSURE_FLAG;
3019 #else
3020         node_bsdf_diffuse(color, 0.0, N, result);
3021 #endif /* EEVEE_ENGINE */
3022 }
3023
3024 /* Unsupported for now */
3025 #ifndef EEVEE_ENGINE
3026 void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result)
3027 {
3028         result = Closure(color.rgb, color.a);
3029 }
3030
3031 void node_ambient_occlusion(vec4 color, out Closure result)
3032 {
3033         result = Closure(color.rgb, color.a);
3034 }
3035 #endif /* EEVEE_ENGINE */
3036
3037 #endif /* VOLUMETRICS */
3038
3039 /* emission */
3040
3041 void node_emission(vec4 color, float strength, vec3 N, out Closure result)
3042 {
3043 #ifndef VOLUMETRICS
3044         color *= strength;
3045 #ifdef EEVEE_ENGINE
3046         result = CLOSURE_DEFAULT;
3047         result.radiance = color.rgb;
3048         result.opacity = color.a;
3049         result.ssr_normal = normal_encode(N, viewCameraVec);
3050 #else
3051         result = Closure(color.rgb, color.a);
3052 #endif
3053 #else
3054         result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
3055 #endif
3056 }
3057
3058 /* background */
3059
3060 void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
3061 {
3062         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
3063         vec4 co_homogenous = (ProjectionMatrixInverse * v);
3064
3065         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
3066 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
3067         worldvec = (ViewMatrixInverse * co).xyz;
3068 #else
3069         worldvec = (ModelViewMatrixInverse * co).xyz;
3070 #endif
3071 }
3072
3073 void node_background(vec4 color, float strength, out Closure result)
3074 {
3075 #ifndef VOLUMETRICS
3076         color *= strength;
3077 #ifdef EEVEE_ENGINE
3078         result = CLOSURE_DEFAULT;
3079         result.radiance = color.rgb;
3080         result.opacity = color.a;
3081 #else
3082         result = Closure(color.rgb, color.a);
3083 #endif
3084 #else
3085         result = CLOSURE_DEFAULT;
3086 #endif
3087 }
3088
3089 /* volumes */
3090
3091 void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result)
3092 {
3093 #ifdef VOLUMETRICS
3094         result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy);
3095 #else
3096         result = CLOSURE_DEFAULT;
3097 #endif
3098 }
3099
3100 void node_volume_absorption(vec4 color, float density, out Closure result)
3101 {
3102 #ifdef VOLUMETRICS
3103         result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0);
3104 #else
3105         result = CLOSURE_DEFAULT;
3106 #endif
3107 }
3108
3109 /* closures */
3110
3111 void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
3112 {
3113         shader = closure_mix(shader1, shader2, fac);
3114 }
3115
3116 void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
3117 {
3118         shader = closure_add(shader1, shader2);
3119 }
3120
3121 /* fresnel */
3122
3123 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
3124 {
3125         /* handle perspective/orthographic */
3126         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3127
3128         float eta = max(ior, 0.00001);
3129         result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
3130 }
3131
3132 /* layer_weight */
3133
3134 void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
3135 {
3136         /* fresnel */
3137         float eta = max(1.0 - blend, 0.00001);
3138         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3139
3140         fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
3141
3142         /* facing */
3143         facing = abs(dot(I_view, N));
3144         if (blend != 0.5) {
3145                 blend = clamp(blend, 0.0, 0.99999);
3146                 blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
3147                 facing = pow(facing, blend);
3148         }
3149         facing = 1.0 - facing;
3150 }
3151
3152 /* gamma */
3153
3154 void node_gamma(vec4 col, float gamma, out vec4 outcol)
3155 {
3156         outcol = col;
3157
3158         if (col.r > 0.0)
3159                 outcol.r = compatible_pow(col.r, gamma);
3160         if (col.g > 0.0)
3161                 outcol.g = compatible_pow(col.g, gamma);
3162         if (col.b > 0.0)
3163                 outcol.b = compatible_pow(col.b, gamma);
3164 }
3165
3166 /* geometry */
3167
3168 void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3169 {
3170 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3171         vec3 cos = volumeObjectLocalCoord;
3172 #else
3173         vec3 cos = vec3(0.0);
3174 #endif
3175         outvec = texture(tex, cos).aaa;
3176         outcol = vec4(outvec, 1.0);
3177         outf = dot(vec3(1.0 / 3.0), outvec);
3178 }
3179
3180 void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3181 {
3182 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3183         vec3 cos = volumeObjectLocalCoord;
3184 #else
3185         vec3 cos = vec3(0.0);
3186 #endif
3187         outvec = texture(tex, cos).rgb;
3188         outcol = vec4(outvec, 1.0);
3189         outf = dot(vec3(1.0 / 3.0), outvec);
3190 }
3191
3192 void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3193 {
3194 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3195         vec3 cos = volumeObjectLocalCoord;
3196 #else
3197         vec3 cos = vec3(0.0);
3198 #endif
3199         outvec = texture(tex, cos).rrr;
3200         outcol = vec4(outvec, 1.0);
3201         outf = dot(vec3(1.0 / 3.0), outvec);
3202 }
3203
3204 void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
3205 {
3206         outcol = vec4(attr, 1.0);
3207         outvec = attr;
3208         outf =  dot(vec3(1.0 / 3.0), attr);
3209 }
3210
3211 void node_uvmap(vec3 attr_uv, out vec3 outvec)
3212 {
3213         outvec = attr_uv;
3214 }
3215
3216 void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
3217 {
3218         orco_out = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5);
3219 }
3220
3221 void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
3222 {
3223         orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5);
3224 }
3225
3226 void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
3227 {
3228         orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 0.0);
3229 }
3230
3231 void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
3232 {
3233         tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz;
3234 }
3235
3236 void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
3237 {
3238         N = (toworld * vec4(N, 0.0)).xyz;
3239         T = (objmat * vec4(orco, 0.0)).xyz;
3240         T = cross(N, normalize(cross(T, N)));
3241 }
3242
3243 void node_geometry(
3244         vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld,
3245         out vec3 position, out vec3 normal, out vec3 tangent,
3246         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
3247         out float backfacing, out float pointiness)
3248 {
3249 #ifdef EEVEE_ENGINE
3250         position = worldPosition;
3251 #else
3252         position = (toworld * vec4(I, 1.0)).xyz;
3253 #endif
3254         normal = (toworld * vec4(N, 0.0)).xyz;
3255         tangent_orco_z(orco, orco);
3256         node_tangent(N, orco, objmat, toworld, tangent);
3257         true_normal = normal;
3258
3259         /* handle perspective/orthographic */
3260         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3261         incoming = -(toworld * vec4(I_view, 0.0)).xyz;
3262
3263         parametric = vec3(0.0);
3264         backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
3265         pointiness = 0.5;
3266 }
3267
3268 void node_tex_coord(
3269         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
3270         vec3 attr_orco, vec3 attr_uv,
3271         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
3272         out vec3 camera, out vec3 window, out vec3 reflection)
3273 {
3274         generated = attr_orco;
3275         normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
3276         uv = attr_uv;
3277         object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
3278         camera = vec3(I.xy, -I.z);
3279         vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
3280         window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
3281
3282         vec3 shade_I;
3283         shade_view(I, shade_I);
3284         vec3 view_reflection = reflect(shade_I, normalize(N));
3285         reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
3286 }
3287
3288 void node_tex_coord_background(
3289         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
3290         vec3 attr_orco, vec3 attr_uv,
3291         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
3292         out vec3 camera, out vec3 window, out vec3 reflection)
3293 {
3294         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
3295         vec4 co_homogenous = (ProjectionMatrixInverse * v);
3296
3297         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
3298
3299         co = normalize(co);
3300
3301 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
3302         vec3 coords = (ViewMatrixInverse * co).xyz;
3303 #else
3304         vec3 coords = (ModelViewMatrixInverse * co).xyz;
3305 #endif
3306
3307         generated = coords;
3308         normal = -coords;
3309         uv = vec3(attr_uv.xy, 0.0);
3310         object = coords;
3311
3312         camera = vec3(co.xy, -co.z);
3313         window = (ProjectionMatrix[3][3] == 0.0) ?
3314                  vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
3315                  vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
3316
3317         reflection = -coords;
3318 }
3319
3320 #if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER))
3321 #define node_tex_coord node_tex_coord_background
3322 #endif
3323
3324 /* textures */
3325
3326 float calc_gradient(vec3 p, int gradient_type)
3327 {
3328         float x, y, z;
3329         x = p.x;
3330         y = p.y;
3331         z = p.z;
3332         if (gradient_type == 0) {  /* linear */
3333                 return x;
3334         }
3335         else if (gradient_type == 1) {  /* quadratic */
3336                 float r = max(x, 0.0);
3337                 return r * r;
3338         }
3339         else if (gradient_type == 2) {  /* easing */
3340                 float r = min(max(x, 0.0), 1.0);
3341                 float t = r * r;
3342                 return (3.0 * t - 2.0 * t * r);
3343         }
3344         else if (gradient_type == 3) {  /* diagonal */
3345                 return (x + y) * 0.5;
3346         }
3347         else if (gradient_type == 4) {  /* radial */
3348                 return atan(y, x) / (M_PI * 2) + 0.5;
3349         }
3350         else {
3351                 /* Bias a little bit for the case where p is a unit length vector,
3352                  * to get exactly zero instead of a small random value depending
3353                  * on float precision. */
3354                 float r = max(0.999999 - sqrt(x * x + y * y + z * z), 0.0);
3355                 if (gradient_type == 5) {  /* quadratic sphere */
3356                         return r * r;
3357                 }
3358                 else if (gradient_type == 6) {  /* sphere */
3359                         return r;
3360                 }
3361         }
3362         return 0.0;
3363 }
3364
3365 void node_tex_gradient(vec3 co, float gradient_type, out vec4 color, out float fac)
3366 {
3367         float f = calc_gradient(co, int(gradient_type));
3368         f = clamp(f, 0.0, 1.0);
3369
3370         color = vec4(f, f, f, 1.0);
3371         fac = f;
3372 }
3373
3374 void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
3375 {
3376         vec3 p = co * scale;
3377
3378         /* Prevent precision issues on unit coordinates. */
3379         p.x = (p.x + 0.000001) * 0.999999;
3380         p.y = (p.y + 0.000001) * 0.999999;
3381         p.z = (p.z + 0.000001) * 0.999999;
3382
3383         int xi = int(abs(floor(p.x)));
3384         int yi = int(abs(floor(p.y)));
3385         int zi = int(abs(floor(p.z)));
3386
3387         bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2)));
3388
3389         color = check ? color1 : color2;
3390         fac = check ? 1.0 : 0.0;
3391 }
3392
3393 vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
3394                         float brick_width, float row_height,
3395                         float offset_amount, int offset_frequency,
3396                         float squash_amount, int squash_frequency)
3397 {
3398         int bricknum, rownum;
3399         float offset = 0.0;
3400         float x, y;
3401
3402         rownum = floor_to_int(p.y / row_height);
3403
3404         if (offset_frequency != 0 && squash_frequency != 0) {
3405                 brick_width *= (rownum % squash_frequency != 0) ? 1.0 : squash_amount; /* squash */
3406                 offset = (rownum % offset_frequency != 0) ? 0.0 : (brick_width * offset_amount); /* offset */
3407         }
3408
3409         bricknum = floor_to_int((p.x + offset) / brick_width);
3410
3411         x = (p.x + offset) - brick_width * bricknum;
3412         y = p.y - row_height * rownum;
3413
3414         float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0);
3415
3416         float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
3417         if (min_dist >= mortar_size) {
3418                 return vec2(tint, 0.0);
3419         }
3420         else if (mortar_smooth == 0.0) {
3421                 return vec2(tint, 1.0);
3422         }
3423         else {
3424                 min_dist = 1.0 - min_dist/mortar_size;
3425                 return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
3426         }
3427 }
3428
3429 void node_tex_brick(vec3 co,
3430                     vec4 color1, vec4 color2,
3431                     vec4 mortar, float scale,
3432                     float mortar_size, float mortar_smooth, float bias,
3433                     float brick_width, float row_height,
3434                     float offset_amount, float offset_frequency,
3435                     float squash_amount, float squash_frequency,
3436                     out vec4 color, out float fac)
3437 {
3438         vec2 f2 = calc_brick_texture(co * scale,
3439                                      mortar_size, mortar_smooth, bias,
3440                                      brick_width, row_height,
3441                                      offset_amount, int(offset_frequency),
3442                                      squash_amount, int(squash_frequency));
3443         float tint = f2.x;
3444         float f = f2.y;
3445         if (f != 1.0) {
3446                 float facm = 1.0 - tint;
3447                 color1 = facm * color1 + tint * color2;
3448         }
3449         color = mix(color1, mortar, f);
3450         fac = f;
3451 }
3452
3453 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
3454 {
3455         color = vec4(1.0);
3456         fac = 1.0;
3457 }
3458
3459 void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
3460 {
3461         vec3 nco = normalize(co);
3462         float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
3463         float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
3464
3465         /* Fix pole bleeding */
3466         float half_width = 0.5 / float(textureSize(ima, 0).x);
3467         v = clamp(v, half_width, 1.0 - half_width);
3468
3469         /* Fix u = 0 seam */
3470         /* This is caused by texture filtering, since uv don't have smooth derivatives
3471          * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
3472          * texels. So we force the highest mipmap and don't do anisotropic filtering. */
3473         color = textureLod(ima, vec2(u, v), 0.0);
3474 }
3475
3476 void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
3477 {
3478         vec3 nco = normalize(co);
3479
3480         nco.y -= 1.0;
3481
3482         float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
3483         if (div > 0.0)
3484                 nco /= div;
3485
3486         float u = 0.5 * (nco.x + 1.0);
3487         float v = 0.5 * (nco.z + 1.0);
3488
3489         color = texture(ima, vec2(u, v));