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