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