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