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