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