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