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