since the introduction of 'newbump' blender
[blender.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; /* keep these factors in sync with texture.h:RGBTOBW */
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(vec4 tangent, out vec3 outtangent)
750 {
751         outtangent = normalize(tangent.xyz);
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 texco, sampler2D ima, out float value, out vec4 color)
1094 {
1095         color = texture2D(ima, texco.xy);
1096         value = 1.0;
1097 }
1098
1099 void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
1100 {
1101         // The invert of the red channel is to make
1102         // the normal map compliant with the outside world.
1103         // It needs to be done because in Blender
1104         // the normal used points inward.
1105         // Should this ever change this negate must be removed.
1106     vec4 color = texture2D(ima, texco.xy);
1107         normal = 2.0*(vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
1108 }
1109
1110 void mtex_bump_normals_init( vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude )
1111 {
1112         vNorg = vN;
1113         vNacc = vN;
1114         fPrevMagnitude = 1.0;
1115 }
1116
1117 /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
1118 mat3 to_mat3(mat4 m4)
1119 {
1120         mat3 m3;
1121         m3[0] = m4[0].xyz;
1122         m3[1] = m4[1].xyz;
1123         m3[2] = m4[2].xyz;
1124         return m3;
1125 }
1126
1127 void mtex_bump_init_objspace( vec3 surf_pos, vec3 surf_norm,
1128                                                           mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv, 
1129                                                           float fPrevMagnitude_in, vec3 vNacc_in,
1130                                                           out float fPrevMagnitude_out, out vec3 vNacc_out, 
1131                                                           out vec3 vR1, out vec3 vR2, out float fDet ) 
1132 {
1133         mat3 obj2view = to_mat3(mView * mObj);
1134         mat3 view2obj = to_mat3(mObjInv * mViewInv);
1135         
1136         vec3 vSigmaS = view2obj * dFdx( surf_pos );
1137         vec3 vSigmaT = view2obj * dFdy( surf_pos );
1138         vec3 vN = normalize( surf_norm * obj2view );
1139
1140         vR1 = cross( vSigmaT, vN );
1141         vR2 = cross( vN, vSigmaS ) ;
1142         fDet = dot ( vSigmaS, vR1 );
1143         
1144         /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */
1145         vR1 = vR1 * view2obj;
1146         vR2 = vR2 * view2obj;
1147         vN = vN * view2obj;
1148         
1149         float fMagnitude = abs(fDet) * length(vN);
1150         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1151         fPrevMagnitude_out = fMagnitude;
1152 }
1153
1154 void mtex_bump_init_texturespace( vec3 surf_pos, vec3 surf_norm, 
1155                                                                   float fPrevMagnitude_in, vec3 vNacc_in,
1156                                                                   out float fPrevMagnitude_out, out vec3 vNacc_out, 
1157                                                                   out vec3 vR1, out vec3 vR2, out float fDet ) 
1158 {
1159         vec3 vSigmaS = dFdx( surf_pos );
1160         vec3 vSigmaT = dFdy( surf_pos );
1161         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1162         
1163         vR1 = normalize( cross( vSigmaT, vN ) );
1164         vR2 = normalize( cross( vN, vSigmaS ) );
1165         fDet = sign( dot(vSigmaS, vR1) );
1166         
1167         float fMagnitude = abs(fDet);
1168         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1169         fPrevMagnitude_out = fMagnitude;
1170 }
1171
1172 void mtex_bump_init_viewspace( vec3 surf_pos, vec3 surf_norm, 
1173                                                            float fPrevMagnitude_in, vec3 vNacc_in,
1174                                                            out float fPrevMagnitude_out, out vec3 vNacc_out, 
1175                                                            out vec3 vR1, out vec3 vR2, out float fDet ) 
1176 {
1177         vec3 vSigmaS = dFdx( surf_pos );
1178         vec3 vSigmaT = dFdy( surf_pos );
1179         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1180         
1181         vR1 = cross( vSigmaT, vN );
1182         vR2 = cross( vN, vSigmaS ) ;
1183         fDet = dot ( vSigmaS, vR1 );
1184         
1185         float fMagnitude = abs(fDet);
1186         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1187         fPrevMagnitude_out = fMagnitude;
1188 }
1189
1190 void mtex_bump_tap3( vec3 texco, sampler2D ima, float hScale, 
1191                      out float dBs, out float dBt ) 
1192 {
1193         vec2 STll = texco.xy;
1194         vec2 STlr = texco.xy + dFdx(texco.xy) ;
1195         vec2 STul = texco.xy + dFdy(texco.xy) ;
1196         
1197         float Hll,Hlr,Hul;
1198         rgbtobw( texture2D(ima, STll), Hll );
1199         rgbtobw( texture2D(ima, STlr), Hlr );
1200         rgbtobw( texture2D(ima, STul), Hul );
1201         
1202         dBs = hScale * (Hlr - Hll);
1203         dBt = hScale * (Hul - Hll);
1204 }
1205
1206 void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale, 
1207                      out float dBs, out float dBt ) 
1208 {
1209         vec2 TexDx = dFdx(texco.xy);
1210         vec2 TexDy = dFdy(texco.xy);
1211
1212         vec2 STc = texco.xy;
1213         vec2 STl = texco.xy - 0.5 * TexDx ;
1214         vec2 STr = texco.xy + 0.5 * TexDx ;
1215         vec2 STd = texco.xy - 0.5 * TexDy ;
1216         vec2 STu = texco.xy + 0.5 * TexDy ;
1217         
1218         float Hc,Hl,Hr,Hd,Hu;
1219         rgbtobw( texture2D(ima, STc), Hc );
1220         rgbtobw( texture2D(ima, STl), Hl );
1221         rgbtobw( texture2D(ima, STr), Hr );
1222         rgbtobw( texture2D(ima, STd), Hd );
1223         rgbtobw( texture2D(ima, STu), Hu );
1224         
1225         dBs = hScale * (Hr - Hl);
1226         dBt = hScale * (Hu - Hd);
1227 }
1228
1229 void mtex_bump_apply( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
1230                                           out vec3 vNacc_out, out vec3 perturbed_norm ) 
1231 {
1232         vec3 vSurfGrad = sign(fDet) * ( dBs * vR1 + dBt * vR2 );
1233         
1234         vNacc_out = vNacc_in - vSurfGrad;
1235         perturbed_norm = normalize( vNacc_out );
1236 }
1237
1238 void mtex_bump_apply_texspace( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
1239                                sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
1240                                                            out vec3 vNacc_out, out vec3 perturbed_norm ) 
1241 {
1242         vec2 TexDx = dFdx(texco.xy);
1243         vec2 TexDy = dFdy(texco.xy);
1244
1245         vec3 vSurfGrad = sign(fDet) * ( 
1246                     dBs / length( vec2(ima_x*TexDx.x, ima_y*TexDx.y) ) * vR1 + 
1247                     dBt / length( vec2(ima_x*TexDy.x, ima_y*TexDy.y) ) * vR2 );
1248                                 
1249         vNacc_out = vNacc_in - vSurfGrad;
1250         perturbed_norm = normalize( vNacc_out );
1251 }
1252
1253 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1254 {
1255         outnormal = vec3(-normal.x, -normal.y, normal.z);
1256 }
1257
1258 void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1259 {
1260         vec3 B = tangent.w * cross(normal, tangent.xyz);
1261
1262         outnormal = texnormal.x*tangent.xyz + texnormal.y*B + texnormal.z*normal;
1263         outnormal = normalize(outnormal);
1264 }
1265
1266 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1267 {
1268         outnormal = (1.0 - norfac)*normal + norfac*newnormal;
1269         outnormal = normalize(outnormal);
1270 }
1271
1272 /******* MATERIAL *********/
1273
1274 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1275 {
1276         lv = lampvec;
1277         dist = 1.0;
1278         visifac = 1.0;
1279 }
1280
1281 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1282 {
1283         lv = co - lampco;
1284         dist = length(lv);
1285         lv = normalize(lv);
1286         visifac = 1.0;
1287 }
1288
1289 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1290 {
1291         visifac = lampdist/(lampdist + dist);
1292 }
1293
1294 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1295 {
1296         visifac = lampdist/(lampdist + dist*dist);
1297 }
1298
1299 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1300 {
1301         float lampdistkw = lampdist*lampdist;
1302
1303         visifac = lampdist/(lampdist + ld1*dist);
1304         visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
1305 }
1306
1307 void lamp_falloff_curve(float lampdist, sampler1D curvemap, float dist, out float visifac)
1308 {
1309         visifac = texture1D(curvemap, dist/lampdist).x;
1310 }
1311
1312 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1313 {
1314         float t= lampdist - dist;
1315
1316         outvisifac= visifac*max(t, 0.0)/lampdist;
1317 }
1318
1319 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec3 lv, out float inpr)
1320 {
1321         if(dot(lv, lampvec) > 0.0) {
1322                 vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
1323                 float x = max(abs(lvrot.x/lvrot.z), abs(lvrot.y/lvrot.z));
1324
1325                 inpr = 1.0/sqrt(1.0 + x*x);
1326         }
1327         else
1328                 inpr = 0.0;
1329 }
1330
1331 void lamp_visibility_spot_circle(vec3 lampvec, vec3 lv, out float inpr)
1332 {
1333         inpr = dot(lv, lampvec);
1334 }
1335
1336 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1337 {
1338         float t = spotsi;
1339
1340         if(inpr <= t) {
1341                 outvisifac = 0.0;
1342         }
1343         else {
1344                 t = inpr - t;
1345
1346                 /* soft area */
1347                 if(spotbl != 0.0)
1348                         inpr *= smoothstep(0.0, 1.0, t/spotbl);
1349
1350                 outvisifac = visifac*inpr;
1351         }
1352 }
1353
1354 void lamp_visibility_clamp(float visifac, out float outvisifac)
1355 {
1356         outvisifac = (visifac < 0.001)? 0.0: visifac;
1357 }
1358
1359 void shade_view(vec3 co, out vec3 view)
1360 {
1361         /* handle perspective/orthographic */
1362         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
1363 }
1364
1365 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1366 {
1367         vec3 c = cross(lv, tang);
1368         vec3 vnor = cross(c, tang);
1369
1370         vn = -normalize(vnor);
1371 }
1372
1373 void shade_inp(vec3 vn, vec3 lv, out float inp)
1374 {
1375         inp = dot(vn, lv);
1376 }
1377
1378 void shade_is_no_diffuse(out float is)
1379 {
1380         is = 0.0;
1381 }
1382
1383 void shade_is_hemi(float inp, out float is)
1384 {
1385         is = 0.5*inp + 0.5;
1386 }
1387
1388 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1389 {
1390         vec3 vec[4], c[4];
1391         float rad[4], fac;
1392         
1393         vec[0] = normalize(co - area[0].xyz);
1394         vec[1] = normalize(co - area[1].xyz);
1395         vec[2] = normalize(co - area[2].xyz);
1396         vec[3] = normalize(co - area[3].xyz);
1397
1398         c[0] = normalize(cross(vec[0], vec[1]));
1399         c[1] = normalize(cross(vec[1], vec[2]));
1400         c[2] = normalize(cross(vec[2], vec[3]));
1401         c[3] = normalize(cross(vec[3], vec[0]));
1402
1403         rad[0] = acos(dot(vec[0], vec[1]));
1404         rad[1] = acos(dot(vec[1], vec[2]));
1405         rad[2] = acos(dot(vec[2], vec[3]));
1406         rad[3] = acos(dot(vec[3], vec[0]));
1407
1408         fac=  rad[0]*dot(vn, c[0]);
1409         fac+= rad[1]*dot(vn, c[1]);
1410         fac+= rad[2]*dot(vn, c[2]);
1411         fac+= rad[3]*dot(vn, c[3]);
1412
1413         return max(fac, 0.0);
1414 }
1415
1416 void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
1417 {
1418         vec3 co = position;
1419         vec3 vec = co - lampco;
1420
1421         if(dot(vec, lampvec) < 0.0) {
1422                 inp = 0.0;
1423         }
1424         else {
1425                 float intens = area_lamp_energy(area, co, vn);
1426
1427                 inp = pow(intens*areasize, k);
1428         }
1429 }
1430
1431 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1432 {
1433         vec3 h = normalize(v + l);
1434         float nh = max(dot(n, h), 0.0);
1435         float nv = max(dot(n, v), 0.0);
1436         float realnl = dot(n, l);
1437
1438         if(realnl < 0.0) {
1439                 is = 0.0;
1440         }
1441         else if(nl < 0.0) {
1442                 is = 0.0;
1443         }
1444         else {
1445                 float vh = max(dot(v, h), 0.0);
1446                 float Lit_A = acos(realnl);
1447                 float View_A = acos(nv);
1448
1449                 vec3 Lit_B = normalize(l - realnl*n);
1450                 vec3 View_B = normalize(v - nv*n);
1451
1452                 float t = max(dot(Lit_B, View_B), 0.0);
1453
1454                 float a, b;
1455
1456                 if(Lit_A > View_A) {
1457                         a = Lit_A;
1458                         b = View_A;
1459                 }
1460                 else {
1461                         a = View_A;
1462                         b = Lit_A;
1463                 }
1464
1465                 float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
1466                 float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
1467
1468                 b *= 0.95;
1469                 is = nl*(A + (B * t * sin(a) * tan(b)));
1470         }
1471 }
1472
1473 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1474 {
1475         float rslt = dot(n, l);
1476         float ang = acos(rslt);
1477
1478         if(ang < size) is = 1.0;
1479         else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1480         else is = 1.0 - ((ang - size)/tsmooth);
1481 }
1482
1483 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
1484 {
1485         if(nl <= 0.0) {
1486                 is = 0.0;
1487         }
1488         else {
1489                 float nv = max(dot(n, v), 0.0);
1490
1491                 if(darkness <= 1.0)
1492                         is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
1493                 else
1494                         is = nl*pow(1.0001 - nv, darkness - 1.0);
1495         }
1496 }
1497
1498 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
1499 {
1500         float t1, t2;
1501         float ffac;
1502
1503         if(fac==0.0) {
1504                 ffac = 1.0;
1505         }
1506         else {
1507                 t1= dot(view, vn);
1508                 if(t1>0.0)  t2= 1.0+t1;
1509                 else t2= 1.0-t1;
1510
1511                 t2= grad + (1.0-grad)*pow(t2, fac);
1512
1513                 if(t2<0.0) ffac = 0.0;
1514                 else if(t2>1.0) ffac = 1.0;
1515                 else ffac = t2;
1516         }
1517
1518         return ffac;
1519 }
1520
1521 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
1522 {
1523         is = fresnel_fac(lv, vn, fac_i, fac);
1524 }
1525
1526 void shade_cubic(float is, out float outis)
1527 {
1528         if(is>0.0 && is<1.0)
1529                 outis= smoothstep(0.0, 1.0, is);
1530         else
1531                 outis= is;
1532 }
1533
1534 void shade_visifac(float i, float visifac, float refl, out float outi)
1535 {
1536         /*if(i > 0.0)*/
1537                 outi = max(i*visifac*refl, 0.0);
1538         /*else
1539                 outi = i;*/
1540 }
1541
1542 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
1543 {
1544         vn = tang;
1545 }
1546
1547 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
1548 {
1549         if(i > 0.0)
1550                 outcol = i*lampcol*col;
1551         else
1552                 outcol = vec3(0.0, 0.0, 0.0);
1553 }
1554
1555 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
1556 {
1557         lv += view;
1558         lv = normalize(lv);
1559
1560         t = dot(vn, lv);
1561         t = 0.5*t + 0.5;
1562
1563         t = visifac*spec*pow(t, hard);
1564 }
1565
1566 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1567 {
1568         vec3 h = normalize(l + v);
1569         float rslt = max(dot(h, n), 0.0);
1570
1571         specfac = pow(rslt, hard);
1572 }
1573
1574 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1575 {
1576         vec3 h = normalize(v + l);
1577         float nh = dot(n, h);
1578
1579         if(nh < 0.0) {
1580                 specfac = 0.0;
1581         }
1582         else {
1583                 float nv = max(dot(n, v), 0.0);
1584                 float i = pow(nh, hard);
1585
1586                 i = i/(0.1+nv);
1587                 specfac = i;
1588         }
1589 }
1590
1591 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
1592 {
1593         if(refrac < 1.0) {
1594                 specfac = 0.0;
1595         }
1596         else if(spec_power == 0.0) {
1597                 specfac = 0.0;
1598         }
1599         else {
1600                 if(spec_power<100.0)
1601                         spec_power= sqrt(1.0/spec_power);
1602                 else
1603                         spec_power= 10.0/spec_power;
1604
1605                 vec3 h = normalize(v + l);
1606                 float nh = dot(n, h);
1607                 if(nh < 0.0) {
1608                         specfac = 0.0;
1609                 }
1610                 else {
1611                         float nv = max(dot(n, v), 0.01);
1612                         float nl = dot(n, l);
1613                         if(nl <= 0.01) {
1614                                 specfac = 0.0;
1615                         }
1616                         else {
1617                                 float vh = max(dot(v, h), 0.01);
1618
1619                                 float a = 1.0;
1620                                 float b = (2.0*nh*nv)/vh;
1621                                 float c = (2.0*nh*nl)/vh;
1622
1623                                 float g = 0.0;
1624
1625                                 if(a < b && a < c) g = a;
1626                                 else if(b < a && b < c) g = b;
1627                                 else if(c < a && c < b) g = c;
1628
1629                                 float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
1630                                 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))));
1631                                 float ang = acos(nh);
1632
1633                                 specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
1634                         }
1635                 }
1636         }
1637 }
1638
1639 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
1640 {
1641         vec3 h = normalize(l + v);
1642         float nh = max(dot(n, h), 0.001);
1643         float nv = max(dot(n, v), 0.001);
1644         float nl = max(dot(n, l), 0.001);
1645         float angle = tan(acos(nh));
1646         float alpha = max(rms, 0.001);
1647
1648         specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
1649 }
1650
1651 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
1652 {
1653         vec3 h = normalize(l + v);
1654         float rslt = dot(h, n);
1655         float ang = acos(rslt);
1656
1657         if(ang < size) rslt = 1.0;
1658         else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
1659         else rslt = 1.0 - ((ang - size)/tsmooth);
1660
1661         specfac = rslt;
1662 }
1663
1664 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
1665 {
1666         outspecfac = specfac*inp;
1667 }
1668
1669 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
1670 {
1671         t = shadfac*spec*visifac*specfac;
1672 }
1673
1674 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
1675 {
1676         outcol = t*lampcol*speccol;
1677 }
1678
1679 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
1680 {
1681         outcol = col1 + col2;
1682 }
1683
1684 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1685 {
1686         outcol = col + col1*col2;
1687 }
1688
1689 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
1690 {
1691         outcol = col + f*col1;
1692 }
1693
1694 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
1695 {
1696         outcol = col1*col2;
1697 }
1698
1699 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
1700 {
1701         outcol = col*fac;
1702 }
1703
1704 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1705 {
1706         outcol = vec4(col.rgb*obcol.rgb, col.a);
1707 }
1708
1709 void ramp_rgbtobw(vec3 color, out float outval)
1710 {
1711         outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
1712 }
1713
1714 void shade_only_shadow(float i, float shadfac, float energy, out float outshadfac)
1715 {
1716         outshadfac = i*energy*(1.0 - shadfac);
1717 }
1718
1719 void shade_only_shadow_diffuse(float shadfac, vec3 rgb, vec4 diff, out vec4 outdiff)
1720 {
1721         outdiff = diff - vec4(rgb*shadfac, 0.0);
1722 }
1723
1724 void shade_only_shadow_specular(float shadfac, vec3 specrgb, vec4 spec, out vec4 outspec)
1725 {
1726         outspec = spec - vec4(specrgb*shadfac, 0.0);
1727 }
1728
1729 void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
1730 {
1731         if(inp <= 0.0) {
1732                 result = 0.0;
1733         }
1734         else {
1735                 vec4 co = shadowpersmat*vec4(rco, 1.0);
1736
1737                 //float bias = (1.5 - inp*inp)*shadowbias;
1738                 co.z -= shadowbias*co.w;
1739
1740                 result = shadow2DProj(shadowmap, co).x;
1741         }
1742 }
1743
1744 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
1745 {
1746         outcol = linfac*(1.0 - exp(col*logfac));
1747 }
1748
1749 void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
1750 {
1751         float fac, zcor;
1752
1753         zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
1754         
1755         fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0);
1756         if(misttype == 0.0) fac *= fac;
1757         else if(misttype == 1.0);
1758         else fac = sqrt(fac);
1759
1760         outfac = 1.0 - (1.0-fac)*(1.0-misi);
1761 }
1762
1763 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
1764 {
1765         float fac = clamp(col.a, 0.0, 1.0);
1766         outcol = vec4(mix(hor, col.rgb, fac), col.a);
1767 }
1768
1769 void shade_alpha_opaque(vec4 col, out vec4 outcol)
1770 {
1771         outcol = vec4(col.rgb, 1.0);
1772 }
1773
1774 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1775 {
1776         outcol = vec4(col.rgb, col.a*obcol.a);
1777 }
1778