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