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