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