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