cfd35f5947879c41840e89514ae26fd9b373abaf
[blender-staging.git] / source / blender / gpu / intern / gpu_shader_material.glsl
1
2 float exp_blender(float f)
3 {
4         return pow(2.71828182846, f);
5 }
6
7 void rgb_to_hsv(vec4 rgb, out vec4 outcol)
8 {
9         float cmax, cmin, h, s, v, cdelta;
10         vec3 c;
11
12         cmax = max(rgb[0], max(rgb[1], rgb[2]));
13         cmin = min(rgb[0], min(rgb[1], rgb[2]));
14         cdelta = cmax-cmin;
15
16         v = cmax;
17         if (cmax!=0.0)
18                 s = cdelta/cmax;
19         else {
20                 s = 0.0;
21                 h = 0.0;
22         }
23
24         if (s == 0.0) {
25                 h = 0.0;
26         }
27         else {
28                 c = (vec3(cmax, cmax, cmax) - rgb.xyz)/cdelta;
29
30                 if (rgb.x==cmax) h = c[2] - c[1];
31                 else if (rgb.y==cmax) h = 2.0 + c[0] -  c[2];
32                 else h = 4.0 + c[1] - c[0];
33
34                 h /= 6.0;
35
36                 if (h<0.0)
37                         h += 1.0;
38         }
39
40         outcol = vec4(h, s, v, rgb.w);
41 }
42
43 void hsv_to_rgb(vec4 hsv, out vec4 outcol)
44 {
45         float i, f, p, q, t, h, s, v;
46         vec3 rgb;
47
48         h = hsv[0];
49         s = hsv[1];
50         v = hsv[2];
51
52         if(s==0.0) {
53                 rgb = vec3(v, v, v);
54         }
55         else {
56                 if(h==1.0)
57                         h = 0.0;
58                 
59                 h *= 6.0;
60                 i = floor(h);
61                 f = h - i;
62                 rgb = vec3(f, f, f);
63                 p = v*(1.0-s);
64                 q = v*(1.0-(s*f));
65                 t = v*(1.0-(s*(1.0-f)));
66                 
67                 if (i == 0.0) rgb = vec3(v, t, p);
68                 else if (i == 1.0) rgb = vec3(q, v, p);
69                 else if (i == 2.0) rgb = vec3(p, v, t);
70                 else if (i == 3.0) rgb = vec3(p, q, v);
71                 else if (i == 4.0) rgb = vec3(t, p, v);
72                 else rgb = vec3(v, p, q);
73         }
74
75         outcol = vec4(rgb, hsv.w);
76 }
77
78 float srgb_to_linearrgb(float c)
79 {
80         if(c < 0.04045)
81                 return (c < 0.0)? 0.0: c * (1.0/12.92);
82         else
83                 return pow((c + 0.055)*(1.0/1.055), 2.4);
84 }
85
86 float linearrgb_to_srgb(float c)
87 {
88         if(c < 0.0031308)
89                 return (c < 0.0)? 0.0: c * 12.92;
90         else
91                 return 1.055 * pow(c, 1.0/2.4) - 0.055;
92 }
93
94 void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
95 {
96         col_to.r = srgb_to_linearrgb(col_from.r);
97         col_to.g = srgb_to_linearrgb(col_from.g);
98         col_to.b = srgb_to_linearrgb(col_from.b);
99         col_to.a = col_from.a;
100 }
101
102 void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
103 {
104         col_to.r = linearrgb_to_srgb(col_from.r);
105         col_to.g = linearrgb_to_srgb(col_from.g);
106         col_to.b = linearrgb_to_srgb(col_from.b);
107         col_to.a = col_from.a;
108 }
109
110 #define M_PI 3.14159265358979323846
111
112 /*********** SHADER NODES ***************/
113
114 void vcol_attribute(vec4 attvcol, out vec4 vcol)
115 {
116         vcol = vec4(attvcol.x/255.0, attvcol.y/255.0, attvcol.z/255.0, 1.0);
117 }
118
119 void uv_attribute(vec2 attuv, out vec3 uv)
120 {
121         uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0);
122 }
123
124 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)
125 {
126         local = co;
127         view = normalize(local);
128         global = (viewinvmat*vec4(local, 1.0)).xyz;
129         orco = attorco;
130         uv_attribute(attuv, uv);
131         normal = -normalize(nor);       /* blender render normal is negated */
132         vcol_attribute(attvcol, vcol);
133         frontback = 1.0;
134 }
135
136 void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
137 {
138         outvec = (mat * vec4(vec, 1.0)).xyz;
139         if(domin == 1.0)
140                 outvec = max(outvec, minvec);
141         if(domax == 1.0)
142                 outvec = min(outvec, maxvec);
143 }
144
145 void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
146 {
147         outdepth = abs(co.z);
148         outdist = length(co);
149         outview = normalize(co);
150 }
151
152 void math_add(float val1, float val2, out float outval)
153 {
154         outval = val1 + val2;
155 }
156
157 void math_subtract(float val1, float val2, out float outval)
158 {
159         outval = val1 - val2;
160 }
161
162 void math_multiply(float val1, float val2, out float outval)
163 {
164         outval = val1 * val2;
165 }
166
167 void math_divide(float val1, float val2, out float outval)
168 {
169         if (val2 == 0.0)
170                 outval = 0.0;
171         else
172                 outval = val1 / val2;
173 }
174
175 void math_sine(float val, out float outval)
176 {
177         outval = sin(val);
178 }
179
180 void math_cosine(float val, out float outval)
181 {
182         outval = cos(val);
183 }
184
185 void math_tangent(float val, out float outval)
186 {
187         outval = tan(val);
188 }
189
190 void math_asin(float val, out float outval)
191 {
192         if (val <= 1.0 && val >= -1.0)
193                 outval = asin(val);
194         else
195                 outval = 0.0;
196 }
197
198 void math_acos(float val, out float outval)
199 {
200         if (val <= 1.0 && val >= -1.0)
201                 outval = acos(val);
202         else
203                 outval = 0.0;
204 }
205
206 void math_atan(float val, out float outval)
207 {
208         outval = atan(val);
209 }
210
211 void math_pow(float val1, float val2, out float outval)
212 {
213         if (val1 >= 0.0)
214                 outval = pow(val1, val2);
215         else
216                 outval = 0.0;
217 }
218
219 void math_log(float val1, float val2, out float outval)
220 {
221         if(val1 > 0.0  && val2 > 0.0)
222                 outval= log2(val1) / log2(val2);
223         else
224                 outval= 0.0;
225 }
226
227 void math_max(float val1, float val2, out float outval)
228 {
229         outval = max(val1, val2);
230 }
231
232 void math_min(float val1, float val2, out float outval)
233 {
234         outval = min(val1, val2);
235 }
236
237 void math_round(float val, out float outval)
238 {
239         outval= floor(val + 0.5);
240 }
241
242 void math_less_than(float val1, float val2, out float outval)
243 {
244         if(val1 < val2)
245                 outval = 1.0;
246         else
247                 outval = 0.0;
248 }
249
250 void math_greater_than(float val1, float val2, out float outval)
251 {
252         if(val1 > val2)
253                 outval = 1.0;
254         else
255                 outval = 0.0;
256 }
257
258 void squeeze(float val, float width, float center, out float outval)
259 {
260         outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));
261 }
262
263 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
264 {
265         outvec = v1 + v2;
266         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
267 }
268
269 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
270 {
271         outvec = v1 - v2;
272         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
273 }
274
275 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
276 {
277         outvec = v1 + v2;
278         outval = length(outvec);
279         outvec = normalize(outvec);
280 }
281
282 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
283 {
284         outvec = vec3(0, 0, 0);
285         outval = dot(v1, v2);
286 }
287
288 void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
289 {
290         outvec = cross(v1, v2);
291         outval = length(outvec);
292 }
293
294 void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
295 {
296         outval = length(v);
297         outvec = normalize(v);
298 }
299
300 void vec_math_negate(vec3 v, out vec3 outv)
301 {
302         outv = -v;
303 }
304
305 void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
306 {
307         outnor = dir;
308         outdot = -dot(dir, nor);
309 }
310
311 void curves_vec(float fac, vec3 vec, sampler1D curvemap, out vec3 outvec)
312 {
313         outvec.x = texture1D(curvemap, (vec.x + 1.0)*0.5).x;
314         outvec.y = texture1D(curvemap, (vec.y + 1.0)*0.5).y;
315         outvec.z = texture1D(curvemap, (vec.z + 1.0)*0.5).z;
316
317         if (fac != 1.0)
318                 outvec = (outvec*fac) + (vec*(1.0-fac));
319
320 }
321
322 void curves_rgb(float fac, vec4 col, sampler1D curvemap, out vec4 outcol)
323 {
324         outcol.r = texture1D(curvemap, texture1D(curvemap, col.r).a).r;
325         outcol.g = texture1D(curvemap, texture1D(curvemap, col.g).a).g;
326         outcol.b = texture1D(curvemap, texture1D(curvemap, col.b).a).b;
327
328         if (fac != 1.0)
329                 outcol = (outcol*fac) + (col*(1.0-fac));
330
331         outcol.a = col.a;
332 }
333
334 void set_value(float val, out float outval)
335 {
336         outval = val;
337 }
338
339 void set_rgb(vec3 col, out vec3 outcol)
340 {
341         outcol = col;
342 }
343
344 void set_rgba(vec4 col, out vec4 outcol)
345 {
346         outcol = col;
347 }
348
349 void set_value_zero(out float outval)
350 {
351         outval = 0.0;
352 }
353
354 void set_value_one(out float outval)
355 {
356         outval = 1.0;
357 }
358
359 void set_rgb_zero(out vec3 outval)
360 {
361         outval = vec3(0.0);
362 }
363
364 void set_rgba_zero(out vec4 outval)
365 {
366         outval = vec4(0.0);
367 }
368
369 void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
370 {
371         fac = clamp(fac, 0.0, 1.0);
372         outcol = mix(col1, col2, fac);
373         outcol.a = col1.a;
374 }
375
376 void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
377 {
378         fac = clamp(fac, 0.0, 1.0);
379         outcol = mix(col1, col1 + col2, fac);
380         outcol.a = col1.a;
381 }
382
383 void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
384 {
385         fac = clamp(fac, 0.0, 1.0);
386         outcol = mix(col1, col1 * col2, fac);
387         outcol.a = col1.a;
388 }
389
390 void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
391 {
392         fac = clamp(fac, 0.0, 1.0);
393         float facm = 1.0 - fac;
394
395         outcol = vec4(1.0) - (vec4(facm) + fac*(vec4(1.0) - col2))*(vec4(1.0) - col1);
396         outcol.a = col1.a;
397 }
398
399 void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
400 {
401         fac = clamp(fac, 0.0, 1.0);
402         float facm = 1.0 - fac;
403
404         outcol = col1;
405
406         if(outcol.r < 0.5)
407                 outcol.r *= facm + 2.0*fac*col2.r;
408         else
409                 outcol.r = 1.0 - (facm + 2.0*fac*(1.0 - col2.r))*(1.0 - outcol.r);
410
411         if(outcol.g < 0.5)
412                 outcol.g *= facm + 2.0*fac*col2.g;
413         else
414                 outcol.g = 1.0 - (facm + 2.0*fac*(1.0 - col2.g))*(1.0 - outcol.g);
415
416         if(outcol.b < 0.5)
417                 outcol.b *= facm + 2.0*fac*col2.b;
418         else
419                 outcol.b = 1.0 - (facm + 2.0*fac*(1.0 - col2.b))*(1.0 - outcol.b);
420 }
421
422 void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
423 {
424         fac = clamp(fac, 0.0, 1.0);
425         outcol = mix(col1, col1 - col2, fac);
426         outcol.a = col1.a;
427 }
428
429 void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
430 {
431         fac = clamp(fac, 0.0, 1.0);
432         float facm = 1.0 - fac;
433
434         outcol = col1;
435
436         if(col2.r != 0.0) outcol.r = facm*outcol.r + fac*outcol.r/col2.r;
437         if(col2.g != 0.0) outcol.g = facm*outcol.g + fac*outcol.g/col2.g;
438         if(col2.b != 0.0) outcol.b = facm*outcol.b + fac*outcol.b/col2.b;
439 }
440
441 void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
442 {
443         fac = clamp(fac, 0.0, 1.0);
444         outcol = mix(col1, abs(col1 - col2), fac);
445         outcol.a = col1.a;
446 }
447
448 void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
449 {
450         fac = clamp(fac, 0.0, 1.0);
451         outcol.rgb = min(col1.rgb, col2.rgb*fac);
452         outcol.a = col1.a;
453 }
454
455 void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
456 {
457         fac = clamp(fac, 0.0, 1.0);
458         outcol.rgb = max(col1.rgb, col2.rgb*fac);
459         outcol.a = col1.a;
460 }
461
462 void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
463 {
464         fac = clamp(fac, 0.0, 1.0);
465         outcol = col1;
466
467         if(outcol.r != 0.0) {
468                 float tmp = 1.0 - fac*col2.r;
469                 if(tmp <= 0.0)
470                         outcol.r = 1.0;
471                 else if((tmp = outcol.r/tmp) > 1.0)
472                         outcol.r = 1.0;
473                 else
474                         outcol.r = tmp;
475         }
476         if(outcol.g != 0.0) {
477                 float tmp = 1.0 - fac*col2.g;
478                 if(tmp <= 0.0)
479                         outcol.g = 1.0;
480                 else if((tmp = outcol.g/tmp) > 1.0)
481                         outcol.g = 1.0;
482                 else
483                         outcol.g = tmp;
484         }
485         if(outcol.b != 0.0) {
486                 float tmp = 1.0 - fac*col2.b;
487                 if(tmp <= 0.0)
488                         outcol.b = 1.0;
489                 else if((tmp = outcol.b/tmp) > 1.0)
490                         outcol.b = 1.0;
491                 else
492                         outcol.b = tmp;
493         }
494 }
495
496 void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
497 {
498         fac = clamp(fac, 0.0, 1.0);
499         float tmp, facm = 1.0 - fac;
500
501         outcol = col1;
502
503         tmp = facm + fac*col2.r;
504         if(tmp <= 0.0)
505                 outcol.r = 0.0;
506         else if((tmp = (1.0 - (1.0 - outcol.r)/tmp)) < 0.0)
507                 outcol.r = 0.0;
508         else if(tmp > 1.0)
509                 outcol.r = 1.0;
510         else
511                 outcol.r = tmp;
512
513         tmp = facm + fac*col2.g;
514         if(tmp <= 0.0)
515                 outcol.g = 0.0;
516         else if((tmp = (1.0 - (1.0 - outcol.g)/tmp)) < 0.0)
517                 outcol.g = 0.0;
518         else if(tmp > 1.0)
519                 outcol.g = 1.0;
520         else
521                 outcol.g = tmp;
522
523         tmp = facm + fac*col2.b;
524         if(tmp <= 0.0)
525                 outcol.b = 0.0;
526         else if((tmp = (1.0 - (1.0 - outcol.b)/tmp)) < 0.0)
527                 outcol.b = 0.0;
528         else if(tmp > 1.0)
529                 outcol.b = 1.0;
530         else
531                 outcol.b = tmp;
532 }
533
534 void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
535 {
536         fac = clamp(fac, 0.0, 1.0);
537         float facm = 1.0 - fac;
538
539         outcol = col1;
540
541         vec4 hsv, hsv2, tmp;
542         rgb_to_hsv(col2, hsv2);
543
544         if(hsv2.y != 0.0) {
545                 rgb_to_hsv(outcol, hsv);
546                 hsv.x = hsv2.x;
547                 hsv_to_rgb(hsv, tmp); 
548
549                 outcol = mix(outcol, tmp, fac);
550                 outcol.a = col1.a;
551         }
552 }
553
554 void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
555 {
556         fac = clamp(fac, 0.0, 1.0);
557         float facm = 1.0 - fac;
558
559         outcol = col1;
560
561         vec4 hsv, hsv2;
562         rgb_to_hsv(outcol, hsv);
563
564         if(hsv.y != 0.0) {
565                 rgb_to_hsv(col2, hsv2);
566
567                 hsv.y = facm*hsv.y + fac*hsv2.y;
568                 hsv_to_rgb(hsv, outcol);
569         }
570 }
571
572 void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
573 {
574         fac = clamp(fac, 0.0, 1.0);
575         float facm = 1.0 - fac;
576
577         vec4 hsv, hsv2;
578         rgb_to_hsv(col1, hsv);
579         rgb_to_hsv(col2, hsv2);
580
581         hsv.z = facm*hsv.z + fac*hsv2.z;
582         hsv_to_rgb(hsv, outcol);
583 }
584
585 void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
586 {
587         fac = clamp(fac, 0.0, 1.0);
588         float facm = 1.0 - fac;
589
590         outcol = col1;
591
592         vec4 hsv, hsv2, tmp;
593         rgb_to_hsv(col2, hsv2);
594
595         if(hsv2.y != 0.0) {
596                 rgb_to_hsv(outcol, hsv);
597                 hsv.x = hsv2.x;
598                 hsv.y = hsv2.y;
599                 hsv_to_rgb(hsv, tmp); 
600
601                 outcol = mix(outcol, tmp, fac);
602                 outcol.a = col1.a;
603         }
604 }
605
606 void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
607 {
608         fac = clamp(fac, 0.0, 1.0);
609         float facm = 1.0 - fac;
610
611         vec4 one= vec4(1.0);
612         vec4 scr= one - (one - col2)*(one - col1);
613         outcol = facm*col1 + fac*((one - col1)*col2*col1 + col1*scr);
614 }
615
616 void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
617 {
618         fac = clamp(fac, 0.0, 1.0);
619
620         outcol = col1;
621
622         if(col2.r > 0.5)
623                 outcol.r= col1.r + fac*(2.0*(col2.r - 0.5));
624         else
625                 outcol.r= col1.r + fac*(2.0*(col2.r) - 1.0);
626
627         if(col2.g > 0.5)
628                 outcol.g= col1.g + fac*(2.0*(col2.g - 0.5));
629         else
630                 outcol.g= col1.g + fac*(2.0*(col2.g) - 1.0);
631
632         if(col2.b > 0.5)
633                 outcol.b= col1.b + fac*(2.0*(col2.b - 0.5));
634         else
635                 outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0);
636 }
637
638 void valtorgb(float fac, sampler1D colormap, out vec4 outcol, out float outalpha)
639 {
640         outcol = texture1D(colormap, fac);
641         outalpha = outcol.a;
642 }
643
644 void rgbtobw(vec4 color, out float outval)
645 {
646         outval = color.r*0.35 + color.g*0.45 + color.b*0.2;
647 }
648
649 void invert(float fac, vec4 col, out vec4 outcol)
650 {
651         outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
652         outcol.w = col.w;
653 }
654
655 void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
656 {
657         vec4 hsv;
658
659         rgb_to_hsv(col, hsv);
660
661         hsv[0] += (hue - 0.5);
662         if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
663         hsv[1] *= sat;
664         if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
665         hsv[2] *= value;
666         if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
667
668         hsv_to_rgb(hsv, outcol);
669
670         outcol = mix(col, outcol, fac);
671 }
672
673 void separate_rgb(vec4 col, out float r, out float g, out float b)
674 {
675         r = col.r;
676         g = col.g;
677         b = col.b;
678 }
679
680 void combine_rgb(float r, float g, float b, out vec4 col)
681 {
682         col = vec4(r, g, b, 1.0);
683 }
684
685 void output_node(vec4 rgb, float alpha, out vec4 outrgb)
686 {
687         outrgb = vec4(rgb.rgb, alpha);
688 }
689
690 /*********** TEXTURES ***************/
691
692 void texture_flip_blend(vec3 vec, out vec3 outvec)
693 {
694         outvec = vec.yxz;
695 }
696
697 void texture_blend_lin(vec3 vec, out float outval)
698 {
699         outval = (1.0+vec.x)/2.0;
700 }
701
702 void texture_blend_quad(vec3 vec, out float outval)
703 {
704         outval = max((1.0+vec.x)/2.0, 0.0);
705         outval *= outval;
706 }
707
708 void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
709 {
710         float a = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z)*20.0;
711         float wi = 0.5 + 0.5*sin(a);
712
713         value = wi;
714         color = vec4(wi, wi, wi, 1.0);
715         normal = vec3(0.0, 0.0, 0.0);
716 }
717
718 void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
719 {
720         color = texture2D(ima, (vec.xy + vec2(1.0, 1.0))*0.5);
721         value = 1.0;
722
723         normal.x = 2.0*(color.r - 0.5);
724         normal.y = 2.0*(0.5 - color.g);
725         normal.z = 2.0*(color.b - 0.5);
726 }
727
728 /************* MTEX *****************/
729
730 void texco_orco(vec3 attorco, out vec3 orco)
731 {
732         orco = attorco;
733 }
734
735 void texco_uv(vec2 attuv, out vec3 uv)
736 {
737         /* disabled for now, works together with leaving out mtex_2d_mapping
738            uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
739         uv = vec3(attuv, 0.0);
740 }
741
742 void texco_norm(vec3 normal, out vec3 outnormal)
743 {
744         /* corresponds to shi->orn, which is negated so cancels
745            out blender normal negation */
746         outnormal = normalize(normal);
747 }
748
749 void texco_tangent(vec3 tangent, out vec3 outtangent)
750 {
751         outtangent = normalize(tangent);
752 }
753
754 void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
755 {
756         global = (viewinvmat*vec4(co, 1.0)).xyz;
757 }
758
759 void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
760 {
761         object = (obinvmat*(viewinvmat*vec4(co, 1.0))).xyz;
762 }
763
764 void texco_refl(vec3 vn, vec3 view, out vec3 ref)
765 {
766         ref = view - 2.0*dot(vn, view)*vn;
767 }
768
769 void shade_norm(vec3 normal, out vec3 outnormal)
770 {
771         /* blender render normal is negated */
772         outnormal = -normalize(normal);
773 }
774
775 void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
776 {
777         float facm;
778
779         fact *= facg;
780         facm = 1.0-fact;
781
782         incol = fact*texcol + facm*outcol;
783 }
784
785 void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
786 {
787         float facm;
788
789         fact *= facg;
790         facm = 1.0-facg;
791
792         incol = (facm + fact*texcol)*outcol;
793 }
794
795 void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
796 {
797         float facm;
798
799         fact *= facg;
800         facm = 1.0-facg;
801
802         incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
803 }
804
805 void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
806 {
807         float facm;
808
809         fact *= facg;
810         facm = 1.0-facg;
811
812         if(outcol.r < 0.5)
813                 incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
814         else
815                 incol.r = 1.0 - (facm + 2.0*fact*(1.0 - texcol.r))*(1.0 - outcol.r);
816
817         if(outcol.g < 0.5)
818                 incol.g = outcol.g*(facm + 2.0*fact*texcol.g);
819         else
820                 incol.g = 1.0 - (facm + 2.0*fact*(1.0 - texcol.g))*(1.0 - outcol.g);
821
822         if(outcol.b < 0.5)
823                 incol.b = outcol.b*(facm + 2.0*fact*texcol.b);
824         else
825                 incol.b = 1.0 - (facm + 2.0*fact*(1.0 - texcol.b))*(1.0 - outcol.b);
826 }
827
828 void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
829 {
830         incol = -fact*facg*texcol + outcol;
831 }
832
833 void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
834 {
835         incol = fact*facg*texcol + outcol;
836 }
837
838 void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
839 {
840         float facm;
841
842         fact *= facg;
843         facm = 1.0-fact;
844
845         if(texcol.r != 0.0) incol.r = facm*outcol.r + fact*outcol.r/texcol.r;
846         if(texcol.g != 0.0) incol.g = facm*outcol.g + fact*outcol.g/texcol.g;
847         if(texcol.b != 0.0) incol.b = facm*outcol.b + fact*outcol.b/texcol.b;
848 }
849
850 void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
851 {
852         float facm;
853
854         fact *= facg;
855         facm = 1.0-fact;
856
857         incol = facm*outcol + fact*abs(texcol - outcol);
858 }
859
860 void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
861 {
862         float facm, col;
863
864         fact *= facg;
865         facm = 1.0-fact;
866
867         col = fact*texcol.r;
868         if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
869         col = fact*texcol.g;
870         if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
871         col = fact*texcol.b;
872         if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
873 }
874
875 void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
876 {
877         float facm, col;
878
879         fact *= facg;
880         facm = 1.0-fact;
881
882         col = fact*texcol.r;
883         if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
884         col = fact*texcol.g;
885         if(col > outcol.g) incol.g = col; else incol.g = outcol.g;
886         col = fact*texcol.b;
887         if(col > outcol.b) incol.b = col; else incol.b = outcol.b;
888 }
889
890 void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
891 {
892         vec4 col;
893
894         mix_hue(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
895         incol.rgb = col.rgb;
896 }
897
898 void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
899 {
900         vec4 col;
901
902         mix_sat(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
903         incol.rgb = col.rgb;
904 }
905
906 void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
907 {
908         vec4 col;
909
910         mix_val(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
911         incol.rgb = col.rgb;
912 }
913
914 void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
915 {
916         vec4 col;
917
918         mix_color(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
919         incol.rgb = col.rgb;
920 }
921
922 void mtex_value_vars(inout float fact, float facg, out float facm)
923 {
924         fact *= abs(facg);
925         facm = 1.0-fact;
926
927         if(facg < 0.0) {
928                 float tmp = fact;
929                 fact = facm;
930                 facm = tmp;
931         }
932 }
933
934 void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
935 {
936         float facm;
937         mtex_value_vars(fact, facg, facm);
938
939         incol = fact*texcol + facm*outcol;
940 }
941
942 void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
943 {
944         float facm;
945         mtex_value_vars(fact, facg, facm);
946
947         facm = 1.0 - facg;
948         incol = (facm + fact*texcol)*outcol;
949 }
950
951 void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
952 {
953         float facm;
954         mtex_value_vars(fact, facg, facm);
955
956         facm = 1.0 - facg;
957         incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol);
958 }
959
960 void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
961 {
962         float facm;
963         mtex_value_vars(fact, facg, facm);
964
965         fact = -fact;
966         incol = fact*texcol + outcol;
967 }
968
969 void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
970 {
971         float facm;
972         mtex_value_vars(fact, facg, facm);
973
974         fact = fact;
975         incol = fact*texcol + outcol;
976 }
977
978 void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
979 {
980         float facm;
981         mtex_value_vars(fact, facg, facm);
982
983         if(texcol != 0.0)
984                 incol = facm*outcol + fact*outcol/texcol;
985         else
986                 incol = 0.0;
987 }
988
989 void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
990 {
991         float facm;
992         mtex_value_vars(fact, facg, facm);
993
994         incol = facm*outcol + fact*abs(texcol - outcol);
995 }
996
997 void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
998 {
999         float facm;
1000         mtex_value_vars(fact, facg, facm);
1001
1002         float col = fact*texcol;
1003         if(col < outcol) incol = col; else incol = outcol;
1004 }
1005
1006 void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
1007 {
1008         float facm;
1009         mtex_value_vars(fact, facg, facm);
1010
1011         float col = fact*texcol;
1012         if(col > outcol) incol = col; else incol = outcol;
1013 }
1014
1015 void mtex_value_clamp_positive(float fac, out float outfac)
1016 {
1017         outfac = max(fac, 0.0);
1018 }
1019
1020 void mtex_value_clamp(float fac, out float outfac)
1021 {
1022         outfac = clamp(fac, 0.0, 1.0);
1023 }
1024
1025 void mtex_har_divide(float har, out float outhar)
1026 {
1027         outhar = har/128.0;
1028 }
1029
1030 void mtex_har_multiply_clamp(float har, out float outhar)
1031 {
1032         har *= 128.0;
1033
1034         if(har < 1.0) outhar = 1.0;
1035         else if(har > 511.0) outhar = 511.0;
1036         else outhar = har;
1037 }
1038
1039 void mtex_alpha_from_col(vec4 col, out float alpha)
1040 {
1041         alpha = col.a;
1042 }
1043
1044 void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
1045 {
1046         outcol = vec4(col.rgb, alpha);
1047 }
1048
1049 void mtex_rgbtoint(vec4 rgb, out float intensity)
1050 {
1051         intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
1052 }
1053
1054 void mtex_value_invert(float invalue, out float outvalue)
1055 {
1056         outvalue = 1.0 - invalue;
1057 }
1058
1059 void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
1060 {
1061         outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
1062 }
1063
1064 void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
1065 {
1066         float fact = intensity;
1067         outintensity = intensity*stencil;
1068         outstencil = stencil*fact;
1069 }
1070
1071 void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
1072 {
1073         float fact = rgb.a;
1074         outrgb = vec4(rgb.rgb, rgb.a*stencil);
1075         outstencil = stencil*fact;
1076 }
1077
1078 void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
1079 {
1080         outtexco = texco + ofs;
1081 }
1082
1083 void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
1084 {
1085         outtexco = size*texco;
1086 }
1087
1088 void mtex_2d_mapping(vec3 vec, out vec3 outvec)
1089 {
1090         outvec = vec3(vec.xy*0.5 + vec2(0.5, 0.5), vec.z);
1091 }
1092
1093 void mtex_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
1094 {
1095         color = texture2D(ima, vec.xy);
1096         value = 1.0;
1097         
1098         normal = 2.0*(vec3(color.r, -color.g, color.b) - vec3(0.5, -0.5, 0.5));
1099 }
1100
1101 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1102 {
1103         outnormal = vec3(-normal.x, -normal.y, normal.z);
1104 }
1105
1106 void mtex_nspace_tangent(vec3 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1107 {
1108         tangent = normalize(tangent);
1109         vec3 B = cross(normal, tangent);
1110
1111         outnormal = texnormal.x*tangent + texnormal.y*B + texnormal.z*normal;
1112         outnormal = normalize(outnormal);
1113 }
1114
1115 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1116 {
1117         outnormal = (1.0 - norfac)*normal + norfac*newnormal;
1118         outnormal = normalize(outnormal);
1119 }
1120
1121 /******* MATERIAL *********/
1122
1123 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1124 {
1125         lv = lampvec;
1126         dist = 1.0;
1127         visifac = 1.0;
1128 }
1129
1130 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1131 {
1132         lv = co - lampco;
1133         dist = length(lv);
1134         lv = normalize(lv);
1135         visifac = 1.0;
1136 }
1137
1138 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1139 {
1140         visifac = lampdist/(lampdist + dist);
1141 }
1142
1143 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1144 {
1145         visifac = lampdist/(lampdist + dist*dist);
1146 }
1147
1148 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1149 {
1150         float lampdistkw = lampdist*lampdist;
1151
1152         visifac = lampdist/(lampdist + ld1*dist);
1153         visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
1154 }
1155
1156 void lamp_falloff_curve(float lampdist, sampler1D curvemap, float dist, out float visifac)
1157 {
1158         visifac = texture1D(curvemap, dist/lampdist).x;
1159 }
1160
1161 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1162 {
1163         float t= lampdist - dist;
1164
1165         outvisifac= visifac*max(t, 0.0)/lampdist;
1166 }
1167
1168 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec3 lv, out float inpr)
1169 {
1170         if(dot(lv, lampvec) > 0.0) {
1171                 vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
1172                 float x = max(abs(lvrot.x/lvrot.z), abs(lvrot.y/lvrot.z));
1173
1174                 inpr = 1.0/sqrt(1.0 + x*x);
1175         }
1176         else
1177                 inpr = 0.0;
1178 }
1179
1180 void lamp_visibility_spot_circle(vec3 lampvec, vec3 lv, out float inpr)
1181 {
1182         inpr = dot(lv, lampvec);
1183 }
1184
1185 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1186 {
1187         float t = spotsi;
1188
1189         if(inpr <= t) {
1190                 outvisifac = 0.0;
1191         }
1192         else {
1193                 t = inpr - t;
1194
1195                 /* soft area */
1196                 if(spotbl != 0.0)
1197                         inpr *= smoothstep(0.0, 1.0, t/spotbl);
1198
1199                 outvisifac = visifac*inpr;
1200         }
1201 }
1202
1203 void lamp_visibility_clamp(float visifac, out float outvisifac)
1204 {
1205         outvisifac = (visifac < 0.001)? 0.0: visifac;
1206 }
1207
1208 void shade_view(vec3 co, out vec3 view)
1209 {
1210         /* handle perspective/orthographic */
1211         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
1212 }
1213
1214 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1215 {
1216         vec3 c = cross(lv, tang);
1217         vec3 vnor = cross(c, tang);
1218
1219         vn = -normalize(vnor);
1220 }
1221
1222 void shade_inp(vec3 vn, vec3 lv, out float inp)
1223 {
1224         inp = dot(vn, lv);
1225 }
1226
1227 void shade_is_no_diffuse(out float is)
1228 {
1229         is = 0.0;
1230 }
1231
1232 void shade_is_hemi(float inp, out float is)
1233 {
1234         is = 0.5*inp + 0.5;
1235 }
1236
1237 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1238 {
1239         vec3 vec[4], c[4];
1240         float rad[4], fac;
1241         
1242         vec[0] = normalize(co - area[0].xyz);
1243         vec[1] = normalize(co - area[1].xyz);
1244         vec[2] = normalize(co - area[2].xyz);
1245         vec[3] = normalize(co - area[3].xyz);
1246
1247         c[0] = normalize(cross(vec[0], vec[1]));
1248         c[1] = normalize(cross(vec[1], vec[2]));
1249         c[2] = normalize(cross(vec[2], vec[3]));
1250         c[3] = normalize(cross(vec[3], vec[0]));
1251
1252         rad[0] = acos(dot(vec[0], vec[1]));
1253         rad[1] = acos(dot(vec[1], vec[2]));
1254         rad[2] = acos(dot(vec[2], vec[3]));
1255         rad[3] = acos(dot(vec[3], vec[0]));
1256
1257         fac=  rad[0]*dot(vn, c[0]);
1258         fac+= rad[1]*dot(vn, c[1]);
1259         fac+= rad[2]*dot(vn, c[2]);
1260         fac+= rad[3]*dot(vn, c[3]);
1261
1262         return max(fac, 0.0);
1263 }
1264
1265 void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
1266 {
1267         vec3 co = position;
1268         vec3 vec = co - lampco;
1269
1270         if(dot(vec, lampvec) < 0.0) {
1271                 inp = 0.0;
1272         }
1273         else {
1274                 float intens = area_lamp_energy(area, co, vn);
1275
1276                 inp = pow(intens*areasize, k);
1277         }
1278 }
1279
1280 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1281 {
1282         vec3 h = normalize(v + l);
1283         float nh = max(dot(n, h), 0.0);
1284         float nv = max(dot(n, v), 0.0);
1285         float realnl = dot(n, l);
1286
1287         if(realnl < 0.0) {
1288                 is = 0.0;
1289         }
1290         else if(nl < 0.0) {
1291                 is = 0.0;
1292         }
1293         else {
1294                 float vh = max(dot(v, h), 0.0);
1295                 float Lit_A = acos(realnl);
1296                 float View_A = acos(nv);
1297
1298                 vec3 Lit_B = normalize(l - realnl*n);
1299                 vec3 View_B = normalize(v - nv*n);
1300
1301                 float t = max(dot(Lit_B, View_B), 0.0);
1302
1303                 float a, b;
1304
1305                 if(Lit_A > View_A) {
1306                         a = Lit_A;
1307                         b = View_A;
1308                 }
1309                 else {
1310                         a = View_A;
1311                         b = Lit_A;
1312                 }
1313
1314                 float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
1315                 float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
1316
1317                 b *= 0.95;
1318                 is = nl*(A + (B * t * sin(a) * tan(b)));
1319         }
1320 }
1321
1322 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1323 {
1324         float rslt = dot(n, l);
1325         float ang = acos(rslt);
1326
1327         if(ang < size) is = 1.0;
1328         else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1329         else is = 1.0 - ((ang - size)/tsmooth);
1330 }
1331
1332 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
1333 {
1334         if(nl <= 0.0) {
1335                 is = 0.0;
1336         }
1337         else {
1338                 float nv = max(dot(n, v), 0.0);
1339
1340                 if(darkness <= 1.0)
1341                         is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
1342                 else
1343                         is = nl*pow(1.0001 - nv, darkness - 1.0);
1344         }
1345 }
1346
1347 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
1348 {
1349         float t1, t2;
1350         float ffac;
1351
1352         if(fac==0.0) {
1353                 ffac = 1.0;
1354         }
1355         else {
1356                 t1= dot(view, vn);
1357                 if(t1>0.0)  t2= 1.0+t1;
1358                 else t2= 1.0-t1;
1359
1360                 t2= grad + (1.0-grad)*pow(t2, fac);
1361
1362                 if(t2<0.0) ffac = 0.0;
1363                 else if(t2>1.0) ffac = 1.0;
1364                 else ffac = t2;
1365         }
1366
1367         return ffac;
1368 }
1369
1370 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
1371 {
1372         is = fresnel_fac(lv, vn, fac_i, fac);
1373 }
1374
1375 void shade_cubic(float is, out float outis)
1376 {
1377         if(is>0.0 && is<1.0)
1378                 outis= smoothstep(0.0, 1.0, is);
1379         else
1380                 outis= is;
1381 }
1382
1383 void shade_visifac(float i, float visifac, float refl, out float outi)
1384 {
1385         /*if(i > 0.0)*/
1386                 outi = max(i*visifac*refl, 0.0);
1387         /*else
1388                 outi = i;*/
1389 }
1390
1391 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
1392 {
1393         vn = tang;
1394 }
1395
1396 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
1397 {
1398         if(i > 0.0)
1399                 outcol = i*lampcol*col;
1400         else
1401                 outcol = vec3(0.0, 0.0, 0.0);
1402 }
1403
1404 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
1405 {
1406         lv += view;
1407         lv = normalize(lv);
1408
1409         t = dot(vn, lv);
1410         t = 0.5*t + 0.5;
1411
1412         t = visifac*spec*pow(t, hard);
1413 }
1414
1415 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1416 {
1417         vec3 h = normalize(l + v);
1418         float rslt = max(dot(h, n), 0.0);
1419
1420         specfac = pow(rslt, hard);
1421 }
1422
1423 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1424 {
1425         vec3 h = normalize(v + l);
1426         float nh = dot(n, h);
1427
1428         if(nh < 0.0) {
1429                 specfac = 0.0;
1430         }
1431         else {
1432                 float nv = max(dot(n, v), 0.0);
1433                 float i = pow(nh, hard);
1434
1435                 i = i/(0.1+nv);
1436                 specfac = i;
1437         }
1438 }
1439
1440 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
1441 {
1442         if(refrac < 1.0) {
1443                 specfac = 0.0;
1444         }
1445         else if(spec_power == 0.0) {
1446                 specfac = 0.0;
1447         }
1448         else {
1449                 if(spec_power<100.0)
1450                         spec_power= sqrt(1.0/spec_power);
1451                 else
1452                         spec_power= 10.0/spec_power;
1453
1454                 vec3 h = normalize(v + l);
1455                 float nh = dot(n, h);
1456                 if(nh < 0.0) {
1457                         specfac = 0.0;
1458                 }
1459                 else {
1460                         float nv = max(dot(n, v), 0.01);
1461                         float nl = dot(n, l);
1462                         if(nl <= 0.01) {
1463                                 specfac = 0.0;
1464                         }
1465                         else {
1466                                 float vh = max(dot(v, h), 0.01);
1467
1468                                 float a = 1.0;
1469                                 float b = (2.0*nh*nv)/vh;
1470                                 float c = (2.0*nh*nl)/vh;
1471
1472                                 float g = 0.0;
1473
1474                                 if(a < b && a < c) g = a;
1475                                 else if(b < a && b < c) g = b;
1476                                 else if(c < a && c < b) g = c;
1477
1478                                 float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
1479                                 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))));
1480                                 float ang = acos(nh);
1481
1482                                 specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
1483                         }
1484                 }
1485         }
1486 }
1487
1488 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
1489 {
1490         vec3 h = normalize(l + v);
1491         float nh = max(dot(n, h), 0.001);
1492         float nv = max(dot(n, v), 0.001);
1493         float nl = max(dot(n, l), 0.001);
1494         float angle = tan(acos(nh));
1495         float alpha = max(rms, 0.001);
1496
1497         specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
1498 }
1499
1500 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
1501 {
1502         vec3 h = normalize(l + v);
1503         float rslt = dot(h, n);
1504         float ang = acos(rslt);
1505
1506         if(ang < size) rslt = 1.0;
1507         else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
1508         else rslt = 1.0 - ((ang - size)/tsmooth);
1509
1510         specfac = rslt;
1511 }
1512
1513 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
1514 {
1515         outspecfac = specfac*inp;
1516 }
1517
1518 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
1519 {
1520         t = shadfac*spec*visifac*specfac;
1521 }
1522
1523 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
1524 {
1525         outcol = t*lampcol*speccol;
1526 }
1527
1528 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
1529 {
1530         outcol = col1 + col2;
1531 }
1532
1533 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1534 {
1535         outcol = col + col1*col2;
1536 }
1537
1538 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
1539 {
1540         outcol = col + f*col1;
1541 }
1542
1543 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
1544 {
1545         outcol = col1*col2;
1546 }
1547
1548 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
1549 {
1550         outcol = col*fac;
1551 }
1552
1553 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1554 {
1555         outcol = vec4(col.rgb*obcol.rgb, col.a);
1556 }
1557
1558 void ramp_rgbtobw(vec3 color, out float outval)
1559 {
1560         outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
1561 }
1562
1563 void shade_only_shadow(float i, float shadfac, float energy, out float outshadfac)
1564 {
1565         outshadfac = i*energy*(1.0 - shadfac);
1566 }
1567
1568 void shade_only_shadow_diffuse(float shadfac, vec3 rgb, vec4 diff, out vec4 outdiff)
1569 {
1570         outdiff = diff - vec4(rgb*shadfac, 0.0);
1571 }
1572
1573 void shade_only_shadow_specular(float shadfac, vec3 specrgb, vec4 spec, out vec4 outspec)
1574 {
1575         outspec = spec - vec4(specrgb*shadfac, 0.0);
1576 }
1577
1578 void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
1579 {
1580         if(inp <= 0.0) {
1581                 result = 0.0;
1582         }
1583         else {
1584                 vec4 co = shadowpersmat*vec4(rco, 1.0);
1585
1586                 //float bias = (1.5 - inp*inp)*shadowbias;
1587                 co.z -= shadowbias*co.w;
1588
1589                 result = shadow2DProj(shadowmap, co).x;
1590         }
1591 }
1592
1593 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
1594 {
1595         outcol = linfac*(1.0 - exp(col*logfac));
1596 }
1597
1598 void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
1599 {
1600         float fac, zcor;
1601
1602         zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
1603         
1604         fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0);
1605         if(misttype == 0.0) fac *= fac;
1606         else if(misttype == 1.0);
1607         else fac = sqrt(fac);
1608
1609         outfac = 1.0 - (1.0-fac)*(1.0-misi);
1610 }
1611
1612 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
1613 {
1614         float fac = clamp(col.a, 0.0, 1.0);
1615         outcol = vec4(mix(hor, col.rgb, fac), col.a);
1616 }
1617
1618 void shade_alpha_opaque(vec4 col, out vec4 outcol)
1619 {
1620         outcol = vec4(col.rgb, 1.0);
1621 }
1622
1623 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1624 {
1625         outcol = vec4(col.rgb, col.a*obcol.a);
1626 }
1627