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, 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 vN = normalize(mat3(ViewMatrix) * N);
2674         result = CLOSURE_DEFAULT;
2675         result.ssr_normal = normal_encode(vN, viewCameraVec);
2676         eevee_closure_diffuse(N, color.rgb, 1.0, result.radiance);
2677         result.radiance *= color.rgb;
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 out_spec, ssr_spec;
2699         roughness = sqrt(roughness);
2700         eevee_closure_glossy(N, vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
2701         vec3 vN = normalize(mat3(ViewMatrix) * N);
2702         result = CLOSURE_DEFAULT;
2703         result.radiance = out_spec * 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 out_spec, out_refr, ssr_spec;
2741         roughness = sqrt(roughness);
2742         vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb : color.rgb; /* Simulate 2 transmission event */
2743         eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
2744         out_refr *= refr_color;
2745         out_spec *= color.rgb;
2746         float fresnel = F_eta(ior, dot(N, cameraVec));
2747         vec3 vN = normalize(mat3(ViewMatrix) * N);
2748         result = CLOSURE_DEFAULT;
2749         result.radiance = mix(out_refr, out_spec, fresnel);
2750         result.ssr_data = vec4(ssr_spec * color.rgb * fresnel, roughness);
2751         result.ssr_normal = normal_encode(vN, viewCameraVec);
2752         result.ssr_id = int(ssr_id);
2753 #else
2754         node_bsdf_diffuse(color, 0.0, N, result);
2755 #endif
2756 }
2757
2758 void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
2759 {
2760         node_bsdf_diffuse(color, 0.0, N, result);
2761 }
2762
2763 #ifndef EEVEE_ENGINE
2764 void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
2765         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
2766         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
2767 {
2768         vec3 X, Y;
2769         float ax, ay;
2770         prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, Y, ax, ay);
2771
2772         /* ambient light */
2773         // TODO: set ambient light to an appropriate value
2774         vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic));
2775
2776         float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0;
2777
2778         /* set the viewing vector */
2779         vec3 V = (ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0);
2780
2781         /* fresnel normalization parameters */
2782         float F0 = fresnel_dielectric_0(eta);
2783         float F0_norm = 1.0 / (1.0 - F0);
2784
2785         /* directional lights */
2786         for (int i = 0; i < NUM_LIGHTS; i++) {
2787                 vec3 light_position_world = glLightSource[i].position.xyz;
2788                 vec3 light_position = normalize(light_position_world);
2789
2790                 vec3 H = normalize(light_position + V);
2791
2792                 vec3 light_diffuse = glLightSource[i].diffuse.rgb;
2793                 vec3 light_specular = glLightSource[i].specular.rgb;
2794
2795                 float NdotL = dot(N, light_position);
2796                 float NdotV = dot(N, V);
2797                 float LdotH = dot(light_position, H);
2798
2799                 vec3 diffuse_and_specular_bsdf = vec3(0.0);
2800                 if (NdotL >= 0.0 && NdotV >= 0.0) {
2801                         float NdotH = dot(N, H);
2802
2803                         float Cdlum = dot(base_color.rgb, vec3(0.3, 0.6, 0.1)); // luminance approx.
2804
2805                         vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat
2806                         vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic);
2807                         vec3 Csheen = mix(vec3(1.0), Ctint, sheen_tint);
2808
2809                         // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
2810                         // and mix in diffuse retro-reflection based on roughness
2811
2812                         float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
2813                         float Fd90 = 0.5 + 2.0 * LdotH*LdotH * roughness;
2814                         float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV);
2815
2816                         // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
2817                         // 1.25 scale is used to (roughly) preserve albedo
2818                         // Fss90 used to "flatten" retroreflection based on roughness
2819                         float Fss90 = LdotH*LdotH * roughness;
2820                         float Fss = mix(1.0, Fss90, FL) * mix(1.0, Fss90, FV);
2821                         float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5);
2822
2823                         // specular
2824                         float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay); //GTR2(NdotH, a);
2825                         float FH = (fresnel_dielectric_cos(LdotH, eta) - F0) * F0_norm;
2826                         vec3 Fs = mix(Cspec0, vec3(1.0), FH);
2827                         float roughg = sqr(roughness * 0.5 + 0.5);
2828                         float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);
2829
2830                         // sheen
2831                         vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen;
2832
2833                         vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse;
2834                         vec3 specular_bsdf = Gs * Fs * Ds * light_specular;
2835                         diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf;
2836                 }
2837                 diffuse_and_specular_bsdf *= max(NdotL, 0.0);
2838
2839                 float CNdotL = dot(CN, light_position);
2840                 float CNdotV = dot(CN, V);
2841
2842                 vec3 clearcoat_bsdf = vec3(0.0);
2843                 if (CNdotL >= 0.0 && CNdotV >= 0.0 && clearcoat > 0.0) {
2844                         float CNdotH = dot(CN, H);
2845                         //float FH = schlick_fresnel(LdotH);
2846
2847                         // clearcoat (ior = 1.5 -> F0 = 0.04)
2848                         float Dr = GTR1(CNdotH, sqr(clearcoat_roughness));
2849                         float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH);
2850                         float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25);
2851
2852                         clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular;
2853                 }
2854                 clearcoat_bsdf *= max(CNdotL, 0.0);
2855
2856                 L += diffuse_and_specular_bsdf + clearcoat_bsdf;
2857         }
2858
2859         result = Closure(L, 1.0);
2860 }
2861 #endif
2862
2863 void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
2864         float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
2865         float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id,
2866         float sss_id, vec3 sss_scale, out Closure result)
2867 {
2868 #ifdef EEVEE_ENGINE
2869         metallic = saturate(metallic);
2870         transmission = saturate(transmission);
2871
2872         vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec;
2873         convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
2874
2875         transmission *= 1.0 - metallic;
2876         subsurface *= 1.0 - metallic;
2877
2878         clearcoat *= 0.25;
2879         clearcoat *= 1.0 - transmission;
2880
2881 #ifdef USE_SSS
2882         diffuse = mix(diffuse, vec3(0.0), subsurface);
2883 #else
2884         diffuse = mix(diffuse, subsurface_color.rgb, subsurface);
2885 #endif
2886         f0 = mix(f0, vec3(1.0), transmission);
2887
2888         float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0));
2889         eevee_closure_principled(N, diffuse, f0, int(ssr_id), roughness,
2890                                  CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior,
2891                                  out_diff, out_trans, out_spec, out_refr, ssr_spec);
2892
2893         vec3 refr_color = base_color.rgb;
2894         refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */
2895
2896         float fresnel = F_eta(ior, dot(N, cameraVec));
2897         vec3 refr_spec_color = base_color.rgb * fresnel;
2898         /* This bit maybe innacurate. */
2899         out_refr = out_refr * refr_color * (1.0 - fresnel) + out_spec * refr_spec_color;
2900
2901         ssr_spec = mix(ssr_spec, refr_spec_color, transmission);
2902
2903         vec3 vN = normalize(mat3(ViewMatrix) * N);
2904         result = CLOSURE_DEFAULT;
2905         result.radiance = out_spec + out_diff * diffuse;
2906         result.radiance = mix(result.radiance, out_refr, transmission);
2907         result.ssr_data = vec4(ssr_spec, roughness);
2908         result.ssr_normal = normal_encode(vN, viewCameraVec);
2909         result.ssr_id = int(ssr_id);
2910 #ifdef USE_SSS
2911         result.sss_data.a = sss_scalef;
2912         result.sss_data.rgb = out_diff + out_trans;
2913 #ifdef USE_SSS_ALBEDO
2914         result.sss_albedo.rgb = mix(vec3(0.0), subsurface_color.rgb, subsurface);
2915 #else
2916         result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface);
2917 #endif
2918         result.sss_data.rgb *= (1.0 - transmission);
2919 #endif
2920
2921 #else
2922         node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
2923                 specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
2924                 clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, result);
2925 #endif
2926 }
2927
2928 void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
2929 {
2930         node_bsdf_diffuse(color, 0.0, -N, result);
2931 }
2932
2933 void node_bsdf_transparent(vec4 color, out Closure result)
2934 {
2935         /* this isn't right */
2936         result = CLOSURE_DEFAULT;
2937         result.radiance = vec3(0.0);
2938         result.opacity = 0.0;
2939 #ifdef EEVEE_ENGINE
2940         result.ssr_id = TRANSPARENT_CLOSURE_FLAG;
2941 #endif
2942 }
2943
2944 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
2945 {
2946         node_bsdf_diffuse(color, 0.0, N, result);
2947 }
2948
2949 void node_subsurface_scattering(
2950         vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
2951         out Closure result)
2952 {
2953 #if defined(EEVEE_ENGINE) && defined(USE_SSS)
2954         vec3 out_diff, out_trans;
2955         vec3 vN = normalize(mat3(ViewMatrix) * N);
2956         result = CLOSURE_DEFAULT;
2957         result.ssr_data = vec4(0.0);
2958         result.ssr_normal = normal_encode(vN, viewCameraVec);
2959         result.ssr_id = -1;
2960         result.sss_data.a = scale;
2961         eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans);
2962         result.sss_data.rgb = out_diff + out_trans;
2963 #ifdef USE_SSS_ALBEDO
2964         /* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */
2965         result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur);
2966         result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur);
2967 #else
2968         result.sss_data.rgb *= color.rgb;
2969 #endif
2970 #else
2971         node_bsdf_diffuse(color, 0.0, N, result);
2972 #endif
2973 }
2974
2975 void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
2976 {
2977 #ifdef EEVEE_ENGINE
2978         vec3 out_refr;
2979         color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
2980         roughness = sqrt(roughness);
2981         eevee_closure_refraction(N, roughness, ior, out_refr);
2982         result = CLOSURE_DEFAULT;
2983         result.radiance = out_refr * color.rgb;
2984         result.ssr_id = REFRACT_CLOSURE_FLAG;
2985 #else
2986         node_bsdf_diffuse(color, 0.0, N, result);
2987 #endif /* EEVEE_ENGINE */
2988 }
2989
2990 /* Unsupported for now */
2991 #ifndef EEVEE_ENGINE
2992 void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result)
2993 {
2994         result = Closure(color.rgb, color.a);
2995 }
2996
2997 void node_ambient_occlusion(vec4 color, out Closure result)
2998 {
2999         result = Closure(color.rgb, color.a);
3000 }
3001 #endif /* EEVEE_ENGINE */
3002
3003 #endif /* VOLUMETRICS */
3004
3005 /* emission */
3006
3007 void node_emission(vec4 color, float strength, vec3 N, out Closure result)
3008 {
3009 #ifndef VOLUMETRICS
3010         color *= strength;
3011 #ifdef EEVEE_ENGINE
3012         result = CLOSURE_DEFAULT;
3013         result.radiance = color.rgb;
3014         result.opacity = color.a;
3015         result.ssr_normal = normal_encode(N, viewCameraVec);
3016 #else
3017         result = Closure(color.rgb, color.a);
3018 #endif
3019 #else
3020         result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
3021 #endif
3022 }
3023
3024 /* background */
3025
3026 void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
3027 {
3028         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
3029         vec4 co_homogenous = (ProjectionMatrixInverse * v);
3030
3031         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
3032 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
3033         worldvec = (ViewMatrixInverse * co).xyz;
3034 #else
3035         worldvec = (ModelViewMatrixInverse * co).xyz;
3036 #endif
3037 }
3038
3039 void node_background(vec4 color, float strength, out Closure result)
3040 {
3041 #ifndef VOLUMETRICS
3042         color *= strength;
3043 #ifdef EEVEE_ENGINE
3044         result = CLOSURE_DEFAULT;
3045         result.radiance = color.rgb;
3046         result.opacity = color.a;
3047 #else
3048         result = Closure(color.rgb, color.a);
3049 #endif
3050 #else
3051         result = CLOSURE_DEFAULT;
3052 #endif
3053 }
3054
3055 /* volumes */
3056
3057 void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result)
3058 {
3059 #ifdef VOLUMETRICS
3060         result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy);
3061 #else
3062         result = CLOSURE_DEFAULT;
3063 #endif
3064 }
3065
3066 void node_volume_absorption(vec4 color, float density, out Closure result)
3067 {
3068 #ifdef VOLUMETRICS
3069         result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0);
3070 #else
3071         result = CLOSURE_DEFAULT;
3072 #endif
3073 }
3074
3075 /* closures */
3076
3077 void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
3078 {
3079         shader = closure_mix(shader1, shader2, fac);
3080 }
3081
3082 void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
3083 {
3084         shader = closure_add(shader1, shader2);
3085 }
3086
3087 /* fresnel */
3088
3089 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
3090 {
3091         /* handle perspective/orthographic */
3092         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3093
3094         float eta = max(ior, 0.00001);
3095         result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
3096 }
3097
3098 /* layer_weight */
3099
3100 void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
3101 {
3102         /* fresnel */
3103         float eta = max(1.0 - blend, 0.00001);
3104         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3105
3106         fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
3107
3108         /* facing */
3109         facing = abs(dot(I_view, N));
3110         if (blend != 0.5) {
3111                 blend = clamp(blend, 0.0, 0.99999);
3112                 blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend);
3113                 facing = pow(facing, blend);
3114         }
3115         facing = 1.0 - facing;
3116 }
3117
3118 /* gamma */
3119
3120 void node_gamma(vec4 col, float gamma, out vec4 outcol)
3121 {
3122         outcol = col;
3123
3124         if (col.r > 0.0)
3125                 outcol.r = compatible_pow(col.r, gamma);
3126         if (col.g > 0.0)
3127                 outcol.g = compatible_pow(col.g, gamma);
3128         if (col.b > 0.0)
3129                 outcol.b = compatible_pow(col.b, gamma);
3130 }
3131
3132 /* geometry */
3133
3134 void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3135 {
3136 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3137         vec3 cos = volumeObjectLocalCoord;
3138 #else
3139         vec3 cos = vec3(0.0);
3140 #endif
3141         outvec = texture(tex, cos).aaa;
3142         outcol = vec4(outvec, 1.0);
3143         outf = dot(vec3(1.0 / 3.0), outvec);
3144 }
3145
3146 void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3147 {
3148 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3149         vec3 cos = volumeObjectLocalCoord;
3150 #else
3151         vec3 cos = vec3(0.0);
3152 #endif
3153         outvec = texture(tex, cos).rgb;
3154         outcol = vec4(outvec, 1.0);
3155         outf = dot(vec3(1.0 / 3.0), outvec);
3156 }
3157
3158 void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
3159 {
3160 #if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
3161         vec3 cos = volumeObjectLocalCoord;
3162 #else
3163         vec3 cos = vec3(0.0);
3164 #endif
3165         outvec = texture(tex, cos).rrr;
3166         outcol = vec4(outvec, 1.0);
3167         outf = dot(vec3(1.0 / 3.0), outvec);
3168 }
3169
3170 void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
3171 {
3172         outcol = vec4(attr, 1.0);
3173         outvec = attr;
3174         outf =  dot(vec3(1.0 / 3.0), attr);
3175 }
3176
3177 void node_uvmap(vec3 attr_uv, out vec3 outvec)
3178 {
3179         outvec = attr_uv;
3180 }
3181
3182 void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
3183 {
3184         orco_out = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5);
3185 }
3186
3187 void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
3188 {
3189         orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5);
3190 }
3191
3192 void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
3193 {
3194         orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 0.0);
3195 }
3196
3197 void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
3198 {
3199         tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz;
3200 }
3201
3202 void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
3203 {
3204         N = (toworld * vec4(N, 0.0)).xyz;
3205         T = (objmat * vec4(orco, 0.0)).xyz;
3206         T = cross(N, normalize(cross(T, N)));
3207 }
3208
3209 void node_geometry(
3210         vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld,
3211         out vec3 position, out vec3 normal, out vec3 tangent,
3212         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
3213         out float backfacing, out float pointiness)
3214 {
3215 #ifdef EEVEE_ENGINE
3216         position = worldPosition;
3217 #else
3218         position = (toworld * vec4(I, 1.0)).xyz;
3219 #endif
3220         normal = (toworld * vec4(N, 0.0)).xyz;
3221         tangent_orco_z(orco, orco);
3222         node_tangent(N, orco, objmat, toworld, tangent);
3223         true_normal = normal;
3224
3225         /* handle perspective/orthographic */
3226         vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
3227         incoming = -(toworld * vec4(I_view, 0.0)).xyz;
3228
3229         parametric = vec3(0.0);
3230         backfacing = (gl_FrontFacing) ? 0.0 : 1.0;
3231         pointiness = 0.5;
3232 }
3233
3234 void node_tex_coord(
3235         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
3236         vec3 attr_orco, vec3 attr_uv,
3237         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
3238         out vec3 camera, out vec3 window, out vec3 reflection)
3239 {
3240         generated = attr_orco;
3241         normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
3242         uv = attr_uv;
3243         object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
3244         camera = vec3(I.xy, -I.z);
3245         vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
3246         window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
3247
3248         vec3 shade_I;
3249         shade_view(I, shade_I);
3250         vec3 view_reflection = reflect(shade_I, normalize(N));
3251         reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
3252 }
3253
3254 void node_tex_coord_background(
3255         vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
3256         vec3 attr_orco, vec3 attr_uv,
3257         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
3258         out vec3 camera, out vec3 window, out vec3 reflection)
3259 {
3260         vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
3261         vec4 co_homogenous = (ProjectionMatrixInverse * v);
3262
3263         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
3264
3265         co = normalize(co);
3266
3267 #if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
3268         vec3 coords = (ViewMatrixInverse * co).xyz;
3269 #else
3270         vec3 coords = (ModelViewMatrixInverse * co).xyz;
3271 #endif
3272
3273         generated = coords;
3274         normal = -coords;
3275         uv = vec3(attr_uv.xy, 0.0);
3276         object = coords;
3277
3278         camera = vec3(co.xy, -co.z);
3279         window = (ProjectionMatrix[3][3] == 0.0) ?
3280                  vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
3281                  vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
3282
3283         reflection = -coords;
3284 }
3285
3286 #if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER))
3287 #define node_tex_coord node_tex_coord_background
3288 #endif
3289
3290 /* textures */
3291
3292 float calc_gradient(vec3 p, int gradient_type)
3293 {
3294         float x, y, z;
3295         x = p.x;
3296         y = p.y;
3297         z = p.z;
3298         if (gradient_type == 0) {  /* linear */
3299                 return x;
3300         }
3301         else if (gradient_type == 1) {  /* quadratic */
3302                 float r = max(x, 0.0);
3303                 return r * r;
3304         }
3305         else if (gradient_type == 2) {  /* easing */
3306                 float r = min(max(x, 0.0), 1.0);
3307                 float t = r * r;
3308                 return (3.0 * t - 2.0 * t * r);
3309         }
3310         else if (gradient_type == 3) {  /* diagonal */
3311                 return (x + y) * 0.5;
3312         }
3313         else if (gradient_type == 4) {  /* radial */
3314                 return atan(y, x) / (M_PI * 2) + 0.5;
3315         }
3316         else {
3317                 /* Bias a little bit for the case where p is a unit length vector,
3318                  * to get exactly zero instead of a small random value depending
3319                  * on float precision. */
3320                 float r = max(0.999999 - sqrt(x * x + y * y + z * z), 0.0);
3321                 if (gradient_type == 5) {  /* quadratic sphere */
3322                         return r * r;
3323                 }
3324                 else if (gradient_type == 6) {  /* sphere */
3325                         return r;
3326                 }
3327         }
3328         return 0.0;
3329 }
3330
3331 void node_tex_gradient(vec3 co, float gradient_type, out vec4 color, out float fac)
3332 {
3333         float f = calc_gradient(co, int(gradient_type));
3334         f = clamp(f, 0.0, 1.0);
3335
3336         color = vec4(f, f, f, 1.0);
3337         fac = f;
3338 }
3339
3340 void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
3341 {
3342         vec3 p = co * scale;
3343
3344         /* Prevent precision issues on unit coordinates. */
3345         p.x = (p.x + 0.000001) * 0.999999;
3346         p.y = (p.y + 0.000001) * 0.999999;
3347         p.z = (p.z + 0.000001) * 0.999999;
3348
3349         int xi = int(abs(floor(p.x)));
3350         int yi = int(abs(floor(p.y)));
3351         int zi = int(abs(floor(p.z)));
3352
3353         bool check = ((mod(xi, 2) == mod(yi, 2)) == bool(mod(zi, 2)));
3354
3355         color = check ? color1 : color2;
3356         fac = check ? 1.0 : 0.0;
3357 }
3358
3359 vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
3360                         float brick_width, float row_height,
3361                         float offset_amount, int offset_frequency,
3362                         float squash_amount, int squash_frequency)
3363 {
3364         int bricknum, rownum;
3365         float offset = 0.0;
3366         float x, y;
3367
3368         rownum = floor_to_int(p.y / row_height);
3369
3370         if (offset_frequency != 0 && squash_frequency != 0) {
3371                 brick_width *= (rownum % squash_frequency != 0) ? 1.0 : squash_amount; /* squash */
3372                 offset = (rownum % offset_frequency != 0) ? 0.0 : (brick_width * offset_amount); /* offset */
3373         }
3374
3375         bricknum = floor_to_int((p.x + offset) / brick_width);
3376
3377         x = (p.x + offset) - brick_width * bricknum;
3378         y = p.y - row_height * rownum;
3379
3380         float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0);
3381
3382         float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
3383         if (min_dist >= mortar_size) {
3384                 return vec2(tint, 0.0);
3385         }
3386         else if (mortar_smooth == 0.0) {
3387                 return vec2(tint, 1.0);
3388         }
3389         else {
3390                 min_dist = 1.0 - min_dist/mortar_size;
3391                 return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
3392         }
3393 }
3394
3395 void node_tex_brick(vec3 co,
3396                     vec4 color1, vec4 color2,
3397                     vec4 mortar, float scale,
3398                     float mortar_size, float mortar_smooth, float bias,
3399                     float brick_width, float row_height,
3400                     float offset_amount, float offset_frequency,
3401                     float squash_amount, float squash_frequency,
3402                     out vec4 color, out float fac)
3403 {
3404         vec2 f2 = calc_brick_texture(co * scale,
3405                                      mortar_size, mortar_smooth, bias,
3406                                      brick_width, row_height,
3407                                      offset_amount, int(offset_frequency),
3408                                      squash_amount, int(squash_frequency));
3409         float tint = f2.x;
3410         float f = f2.y;
3411         if (f != 1.0) {
3412                 float facm = 1.0 - tint;
3413                 color1 = facm * color1 + tint * color2;
3414         }
3415         color = mix(color1, mortar, f);
3416         fac = f;
3417 }
3418
3419 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
3420 {
3421         color = vec4(1.0);
3422         fac = 1.0;
3423 }
3424
3425 void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
3426 {
3427         vec3 nco = normalize(co);
3428         float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
3429         float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
3430
3431         /* Fix pole bleeding */
3432         float half_width = 0.5 / float(textureSize(ima, 0).x);
3433         v = clamp(v, half_width, 1.0 - half_width);
3434
3435         /* Fix u = 0 seam */
3436         /* This is caused by texture filtering, since uv don't have smooth derivatives
3437          * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
3438          * texels. So we force the highest mipmap and don't do anisotropic filtering. */
3439         color = textureLod(ima, vec2(u, v), 0.0);
3440 }
3441
3442 void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
3443 {
3444         vec3 nco = normalize(co);
3445
3446         nco.y -= 1.0;
3447
3448         float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
3449         if (div > 0.0)
3450                 nco /= div;
3451
3452         float u = 0.5 * (nco.x + 1.0);
3453         float v = 0.5 * (nco.z + 1.0);
3454
3455         color = texture(ima, vec2(u, v));
3456 }
3457
3458 void node_tex_environment_empty(vec3 co, out vec4 color)
3459 {
3460         color = vec4(1.0, 0.0, 1.0, 1.0);
3461 }
3462
3463 void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
3464 {
3465         color = texture(ima, co.xy);
3466         alpha = color.a;
3467 }
3468
3469 void node_tex_image_box(vec3 texco,
3470                         vec3 N,
3471                         sampler2D ima,
3472                         float blend,
3473                         out vec4 color,
3474                         out float alpha)
3475 {
3476         vec3 signed_N = N;
3477
3478         /* project from direction vector to barycentric coordinates in triangles */
3479         N = vec3(abs(N.x), abs(N.y), abs(N.z));
3480         N /= (N.x + N.y + N.z);
3481
3482         /* basic idea is to think of this as a triangle, each corner representing
3483          * one of the 3 faces of the cube. in the corners we have single textures,
3484          * in between we blend between two textures, and in the middle we a blend
3485          * between three textures.
3486          *
3487          * the Nxyz values are the barycentric coordinates in an equilateral
3488          * triangle, which in case of blending, in the middle has a smaller
3489          * equilateral triangle where 3 textures blend. this divides things into
3490          * 7 zones, with an if () test for each zone */
3491
3492         vec3 weight = vec3(0.0, 0.0, 0.0);
3493         float limit = 0.5 * (1.0 + blend);