small speedup for BM_SelectMode_Flush()
[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 #define M_1_PI 0.31830988618379069
112
113 /*********** SHADER NODES ***************/
114
115 void vcol_attribute(vec4 attvcol, out vec4 vcol)
116 {
117         vcol = vec4(attvcol.x/255.0, attvcol.y/255.0, attvcol.z/255.0, 1.0);
118 }
119
120 void uv_attribute(vec2 attuv, out vec3 uv)
121 {
122         uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0);
123 }
124
125 void geom(vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 attvcol, out vec3 global, out vec3 local, out vec3 view, out vec3 orco, out vec3 uv, out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback)
126 {
127         local = co;
128         view = normalize(local);
129         global = (viewinvmat*vec4(local, 1.0)).xyz;
130         orco = attorco;
131         uv_attribute(attuv, uv);
132         normal = -normalize(nor);       /* blender render normal is negated */
133         vcol_attribute(attvcol, vcol);
134         vcol_alpha = attvcol.a;
135         frontback = 1.0;
136 }
137
138 void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
139 {
140         outvec = (mat * vec4(vec, 1.0)).xyz;
141         if(domin == 1.0)
142                 outvec = max(outvec, minvec);
143         if(domax == 1.0)
144                 outvec = min(outvec, maxvec);
145 }
146
147 void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
148 {
149         outdepth = abs(co.z);
150         outdist = length(co);
151         outview = normalize(co);
152 }
153
154 void math_add(float val1, float val2, out float outval)
155 {
156         outval = val1 + val2;
157 }
158
159 void math_subtract(float val1, float val2, out float outval)
160 {
161         outval = val1 - val2;
162 }
163
164 void math_multiply(float val1, float val2, out float outval)
165 {
166         outval = val1 * val2;
167 }
168
169 void math_divide(float val1, float val2, out float outval)
170 {
171         if (val2 == 0.0)
172                 outval = 0.0;
173         else
174                 outval = val1 / val2;
175 }
176
177 void math_sine(float val, out float outval)
178 {
179         outval = sin(val);
180 }
181
182 void math_cosine(float val, out float outval)
183 {
184         outval = cos(val);
185 }
186
187 void math_tangent(float val, out float outval)
188 {
189         outval = tan(val);
190 }
191
192 void math_asin(float val, out float outval)
193 {
194         if (val <= 1.0 && val >= -1.0)
195                 outval = asin(val);
196         else
197                 outval = 0.0;
198 }
199
200 void math_acos(float val, out float outval)
201 {
202         if (val <= 1.0 && val >= -1.0)
203                 outval = acos(val);
204         else
205                 outval = 0.0;
206 }
207
208 void math_atan(float val, out float outval)
209 {
210         outval = atan(val);
211 }
212
213 void math_pow(float val1, float val2, out float outval)
214 {
215         if (val1 >= 0.0)
216                 outval = pow(val1, val2);
217         else
218                 outval = 0.0;
219 }
220
221 void math_log(float val1, float val2, out float outval)
222 {
223         if(val1 > 0.0  && val2 > 0.0)
224                 outval= log2(val1) / log2(val2);
225         else
226                 outval= 0.0;
227 }
228
229 void math_max(float val1, float val2, out float outval)
230 {
231         outval = max(val1, val2);
232 }
233
234 void math_min(float val1, float val2, out float outval)
235 {
236         outval = min(val1, val2);
237 }
238
239 void math_round(float val, out float outval)
240 {
241         outval= floor(val + 0.5);
242 }
243
244 void math_less_than(float val1, float val2, out float outval)
245 {
246         if(val1 < val2)
247                 outval = 1.0;
248         else
249                 outval = 0.0;
250 }
251
252 void math_greater_than(float val1, float val2, out float outval)
253 {
254         if(val1 > val2)
255                 outval = 1.0;
256         else
257                 outval = 0.0;
258 }
259
260 void squeeze(float val, float width, float center, out float outval)
261 {
262         outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));
263 }
264
265 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
266 {
267         outvec = v1 + v2;
268         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
269 }
270
271 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
272 {
273         outvec = v1 - v2;
274         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
275 }
276
277 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
278 {
279         outvec = v1 + v2;
280         outval = length(outvec);
281         outvec = normalize(outvec);
282 }
283
284 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
285 {
286         outvec = vec3(0, 0, 0);
287         outval = dot(v1, v2);
288 }
289
290 void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
291 {
292         outvec = cross(v1, v2);
293         outval = length(outvec);
294 }
295
296 void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
297 {
298         outval = length(v);
299         outvec = normalize(v);
300 }
301
302 void vec_math_negate(vec3 v, out vec3 outv)
303 {
304         outv = -v;
305 }
306
307 void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
308 {
309         outnor = nor;
310         outdot = -dot(dir, nor);
311 }
312
313 void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
314 {
315         outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x;
316         outvec.y = texture2D(curvemap, vec2((vec.y + 1.0)*0.5, 0.0)).y;
317         outvec.z = texture2D(curvemap, vec2((vec.z + 1.0)*0.5, 0.0)).z;
318
319         if (fac != 1.0)
320                 outvec = (outvec*fac) + (vec*(1.0-fac));
321
322 }
323
324 void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
325 {
326         outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
327         outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
328         outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
329
330         if (fac != 1.0)
331                 outcol = (outcol*fac) + (col*(1.0-fac));
332
333         outcol.a = col.a;
334 }
335
336 void set_value(float val, out float outval)
337 {
338         outval = val;
339 }
340
341 void set_rgb(vec3 col, out vec3 outcol)
342 {
343         outcol = col;
344 }
345
346 void set_rgba(vec4 col, out vec4 outcol)
347 {
348         outcol = col;
349 }
350
351 void set_value_zero(out float outval)
352 {
353         outval = 0.0;
354 }
355
356 void set_value_one(out float outval)
357 {
358         outval = 1.0;
359 }
360
361 void set_rgb_zero(out vec3 outval)
362 {
363         outval = vec3(0.0);
364 }
365
366 void set_rgba_zero(out vec4 outval)
367 {
368         outval = vec4(0.0);
369 }
370
371 void copy_raw(vec4 val, out vec4 outval)
372 {
373         outval = val;
374 }
375
376 void copy_raw(vec3 val, out vec3 outval)
377 {
378         outval = val;
379 }
380
381 void copy_raw(vec2 val, out vec2 outval)
382 {
383         outval = val;
384 }
385
386 void copy_raw(float val, out float outval)
387 {
388         outval = val;
389 }
390
391 void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
392 {
393         fac = clamp(fac, 0.0, 1.0);
394         outcol = mix(col1, col2, fac);
395         outcol.a = col1.a;
396 }
397
398 void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
399 {
400         fac = clamp(fac, 0.0, 1.0);
401         outcol = mix(col1, col1 + col2, fac);
402         outcol.a = col1.a;
403 }
404
405 void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
406 {
407         fac = clamp(fac, 0.0, 1.0);
408         outcol = mix(col1, col1 * col2, fac);
409         outcol.a = col1.a;
410 }
411
412 void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
413 {
414         fac = clamp(fac, 0.0, 1.0);
415         float facm = 1.0 - fac;
416
417         outcol = vec4(1.0) - (vec4(facm) + fac*(vec4(1.0) - col2))*(vec4(1.0) - col1);
418         outcol.a = col1.a;
419 }
420
421 void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
422 {
423         fac = clamp(fac, 0.0, 1.0);
424         float facm = 1.0 - fac;
425
426         outcol = col1;
427
428         if(outcol.r < 0.5)
429                 outcol.r *= facm + 2.0*fac*col2.r;
430         else
431                 outcol.r = 1.0 - (facm + 2.0*fac*(1.0 - col2.r))*(1.0 - outcol.r);
432
433         if(outcol.g < 0.5)
434                 outcol.g *= facm + 2.0*fac*col2.g;
435         else
436                 outcol.g = 1.0 - (facm + 2.0*fac*(1.0 - col2.g))*(1.0 - outcol.g);
437
438         if(outcol.b < 0.5)
439                 outcol.b *= facm + 2.0*fac*col2.b;
440         else
441                 outcol.b = 1.0 - (facm + 2.0*fac*(1.0 - col2.b))*(1.0 - outcol.b);
442 }
443
444 void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
445 {
446         fac = clamp(fac, 0.0, 1.0);
447         outcol = mix(col1, col1 - col2, fac);
448         outcol.a = col1.a;
449 }
450
451 void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
452 {
453         fac = clamp(fac, 0.0, 1.0);
454         float facm = 1.0 - fac;
455
456         outcol = col1;
457
458         if(col2.r != 0.0) outcol.r = facm*outcol.r + fac*outcol.r/col2.r;
459         if(col2.g != 0.0) outcol.g = facm*outcol.g + fac*outcol.g/col2.g;
460         if(col2.b != 0.0) outcol.b = facm*outcol.b + fac*outcol.b/col2.b;
461 }
462
463 void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
464 {
465         fac = clamp(fac, 0.0, 1.0);
466         outcol = mix(col1, abs(col1 - col2), fac);
467         outcol.a = col1.a;
468 }
469
470 void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
471 {
472         fac = clamp(fac, 0.0, 1.0);
473         outcol.rgb = min(col1.rgb, col2.rgb*fac);
474         outcol.a = col1.a;
475 }
476
477 void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
478 {
479         fac = clamp(fac, 0.0, 1.0);
480         outcol.rgb = max(col1.rgb, col2.rgb*fac);
481         outcol.a = col1.a;
482 }
483
484 void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
485 {
486         fac = clamp(fac, 0.0, 1.0);
487         outcol = col1;
488
489         if(outcol.r != 0.0) {
490                 float tmp = 1.0 - fac*col2.r;
491                 if(tmp <= 0.0)
492                         outcol.r = 1.0;
493                 else if((tmp = outcol.r/tmp) > 1.0)
494                         outcol.r = 1.0;
495                 else
496                         outcol.r = tmp;
497         }
498         if(outcol.g != 0.0) {
499                 float tmp = 1.0 - fac*col2.g;
500                 if(tmp <= 0.0)
501                         outcol.g = 1.0;
502                 else if((tmp = outcol.g/tmp) > 1.0)
503                         outcol.g = 1.0;
504                 else
505                         outcol.g = tmp;
506         }
507         if(outcol.b != 0.0) {
508                 float tmp = 1.0 - fac*col2.b;
509                 if(tmp <= 0.0)
510                         outcol.b = 1.0;
511                 else if((tmp = outcol.b/tmp) > 1.0)
512                         outcol.b = 1.0;
513                 else
514                         outcol.b = tmp;
515         }
516 }
517
518 void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
519 {
520         fac = clamp(fac, 0.0, 1.0);
521         float tmp, facm = 1.0 - fac;
522
523         outcol = col1;
524
525         tmp = facm + fac*col2.r;
526         if(tmp <= 0.0)
527                 outcol.r = 0.0;
528         else if((tmp = (1.0 - (1.0 - outcol.r)/tmp)) < 0.0)
529                 outcol.r = 0.0;
530         else if(tmp > 1.0)
531                 outcol.r = 1.0;
532         else
533                 outcol.r = tmp;
534
535         tmp = facm + fac*col2.g;
536         if(tmp <= 0.0)
537                 outcol.g = 0.0;
538         else if((tmp = (1.0 - (1.0 - outcol.g)/tmp)) < 0.0)
539                 outcol.g = 0.0;
540         else if(tmp > 1.0)
541                 outcol.g = 1.0;
542         else
543                 outcol.g = tmp;
544
545         tmp = facm + fac*col2.b;
546         if(tmp <= 0.0)
547                 outcol.b = 0.0;
548         else if((tmp = (1.0 - (1.0 - outcol.b)/tmp)) < 0.0)
549                 outcol.b = 0.0;
550         else if(tmp > 1.0)
551                 outcol.b = 1.0;
552         else
553                 outcol.b = tmp;
554 }
555
556 void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
557 {
558         fac = clamp(fac, 0.0, 1.0);
559         float facm = 1.0 - fac;
560
561         outcol = col1;
562
563         vec4 hsv, hsv2, tmp;
564         rgb_to_hsv(col2, hsv2);
565
566         if(hsv2.y != 0.0) {
567                 rgb_to_hsv(outcol, hsv);
568                 hsv.x = hsv2.x;
569                 hsv_to_rgb(hsv, tmp); 
570
571                 outcol = mix(outcol, tmp, fac);
572                 outcol.a = col1.a;
573         }
574 }
575
576 void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
577 {
578         fac = clamp(fac, 0.0, 1.0);
579         float facm = 1.0 - fac;
580
581         outcol = col1;
582
583         vec4 hsv, hsv2;
584         rgb_to_hsv(outcol, hsv);
585
586         if(hsv.y != 0.0) {
587                 rgb_to_hsv(col2, hsv2);
588
589                 hsv.y = facm*hsv.y + fac*hsv2.y;
590                 hsv_to_rgb(hsv, outcol);
591         }
592 }
593
594 void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
595 {
596         fac = clamp(fac, 0.0, 1.0);
597         float facm = 1.0 - fac;
598
599         vec4 hsv, hsv2;
600         rgb_to_hsv(col1, hsv);
601         rgb_to_hsv(col2, hsv2);
602
603         hsv.z = facm*hsv.z + fac*hsv2.z;
604         hsv_to_rgb(hsv, outcol);
605 }
606
607 void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
608 {
609         fac = clamp(fac, 0.0, 1.0);
610         float facm = 1.0 - fac;
611
612         outcol = col1;
613
614         vec4 hsv, hsv2, tmp;
615         rgb_to_hsv(col2, hsv2);
616
617         if(hsv2.y != 0.0) {
618                 rgb_to_hsv(outcol, hsv);
619                 hsv.x = hsv2.x;
620                 hsv.y = hsv2.y;
621                 hsv_to_rgb(hsv, tmp); 
622
623                 outcol = mix(outcol, tmp, fac);
624                 outcol.a = col1.a;
625         }
626 }
627
628 void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
629 {
630         fac = clamp(fac, 0.0, 1.0);
631         float facm = 1.0 - fac;
632
633         vec4 one= vec4(1.0);
634         vec4 scr= one - (one - col2)*(one - col1);
635         outcol = facm*col1 + fac*((one - col1)*col2*col1 + col1*scr);
636 }
637
638 void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
639 {
640         fac = clamp(fac, 0.0, 1.0);
641
642         outcol = col1;
643
644         if(col2.r > 0.5)
645                 outcol.r= col1.r + fac*(2.0*(col2.r - 0.5));
646         else
647                 outcol.r= col1.r + fac*(2.0*(col2.r) - 1.0);
648
649         if(col2.g > 0.5)
650                 outcol.g= col1.g + fac*(2.0*(col2.g - 0.5));
651         else
652                 outcol.g= col1.g + fac*(2.0*(col2.g) - 1.0);
653
654         if(col2.b > 0.5)
655                 outcol.b= col1.b + fac*(2.0*(col2.b - 0.5));
656         else
657                 outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0);
658 }
659
660 void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
661 {
662         outcol = texture2D(colormap, vec2(fac, 0.0));
663         outalpha = outcol.a;
664 }
665
666 void rgbtobw(vec4 color, out float outval)  
667 {
668         outval = color.r*0.35 + color.g*0.45 + color.b*0.2; /* keep these factors in sync with texture.h:RGBTOBW */
669 }
670
671 void invert(float fac, vec4 col, out vec4 outcol)
672 {
673         outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
674         outcol.w = col.w;
675 }
676
677 void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
678 {
679         vec4 hsv;
680
681         rgb_to_hsv(col, hsv);
682
683         hsv[0] += (hue - 0.5);
684         if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
685         hsv[1] *= sat;
686         if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
687         hsv[2] *= value;
688         if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
689
690         hsv_to_rgb(hsv, outcol);
691
692         outcol = mix(col, outcol, fac);
693 }
694
695 void separate_rgb(vec4 col, out float r, out float g, out float b)
696 {
697         r = col.r;
698         g = col.g;
699         b = col.b;
700 }
701
702 void combine_rgb(float r, float g, float b, out vec4 col)
703 {
704         col = vec4(r, g, b, 1.0);
705 }
706
707 void output_node(vec4 rgb, float alpha, out vec4 outrgb)
708 {
709         outrgb = vec4(rgb.rgb, alpha);
710 }
711
712 /*********** TEXTURES ***************/
713
714 void texture_flip_blend(vec3 vec, out vec3 outvec)
715 {
716         outvec = vec.yxz;
717 }
718
719 void texture_blend_lin(vec3 vec, out float outval)
720 {
721         outval = (1.0+vec.x)/2.0;
722 }
723
724 void texture_blend_quad(vec3 vec, out float outval)
725 {
726         outval = max((1.0+vec.x)/2.0, 0.0);
727         outval *= outval;
728 }
729
730 void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
731 {
732         float a = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z)*20.0;
733         float wi = 0.5 + 0.5*sin(a);
734
735         value = wi;
736         color = vec4(wi, wi, wi, 1.0);
737         normal = vec3(0.0, 0.0, 0.0);
738 }
739
740 void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
741 {
742         color = texture2D(ima, (vec.xy + vec2(1.0, 1.0))*0.5);
743         value = 1.0;
744
745         normal.x = 2.0*(color.r - 0.5);
746         normal.y = 2.0*(0.5 - color.g);
747         normal.z = 2.0*(color.b - 0.5);
748 }
749
750 /************* MTEX *****************/
751
752 void texco_orco(vec3 attorco, out vec3 orco)
753 {
754         orco = attorco;
755 }
756
757 void texco_uv(vec2 attuv, out vec3 uv)
758 {
759         /* disabled for now, works together with leaving out mtex_2d_mapping
760            uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
761         uv = vec3(attuv, 0.0);
762 }
763
764 void texco_norm(vec3 normal, out vec3 outnormal)
765 {
766         /* corresponds to shi->orn, which is negated so cancels
767            out blender normal negation */
768         outnormal = normalize(normal);
769 }
770
771 void texco_tangent(vec4 tangent, out vec3 outtangent)
772 {
773         outtangent = normalize(tangent.xyz);
774 }
775
776 void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
777 {
778         global = (viewinvmat*vec4(co, 1.0)).xyz;
779 }
780
781 void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
782 {
783         object = (obinvmat*(viewinvmat*vec4(co, 1.0))).xyz;
784 }
785
786 void texco_refl(vec3 vn, vec3 view, out vec3 ref)
787 {
788         ref = view - 2.0*dot(vn, view)*vn;
789 }
790
791 void shade_norm(vec3 normal, out vec3 outnormal)
792 {
793         /* blender render normal is negated */
794         outnormal = -normalize(normal);
795 }
796
797 void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
798 {
799         float facm;
800
801         fact *= facg;
802         facm = 1.0-fact;
803
804         incol = fact*texcol + facm*outcol;
805 }
806
807 void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
808 {
809         float facm;
810
811         fact *= facg;
812         facm = 1.0-facg;
813
814         incol = (facm + fact*texcol)*outcol;
815 }
816
817 void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
818 {
819         float facm;
820
821         fact *= facg;
822         facm = 1.0-facg;
823
824         incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
825 }
826
827 void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
828 {
829         float facm;
830
831         fact *= facg;
832         facm = 1.0-facg;
833
834         if(outcol.r < 0.5)
835                 incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
836         else
837                 incol.r = 1.0 - (facm + 2.0*fact*(1.0 - texcol.r))*(1.0 - outcol.r);
838
839         if(outcol.g < 0.5)
840                 incol.g = outcol.g*(facm + 2.0*fact*texcol.g);
841         else
842                 incol.g = 1.0 - (facm + 2.0*fact*(1.0 - texcol.g))*(1.0 - outcol.g);
843
844         if(outcol.b < 0.5)
845                 incol.b = outcol.b*(facm + 2.0*fact*texcol.b);
846         else
847                 incol.b = 1.0 - (facm + 2.0*fact*(1.0 - texcol.b))*(1.0 - outcol.b);
848 }
849
850 void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
851 {
852         incol = -fact*facg*texcol + outcol;
853 }
854
855 void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
856 {
857         incol = fact*facg*texcol + outcol;
858 }
859
860 void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
861 {
862         float facm;
863
864         fact *= facg;
865         facm = 1.0-fact;
866
867         if(texcol.r != 0.0) incol.r = facm*outcol.r + fact*outcol.r/texcol.r;
868         if(texcol.g != 0.0) incol.g = facm*outcol.g + fact*outcol.g/texcol.g;
869         if(texcol.b != 0.0) incol.b = facm*outcol.b + fact*outcol.b/texcol.b;
870 }
871
872 void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
873 {
874         float facm;
875
876         fact *= facg;
877         facm = 1.0-fact;
878
879         incol = facm*outcol + fact*abs(texcol - outcol);
880 }
881
882 void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
883 {
884         float facm, col;
885
886         fact *= facg;
887         facm = 1.0-fact;
888
889         col = fact*texcol.r;
890         if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
891         col = fact*texcol.g;
892         if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
893         col = fact*texcol.b;
894         if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
895 }
896
897 void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
898 {
899         float facm, col;
900
901         fact *= facg;
902         facm = 1.0-fact;
903
904         col = fact*texcol.r;
905         if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
906         col = fact*texcol.g;
907         if(col > outcol.g) incol.g = col; else incol.g = outcol.g;
908         col = fact*texcol.b;
909         if(col > outcol.b) incol.b = col; else incol.b = outcol.b;
910 }
911
912 void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
913 {
914         vec4 col;
915
916         mix_hue(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
917         incol.rgb = col.rgb;
918 }
919
920 void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
921 {
922         vec4 col;
923
924         mix_sat(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
925         incol.rgb = col.rgb;
926 }
927
928 void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
929 {
930         vec4 col;
931
932         mix_val(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
933         incol.rgb = col.rgb;
934 }
935
936 void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
937 {
938         vec4 col;
939
940         mix_color(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
941         incol.rgb = col.rgb;
942 }
943
944 void mtex_value_vars(inout float fact, float facg, out float facm)
945 {
946         fact *= abs(facg);
947         facm = 1.0-fact;
948
949         if(facg < 0.0) {
950                 float tmp = fact;
951                 fact = facm;
952                 facm = tmp;
953         }
954 }
955
956 void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
957 {
958         float facm;
959         mtex_value_vars(fact, facg, facm);
960
961         incol = fact*texcol + facm*outcol;
962 }
963
964 void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
965 {
966         float facm;
967         mtex_value_vars(fact, facg, facm);
968
969         facm = 1.0 - facg;
970         incol = (facm + fact*texcol)*outcol;
971 }
972
973 void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
974 {
975         float facm;
976         mtex_value_vars(fact, facg, facm);
977
978         facm = 1.0 - facg;
979         incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol);
980 }
981
982 void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
983 {
984         float facm;
985         mtex_value_vars(fact, facg, facm);
986
987         fact = -fact;
988         incol = fact*texcol + outcol;
989 }
990
991 void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
992 {
993         float facm;
994         mtex_value_vars(fact, facg, facm);
995
996         fact = fact;
997         incol = fact*texcol + outcol;
998 }
999
1000 void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
1001 {
1002         float facm;
1003         mtex_value_vars(fact, facg, facm);
1004
1005         if(texcol != 0.0)
1006                 incol = facm*outcol + fact*outcol/texcol;
1007         else
1008                 incol = 0.0;
1009 }
1010
1011 void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
1012 {
1013         float facm;
1014         mtex_value_vars(fact, facg, facm);
1015
1016         incol = facm*outcol + fact*abs(texcol - outcol);
1017 }
1018
1019 void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
1020 {
1021         float facm;
1022         mtex_value_vars(fact, facg, facm);
1023
1024         float col = fact*texcol;
1025         if(col < outcol) incol = col; else incol = outcol;
1026 }
1027
1028 void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
1029 {
1030         float facm;
1031         mtex_value_vars(fact, facg, facm);
1032
1033         float col = fact*texcol;
1034         if(col > outcol) incol = col; else incol = outcol;
1035 }
1036
1037 void mtex_value_clamp_positive(float fac, out float outfac)
1038 {
1039         outfac = max(fac, 0.0);
1040 }
1041
1042 void mtex_value_clamp(float fac, out float outfac)
1043 {
1044         outfac = clamp(fac, 0.0, 1.0);
1045 }
1046
1047 void mtex_har_divide(float har, out float outhar)
1048 {
1049         outhar = har/128.0;
1050 }
1051
1052 void mtex_har_multiply_clamp(float har, out float outhar)
1053 {
1054         har *= 128.0;
1055
1056         if(har < 1.0) outhar = 1.0;
1057         else if(har > 511.0) outhar = 511.0;
1058         else outhar = har;
1059 }
1060
1061 void mtex_alpha_from_col(vec4 col, out float alpha)
1062 {
1063         alpha = col.a;
1064 }
1065
1066 void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
1067 {
1068         outcol = vec4(col.rgb, alpha);
1069 }
1070
1071 void mtex_rgbtoint(vec4 rgb, out float intensity)
1072 {
1073         intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
1074 }
1075
1076 void mtex_value_invert(float invalue, out float outvalue)
1077 {
1078         outvalue = 1.0 - invalue;
1079 }
1080
1081 void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
1082 {
1083         outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
1084 }
1085
1086 void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
1087 {
1088         float fact = intensity;
1089         outintensity = intensity*stencil;
1090         outstencil = stencil*fact;
1091 }
1092
1093 void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
1094 {
1095         float fact = rgb.a;
1096         outrgb = vec4(rgb.rgb, rgb.a*stencil);
1097         outstencil = stencil*fact;
1098 }
1099
1100 void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
1101 {
1102         outtexco = texco + ofs;
1103 }
1104
1105 void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
1106 {
1107         outtexco = size*texco;
1108 }
1109
1110 void mtex_2d_mapping(vec3 vec, out vec3 outvec)
1111 {
1112         outvec = vec3(vec.xy*0.5 + vec2(0.5, 0.5), vec.z);
1113 }
1114
1115 void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
1116 {
1117         color = texture2D(ima, texco.xy);
1118         value = 1.0;
1119 }
1120
1121 void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
1122 {
1123         // The invert of the red channel is to make
1124         // the normal map compliant with the outside world.
1125         // It needs to be done because in Blender
1126         // the normal used points inward.
1127         // Should this ever change this negate must be removed.
1128     vec4 color = texture2D(ima, texco.xy);
1129         normal = 2.0*(vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
1130 }
1131
1132 void mtex_bump_normals_init( vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude )
1133 {
1134         vNorg = vN;
1135         vNacc = vN;
1136         fPrevMagnitude = 1.0;
1137 }
1138
1139 /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
1140 mat3 to_mat3(mat4 m4)
1141 {
1142         mat3 m3;
1143         m3[0] = m4[0].xyz;
1144         m3[1] = m4[1].xyz;
1145         m3[2] = m4[2].xyz;
1146         return m3;
1147 }
1148
1149 void mtex_bump_init_objspace( vec3 surf_pos, vec3 surf_norm,
1150                                                           mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv, 
1151                                                           float fPrevMagnitude_in, vec3 vNacc_in,
1152                                                           out float fPrevMagnitude_out, out vec3 vNacc_out, 
1153                                                           out vec3 vR1, out vec3 vR2, out float fDet ) 
1154 {
1155         mat3 obj2view = to_mat3(gl_ModelViewMatrix);
1156         mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse);
1157         
1158         vec3 vSigmaS = view2obj * dFdx( surf_pos );
1159         vec3 vSigmaT = view2obj * dFdy( surf_pos );
1160         vec3 vN = normalize( surf_norm * obj2view );
1161
1162         vR1 = cross( vSigmaT, vN );
1163         vR2 = cross( vN, vSigmaS ) ;
1164         fDet = dot ( vSigmaS, vR1 );
1165         
1166         /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */
1167         vR1 = vR1 * view2obj;
1168         vR2 = vR2 * view2obj;
1169         vN = vN * view2obj;
1170         
1171         float fMagnitude = abs(fDet) * length(vN);
1172         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1173         fPrevMagnitude_out = fMagnitude;
1174 }
1175
1176 void mtex_bump_init_texturespace( vec3 surf_pos, vec3 surf_norm, 
1177                                                                   float fPrevMagnitude_in, vec3 vNacc_in,
1178                                                                   out float fPrevMagnitude_out, out vec3 vNacc_out, 
1179                                                                   out vec3 vR1, out vec3 vR2, out float fDet ) 
1180 {
1181         vec3 vSigmaS = dFdx( surf_pos );
1182         vec3 vSigmaT = dFdy( surf_pos );
1183         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1184         
1185         vR1 = normalize( cross( vSigmaT, vN ) );
1186         vR2 = normalize( cross( vN, vSigmaS ) );
1187         fDet = sign( dot(vSigmaS, vR1) );
1188         
1189         float fMagnitude = abs(fDet);
1190         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1191         fPrevMagnitude_out = fMagnitude;
1192 }
1193
1194 void mtex_bump_init_viewspace( vec3 surf_pos, vec3 surf_norm, 
1195                                                            float fPrevMagnitude_in, vec3 vNacc_in,
1196                                                            out float fPrevMagnitude_out, out vec3 vNacc_out, 
1197                                                            out vec3 vR1, out vec3 vR2, out float fDet ) 
1198 {
1199         vec3 vSigmaS = dFdx( surf_pos );
1200         vec3 vSigmaT = dFdy( surf_pos );
1201         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1202         
1203         vR1 = cross( vSigmaT, vN );
1204         vR2 = cross( vN, vSigmaS ) ;
1205         fDet = dot ( vSigmaS, vR1 );
1206         
1207         float fMagnitude = abs(fDet);
1208         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1209         fPrevMagnitude_out = fMagnitude;
1210 }
1211
1212 void mtex_bump_tap3( vec3 texco, sampler2D ima, float hScale, 
1213                      out float dBs, out float dBt ) 
1214 {
1215         vec2 STll = texco.xy;
1216         vec2 STlr = texco.xy + dFdx(texco.xy) ;
1217         vec2 STul = texco.xy + dFdy(texco.xy) ;
1218         
1219         float Hll,Hlr,Hul;
1220         rgbtobw( texture2D(ima, STll), Hll );
1221         rgbtobw( texture2D(ima, STlr), Hlr );
1222         rgbtobw( texture2D(ima, STul), Hul );
1223         
1224         dBs = hScale * (Hlr - Hll);
1225         dBt = hScale * (Hul - Hll);
1226 }
1227
1228 #ifdef BUMP_BICUBIC
1229
1230 void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale, 
1231                      out float dBs, out float dBt ) 
1232 {
1233         float Hl;
1234         float Hr;
1235         float Hd;
1236         float Hu;
1237         
1238         vec2 TexDx = dFdx(texco.xy);
1239         vec2 TexDy = dFdy(texco.xy);
1240  
1241         vec2 STl = texco.xy - 0.5 * TexDx ;
1242         vec2 STr = texco.xy + 0.5 * TexDx ;
1243         vec2 STd = texco.xy - 0.5 * TexDy ;
1244         vec2 STu = texco.xy + 0.5 * TexDy ;
1245         
1246         rgbtobw(texture2D(ima, STl), Hl);
1247         rgbtobw(texture2D(ima, STr), Hr);
1248         rgbtobw(texture2D(ima, STd), Hd);
1249         rgbtobw(texture2D(ima, STu), Hu);
1250         
1251         vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
1252         float fBlend = clamp(1.0-textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
1253         if(fBlend!=0.0)
1254         {
1255                 // the derivative of the bicubic sampling of level 0
1256                 ivec2 vDim;
1257                 vDim = textureSize(ima, 0);
1258
1259                 // taking the fract part of the texture coordinate is a hardcoded wrap mode.
1260                 // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender. 
1261                 // this is done so that we can still get a valid texel with uvs outside the 0,1 range
1262                 // by texelFetch below, as coordinates are clamped when using this function.
1263                 vec2 fTexLoc = vDim*fract(texco.xy) - vec2(0.5, 0.5);
1264                 ivec2 iTexLoc = ivec2(floor(fTexLoc));
1265                 vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0);            // sat just to be pedantic
1266
1267 /*******************************************************************************************
1268  * This block will replace the one below when one channel textures are properly supported. *
1269  *******************************************************************************************
1270                 vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim );
1271                 vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim );
1272                 vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim );
1273                 vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim );
1274
1275                 mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
1276                                         vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
1277                                         vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
1278                                         vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
1279 */      
1280                 ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
1281
1282                 mat4 H;
1283                 
1284                 for(int i = 0; i < 4; i++){
1285                         for(int j = 0; j < 4; j++){
1286                                 ivec2 iTexTmp = iTexLocMod + ivec2(i,j);
1287                                 
1288                                 // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range.
1289                                 // this is guaranteed to work since we take the fractional part of the uv above.
1290                                 iTexTmp.x = (iTexTmp.x < 0)? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x)? iTexTmp.x - vDim.x : iTexTmp.x);
1291                                 iTexTmp.y = (iTexTmp.y < 0)? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y)? iTexTmp.y - vDim.y : iTexTmp.y);
1292
1293                                 rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]);
1294                         }
1295                 }
1296                 
1297                 float x = t.x, y = t.y;
1298                 float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y;
1299
1300                 vec4 X = vec4(-0.5*(x3+x)+x2,           1.5*x3-2.5*x2+1,        -1.5*x3+2*x2+0.5*x,             0.5*(x3-x2));
1301                 vec4 Y = vec4(-0.5*(y3+y)+y2,           1.5*y3-2.5*y2+1,        -1.5*y3+2*y2+0.5*y,             0.5*(y3-y2));
1302                 vec4 dX = vec4(-1.5*x2+2*x-0.5,         4.5*x2-5*x,                     -4.5*x2+4*x+0.5,                1.5*x2-x);
1303                 vec4 dY = vec4(-1.5*y2+2*y-0.5,         4.5*y2-5*y,                     -4.5*y2+4*y+0.5,                1.5*y2-y);
1304         
1305                 // complete derivative in normalized coordinates (mul by vDim)
1306                 vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X));
1307
1308                 // transform derivative to screen-space
1309                 vec2 dHdxy_bicubic = vec2( dHdST.x * TexDx.x + dHdST.y * TexDx.y,
1310                                                                    dHdST.x * TexDy.x + dHdST.y * TexDy.y );
1311
1312                 // blend between the two
1313                 dHdxy = dHdxy*(1-fBlend) + dHdxy_bicubic*fBlend;
1314         }
1315
1316         dBs = hScale * dHdxy.x;
1317         dBt = hScale * dHdxy.y;
1318 }
1319
1320 #endif
1321
1322 void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale, 
1323                      out float dBs, out float dBt ) 
1324 {
1325         vec2 TexDx = dFdx(texco.xy);
1326         vec2 TexDy = dFdy(texco.xy);
1327
1328         vec2 STc = texco.xy;
1329         vec2 STl = texco.xy - 0.5 * TexDx ;
1330         vec2 STr = texco.xy + 0.5 * TexDx ;
1331         vec2 STd = texco.xy - 0.5 * TexDy ;
1332         vec2 STu = texco.xy + 0.5 * TexDy ;
1333         
1334         float Hc,Hl,Hr,Hd,Hu;
1335         rgbtobw( texture2D(ima, STc), Hc );
1336         rgbtobw( texture2D(ima, STl), Hl );
1337         rgbtobw( texture2D(ima, STr), Hr );
1338         rgbtobw( texture2D(ima, STd), Hd );
1339         rgbtobw( texture2D(ima, STu), Hu );
1340         
1341         dBs = hScale * (Hr - Hl);
1342         dBt = hScale * (Hu - Hd);
1343 }
1344
1345 void mtex_bump_deriv( vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, 
1346                      out float dBs, out float dBt ) 
1347 {
1348         float s = 1.0;          // negate this if flipped texture coordinate
1349         vec2 TexDx = dFdx(texco.xy);
1350         vec2 TexDy = dFdy(texco.xy);
1351         
1352         // this variant using a derivative map is described here
1353         // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
1354         vec2 dim = vec2(ima_x, ima_y);
1355         vec2 dBduv = hScale*dim*(2.0*texture2D(ima, texco.xy).xy-1.0);
1356         
1357         dBs = dBduv.x*TexDx.x + s*dBduv.y*TexDx.y;
1358         dBt = dBduv.x*TexDy.x + s*dBduv.y*TexDy.y;
1359 }
1360
1361 void mtex_bump_apply( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
1362                                           out vec3 vNacc_out, out vec3 perturbed_norm ) 
1363 {
1364         vec3 vSurfGrad = sign(fDet) * ( dBs * vR1 + dBt * vR2 );
1365         
1366         vNacc_out = vNacc_in - vSurfGrad;
1367         perturbed_norm = normalize( vNacc_out );
1368 }
1369
1370 void mtex_bump_apply_texspace( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
1371                                sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
1372                                                            out vec3 vNacc_out, out vec3 perturbed_norm ) 
1373 {
1374         vec2 TexDx = dFdx(texco.xy);
1375         vec2 TexDy = dFdy(texco.xy);
1376
1377         vec3 vSurfGrad = sign(fDet) * ( 
1378                     dBs / length( vec2(ima_x*TexDx.x, ima_y*TexDx.y) ) * vR1 + 
1379                     dBt / length( vec2(ima_x*TexDy.x, ima_y*TexDy.y) ) * vR2 );
1380                                 
1381         vNacc_out = vNacc_in - vSurfGrad;
1382         perturbed_norm = normalize( vNacc_out );
1383 }
1384
1385 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1386 {
1387         outnormal = vec3(-normal.x, -normal.y, normal.z);
1388 }
1389
1390 void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1391 {
1392         vec3 B = tangent.w * cross(normal, tangent.xyz);
1393
1394         outnormal = texnormal.x*tangent.xyz + texnormal.y*B + texnormal.z*normal;
1395         outnormal = normalize(outnormal);
1396 }
1397
1398 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1399 {
1400         outnormal = (1.0 - norfac)*normal + norfac*newnormal;
1401         outnormal = normalize(outnormal);
1402 }
1403
1404 /******* MATERIAL *********/
1405
1406 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1407 {
1408         lv = lampvec;
1409         dist = 1.0;
1410         visifac = 1.0;
1411 }
1412
1413 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1414 {
1415         lv = co - lampco;
1416         dist = length(lv);
1417         lv = normalize(lv);
1418         visifac = 1.0;
1419 }
1420
1421 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1422 {
1423         visifac = lampdist/(lampdist + dist);
1424 }
1425
1426 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1427 {
1428         visifac = lampdist/(lampdist + dist*dist);
1429 }
1430
1431 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1432 {
1433         float lampdistkw = lampdist*lampdist;
1434
1435         visifac = lampdist/(lampdist + ld1*dist);
1436         visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
1437 }
1438
1439 void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
1440 {
1441         visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x;
1442 }
1443
1444 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1445 {
1446         float t= lampdist - dist;
1447
1448         outvisifac= visifac*max(t, 0.0)/lampdist;
1449 }
1450
1451 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec3 lv, out float inpr)
1452 {
1453         if(dot(lv, lampvec) > 0.0) {
1454                 vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
1455                 float x = max(abs(lvrot.x/lvrot.z), abs(lvrot.y/lvrot.z));
1456
1457                 inpr = 1.0/sqrt(1.0 + x*x);
1458         }
1459         else
1460                 inpr = 0.0;
1461 }
1462
1463 void lamp_visibility_spot_circle(vec3 lampvec, vec3 lv, out float inpr)
1464 {
1465         inpr = dot(lv, lampvec);
1466 }
1467
1468 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1469 {
1470         float t = spotsi;
1471
1472         if(inpr <= t) {
1473                 outvisifac = 0.0;
1474         }
1475         else {
1476                 t = inpr - t;
1477
1478                 /* soft area */
1479                 if(spotbl != 0.0)
1480                         inpr *= smoothstep(0.0, 1.0, t/spotbl);
1481
1482                 outvisifac = visifac*inpr;
1483         }
1484 }
1485
1486 void lamp_visibility_clamp(float visifac, out float outvisifac)
1487 {
1488         outvisifac = (visifac < 0.001)? 0.0: visifac;
1489 }
1490
1491 void shade_view(vec3 co, out vec3 view)
1492 {
1493         /* handle perspective/orthographic */
1494         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
1495 }
1496
1497 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1498 {
1499         vec3 c = cross(lv, tang);
1500         vec3 vnor = cross(c, tang);
1501
1502         vn = -normalize(vnor);
1503 }
1504
1505 void shade_inp(vec3 vn, vec3 lv, out float inp)
1506 {
1507         inp = dot(vn, lv);
1508 }
1509
1510 void shade_is_no_diffuse(out float is)
1511 {
1512         is = 0.0;
1513 }
1514
1515 void shade_is_hemi(float inp, out float is)
1516 {
1517         is = 0.5*inp + 0.5;
1518 }
1519
1520 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1521 {
1522         vec3 vec[4], c[4];
1523         float rad[4], fac;
1524         
1525         vec[0] = normalize(co - area[0].xyz);
1526         vec[1] = normalize(co - area[1].xyz);
1527         vec[2] = normalize(co - area[2].xyz);
1528         vec[3] = normalize(co - area[3].xyz);
1529
1530         c[0] = normalize(cross(vec[0], vec[1]));
1531         c[1] = normalize(cross(vec[1], vec[2]));
1532         c[2] = normalize(cross(vec[2], vec[3]));
1533         c[3] = normalize(cross(vec[3], vec[0]));
1534
1535         rad[0] = acos(dot(vec[0], vec[1]));
1536         rad[1] = acos(dot(vec[1], vec[2]));
1537         rad[2] = acos(dot(vec[2], vec[3]));
1538         rad[3] = acos(dot(vec[3], vec[0]));
1539
1540         fac=  rad[0]*dot(vn, c[0]);
1541         fac+= rad[1]*dot(vn, c[1]);
1542         fac+= rad[2]*dot(vn, c[2]);
1543         fac+= rad[3]*dot(vn, c[3]);
1544
1545         return max(fac, 0.0);
1546 }
1547
1548 void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
1549 {
1550         vec3 co = position;
1551         vec3 vec = co - lampco;
1552
1553         if(dot(vec, lampvec) < 0.0) {
1554                 inp = 0.0;
1555         }
1556         else {
1557                 float intens = area_lamp_energy(area, co, vn);
1558
1559                 inp = pow(intens*areasize, k);
1560         }
1561 }
1562
1563 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1564 {
1565         vec3 h = normalize(v + l);
1566         float nh = max(dot(n, h), 0.0);
1567         float nv = max(dot(n, v), 0.0);
1568         float realnl = dot(n, l);
1569
1570         if(realnl < 0.0) {
1571                 is = 0.0;
1572         }
1573         else if(nl < 0.0) {
1574                 is = 0.0;
1575         }
1576         else {
1577                 float vh = max(dot(v, h), 0.0);
1578                 float Lit_A = acos(realnl);
1579                 float View_A = acos(nv);
1580
1581                 vec3 Lit_B = normalize(l - realnl*n);
1582                 vec3 View_B = normalize(v - nv*n);
1583
1584                 float t = max(dot(Lit_B, View_B), 0.0);
1585
1586                 float a, b;
1587
1588                 if(Lit_A > View_A) {
1589                         a = Lit_A;
1590                         b = View_A;
1591                 }
1592                 else {
1593                         a = View_A;
1594                         b = Lit_A;
1595                 }
1596
1597                 float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
1598                 float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
1599
1600                 b *= 0.95;
1601                 is = nl*(A + (B * t * sin(a) * tan(b)));
1602         }
1603 }
1604
1605 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1606 {
1607         float rslt = dot(n, l);
1608         float ang = acos(rslt);
1609
1610         if(ang < size) is = 1.0;
1611         else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1612         else is = 1.0 - ((ang - size)/tsmooth);
1613 }
1614
1615 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
1616 {
1617         if(nl <= 0.0) {
1618                 is = 0.0;
1619         }
1620         else {
1621                 float nv = max(dot(n, v), 0.0);
1622
1623                 if(darkness <= 1.0)
1624                         is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
1625                 else
1626                         is = nl*pow(1.0001 - nv, darkness - 1.0);
1627         }
1628 }
1629
1630 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
1631 {
1632         float t1, t2;
1633         float ffac;
1634
1635         if(fac==0.0) {
1636                 ffac = 1.0;
1637         }
1638         else {
1639                 t1= dot(view, vn);
1640                 if(t1>0.0)  t2= 1.0+t1;
1641                 else t2= 1.0-t1;
1642
1643                 t2= grad + (1.0-grad)*pow(t2, fac);
1644
1645                 if(t2<0.0) ffac = 0.0;
1646                 else if(t2>1.0) ffac = 1.0;
1647                 else ffac = t2;
1648         }
1649
1650         return ffac;
1651 }
1652
1653 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
1654 {
1655         is = fresnel_fac(lv, vn, fac_i, fac);
1656 }
1657
1658 void shade_cubic(float is, out float outis)
1659 {
1660         if(is>0.0 && is<1.0)
1661                 outis= smoothstep(0.0, 1.0, is);
1662         else
1663                 outis= is;
1664 }
1665
1666 void shade_visifac(float i, float visifac, float refl, out float outi)
1667 {
1668         /*if(i > 0.0)*/
1669                 outi = max(i*visifac*refl, 0.0);
1670         /*else
1671                 outi = i;*/
1672 }
1673
1674 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
1675 {
1676         vn = tang;
1677 }
1678
1679 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
1680 {
1681         if(i > 0.0)
1682                 outcol = i*lampcol*col;
1683         else
1684                 outcol = vec3(0.0, 0.0, 0.0);
1685 }
1686
1687 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
1688 {
1689         lv += view;
1690         lv = normalize(lv);
1691
1692         t = dot(vn, lv);
1693         t = 0.5*t + 0.5;
1694
1695         t = visifac*spec*pow(t, hard);
1696 }
1697
1698 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1699 {
1700         vec3 h = normalize(l + v);
1701         float rslt = max(dot(h, n), 0.0);
1702
1703         specfac = pow(rslt, hard);
1704 }
1705
1706 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1707 {
1708         vec3 h = normalize(v + l);
1709         float nh = dot(n, h);
1710
1711         if(nh < 0.0) {
1712                 specfac = 0.0;
1713         }
1714         else {
1715                 float nv = max(dot(n, v), 0.0);
1716                 float i = pow(nh, hard);
1717
1718                 i = i/(0.1+nv);
1719                 specfac = i;
1720         }
1721 }
1722
1723 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
1724 {
1725         if(refrac < 1.0) {
1726                 specfac = 0.0;
1727         }
1728         else if(spec_power == 0.0) {
1729                 specfac = 0.0;
1730         }
1731         else {
1732                 if(spec_power<100.0)
1733                         spec_power= sqrt(1.0/spec_power);
1734                 else
1735                         spec_power= 10.0/spec_power;
1736
1737                 vec3 h = normalize(v + l);
1738                 float nh = dot(n, h);
1739                 if(nh < 0.0) {
1740                         specfac = 0.0;
1741                 }
1742                 else {
1743                         float nv = max(dot(n, v), 0.01);
1744                         float nl = dot(n, l);
1745                         if(nl <= 0.01) {
1746                                 specfac = 0.0;
1747                         }
1748                         else {
1749                                 float vh = max(dot(v, h), 0.01);
1750
1751                                 float a = 1.0;
1752                                 float b = (2.0*nh*nv)/vh;
1753                                 float c = (2.0*nh*nl)/vh;
1754
1755                                 float g = 0.0;
1756
1757                                 if(a < b && a < c) g = a;
1758                                 else if(b < a && b < c) g = b;
1759                                 else if(c < a && c < b) g = c;
1760
1761                                 float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
1762                                 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))));
1763                                 float ang = acos(nh);
1764
1765                                 specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
1766                         }
1767                 }
1768         }
1769 }
1770
1771 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
1772 {
1773         vec3 h = normalize(l + v);
1774         float nh = max(dot(n, h), 0.001);
1775         float nv = max(dot(n, v), 0.001);
1776         float nl = max(dot(n, l), 0.001);
1777         float angle = tan(acos(nh));
1778         float alpha = max(rms, 0.001);
1779
1780         specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
1781 }
1782
1783 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
1784 {
1785         vec3 h = normalize(l + v);
1786         float rslt = dot(h, n);
1787         float ang = acos(rslt);
1788
1789         if(ang < size) rslt = 1.0;
1790         else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
1791         else rslt = 1.0 - ((ang - size)/tsmooth);
1792
1793         specfac = rslt;
1794 }
1795
1796 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
1797 {
1798         outspecfac = specfac*inp;
1799 }
1800
1801 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
1802 {
1803         t = shadfac*spec*visifac*specfac;
1804 }
1805
1806 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
1807 {
1808         outcol = t*lampcol*speccol;
1809 }
1810
1811 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
1812 {
1813         outcol = col1 + col2;
1814 }
1815
1816 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1817 {
1818         outcol = col + col1*col2;
1819 }
1820
1821 void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
1822 {
1823         outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0));
1824 }
1825
1826 void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1827 {
1828         outcol = col + max(col1*col2, vec4(0.0, 0.0, 0.0, 0.0));
1829 }
1830
1831 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
1832 {
1833         outcol = col + f*col1;
1834 }
1835
1836 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
1837 {
1838         outcol = col1*col2;
1839 }
1840
1841 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
1842 {
1843         outcol = col*fac;
1844 }
1845
1846 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1847 {
1848         outcol = vec4(col.rgb*obcol.rgb, col.a);
1849 }
1850
1851 void ramp_rgbtobw(vec3 color, out float outval)
1852 {
1853         outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
1854 }
1855
1856 void shade_only_shadow(float i, float shadfac, float energy, out float outshadfac)
1857 {
1858         outshadfac = i*energy*(1.0 - shadfac);
1859 }
1860
1861 void shade_only_shadow_diffuse(float shadfac, vec3 rgb, vec4 diff, out vec4 outdiff)
1862 {
1863         outdiff = diff - vec4(rgb*shadfac, 0.0);
1864 }
1865
1866 void shade_only_shadow_specular(float shadfac, vec3 specrgb, vec4 spec, out vec4 outspec)
1867 {
1868         outspec = spec - vec4(specrgb*shadfac, 0.0);
1869 }
1870
1871 void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
1872 {
1873         if(inp <= 0.0) {
1874                 result = 0.0;
1875         }
1876         else {
1877                 vec4 co = shadowpersmat*vec4(rco, 1.0);
1878
1879                 //float bias = (1.5 - inp*inp)*shadowbias;
1880                 co.z -= shadowbias*co.w;
1881
1882                 result = shadow2DProj(shadowmap, co).x;
1883         }
1884 }
1885
1886 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
1887 {
1888         outcol = linfac*(1.0 - exp(col*logfac));
1889 }
1890
1891 void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
1892 {
1893         float fac, zcor;
1894
1895         zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
1896         
1897         fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0);
1898         if(misttype == 0.0) fac *= fac;
1899         else if(misttype == 1.0);
1900         else fac = sqrt(fac);
1901
1902         outfac = 1.0 - (1.0-fac)*(1.0-misi);
1903 }
1904
1905 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
1906 {
1907         float fac = clamp(col.a, 0.0, 1.0);
1908         outcol = vec4(mix(hor, col.rgb, fac), col.a);
1909 }
1910
1911 void shade_alpha_opaque(vec4 col, out vec4 outcol)
1912 {
1913         outcol = vec4(col.rgb, 1.0);
1914 }
1915
1916 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1917 {
1918         outcol = vec4(col.rgb, col.a*obcol.a);
1919 }
1920
1921 /*********** NEW SHADER UTILITIES **************/
1922
1923 float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
1924 {
1925     /* compute fresnel reflectance without explicitly computing
1926        the refracted direction */
1927     float c = abs(dot(Incoming, Normal));
1928     float g = eta * eta - 1.0 + c * c;
1929     float result;
1930
1931     if(g > 0.0) {
1932         g = sqrt(g);
1933         float A =(g - c)/(g + c);
1934         float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
1935         result = 0.5 * A * A *(1.0 + B * B);
1936     }
1937     else
1938         result = 1.0;  /* TIR (no refracted component) */
1939
1940     return result;
1941 }
1942
1943 float hypot(float x, float y)
1944 {
1945         return sqrt(x*x + y*y);
1946 }
1947
1948 /*********** NEW SHADER NODES ***************/
1949
1950 #define NUM_LIGHTS 3
1951
1952 /* bsdfs */
1953
1954 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
1955 {
1956         /* ambient light */
1957         vec3 L = vec3(0.2);
1958
1959         /* directional lights */
1960         for(int i = 0; i < NUM_LIGHTS; i++) {
1961                 vec3 light_position = gl_LightSource[i].position.xyz;
1962                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
1963
1964                 float bsdf = max(dot(N, light_position), 0.0);
1965                 L += light_diffuse*bsdf;
1966         }
1967
1968         result = vec4(L*color.rgb, 1.0);
1969 }
1970
1971 void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result)
1972 {
1973         /* ambient light */
1974         vec3 L = vec3(0.2);
1975
1976         /* directional lights */
1977         for(int i = 0; i < NUM_LIGHTS; i++) {
1978                 vec3 light_position = gl_LightSource[i].position.xyz;
1979                 vec3 H = gl_LightSource[i].halfVector.xyz;
1980                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
1981                 vec3 light_specular = gl_LightSource[i].specular.rgb;
1982
1983                 /* we mix in some diffuse so low roughness still shows up */
1984                 float bsdf = 0.5*pow(max(dot(N, H), 0.0), 1.0/roughness);
1985                 bsdf += 0.5*max(dot(N, light_position), 0.0);
1986                 L += light_specular*bsdf;
1987         }
1988
1989         result = vec4(L*color.rgb, 1.0);
1990 }
1991
1992 void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 I, out vec4 result)
1993 {
1994         node_bsdf_diffuse(color, 0.0, N, result);
1995 }
1996
1997 void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result)
1998 {
1999         node_bsdf_diffuse(color, 0.0, N, result);
2000 }
2001
2002 void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
2003 {
2004         node_bsdf_diffuse(color, 0.0, N, result);
2005 }
2006
2007 void node_bsdf_transparent(vec4 color, out vec4 result)
2008 {
2009         /* this isn't right */
2010         result.r = color.r;
2011         result.g = color.g;
2012         result.b = color.b;
2013         result.a = 0.0;
2014 }
2015
2016 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
2017 {
2018         node_bsdf_diffuse(color, 0.0, N, result);
2019 }
2020
2021 /* emission */
2022
2023 void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
2024 {
2025         result = color*strength;
2026 }
2027
2028 /* closures */
2029
2030 void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
2031 {
2032         shader = mix(shader1, shader2, fac);
2033 }
2034
2035 void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
2036 {
2037         shader = shader1 + shader2;
2038 }
2039
2040 /* fresnel */
2041
2042 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
2043 {
2044         float eta = max(ior, 0.00001);
2045         result = fresnel_dielectric(I, N, eta); //backfacing()? 1.0/eta: eta);
2046 }
2047
2048 /* geometry */
2049
2050 void node_geometry(vec3 I, vec3 N, mat4 toworld,
2051         out vec3 position, out vec3 normal, out vec3 tangent,
2052         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
2053         out float backfacing)
2054 {
2055         position = (toworld*vec4(I, 1.0)).xyz;
2056         normal = N;
2057         tangent = vec3(0.0);
2058         true_normal = N;
2059         incoming = I;
2060         parametric = vec3(0.0);
2061         backfacing = 0.0;
2062 }
2063
2064 void node_tex_coord(vec3 I, vec3 N, mat4 toworld,
2065         vec3 attr_orco, vec3 attr_uv,
2066         out vec3 generated, out vec3 uv, out vec3 object,
2067         out vec3 camera, out vec3 window, out vec3 reflection)
2068 {
2069         generated = attr_orco;
2070         uv = attr_uv;
2071         object = I;
2072         camera = I;
2073         window = gl_FragCoord.xyz;
2074         reflection = reflect(N, I);
2075
2076 }
2077
2078 /* textures */
2079
2080 void node_tex_blend(vec3 co, out float fac)
2081 {
2082         fac = 1.0;
2083 }
2084
2085 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
2086 {
2087         color = vec4(1.0);
2088         fac = 1.0;
2089 }
2090
2091 void node_tex_distnoise(vec3 co, float size, float distortion, out float fac)
2092 {
2093         fac = 1.0;
2094 }
2095
2096 void node_tex_environment(vec3 co, sampler2D ima, out vec4 color)
2097 {
2098         float u = (atan(co.y, co.x) + M_PI)/(2.0*M_PI);
2099         float v = atan(co.z, hypot(co.x, co.y))/M_PI + 0.5;
2100
2101         color = texture2D(ima, vec2(u, v));
2102 }
2103
2104 void node_tex_image(vec3 co, sampler2D ima, out vec4 color)
2105 {
2106         color = texture2D(ima, co.xy);
2107 }
2108
2109 void node_tex_magic(vec3 p, float turbulence, float n, out vec4 color)
2110 {
2111         float turb = turbulence/5.0;
2112
2113         float x = sin((p.x + p.y + p.z)*5.0);
2114         float y = cos((-p.x + p.y - p.z)*5.0);
2115         float z = -cos((-p.x - p.y + p.z)*5.0);
2116
2117         if(n > 0.0) {
2118                 x *= turb;
2119                 y *= turb;
2120                 z *= turb;
2121                 y = -cos(x-y+z);
2122                 y *= turb;
2123
2124                 if(n > 1.0) {
2125                         x= cos(x-y-z);
2126                         x *= turb;
2127
2128                         if(n > 2.0) {
2129                                 z= sin(-x-y-z);
2130                                 z *= turb;
2131
2132                                 if(n > 3.0) {
2133                                         x= -cos(-x+y-z);
2134                                         x *= turb;
2135
2136                                         if(n > 4.0) {
2137                                                 y= -sin(-x+y+z);
2138                                                 y *= turb;
2139
2140                                                 if(n > 5.0) {
2141                                                         y= -cos(-x+y+z);
2142                                                         y *= turb;
2143
2144                                                         if(n > 6.0) {
2145                                                                 x= cos(x+y+z);
2146                                                                 x *= turb;
2147
2148                                                                 if(n > 7.0) {
2149                                                                         z= sin(x+y-z);
2150                                                                         z *= turb;
2151
2152                                                                         if(n > 8.0) {
2153                                                                                 x= -cos(-x-y+z);
2154                                                                                 x *= turb;
2155
2156                                                                                 if(n > 9.0) {
2157                                                                                         y= -sin(x-y+z);
2158                                                                                         y *= turb;
2159                                                                                 }
2160                                                                         }
2161                                                                 }
2162                                                         }
2163                                                 }
2164                                         }
2165                                 }
2166                         }
2167                 }
2168         }
2169
2170         if(turb != 0.0) {
2171                 turb *= 2.0;
2172                 x /= turb;
2173                 y /= turb;
2174                 z /= turb;
2175         }
2176
2177         color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
2178 }
2179
2180 void node_tex_marble(vec3 co, float size, float turbulence, out float fac)
2181 {
2182         fac = 1.0;
2183 }
2184
2185 void node_tex_musgrave(vec3 co, float size, float dimension, float lacunarity, float octaves, float offset, float gain, out float fac)
2186 {
2187         fac = 1.0;
2188 }
2189
2190 void node_tex_noise(vec3 co, out vec4 color, out float fac)
2191 {
2192         color = vec4(1.0);
2193         fac = 1.0;
2194 }
2195
2196 void node_tex_sky(vec3 co, out vec4 color)
2197 {
2198         color = vec4(1.0);
2199 }
2200
2201 void node_tex_stucci(vec3 co, float size, float turbulence, out float fac)
2202 {
2203         fac = 1.0;
2204 }
2205
2206 void node_tex_voronoi(vec3 co, float size, float weight1, float weight2, float weight3, float weight4, float exponent, out vec4 color, out float fac)
2207 {
2208         color = vec4(1.0);
2209         fac = 1.0;
2210 }
2211
2212 void node_tex_wood(vec3 co, float size, float turbulence, out float fac)
2213 {
2214         fac = 1.0;
2215 }
2216
2217 /* light path */
2218
2219 void node_light_path(
2220         out float is_camera_ray,
2221         out float is_shadow_ray,
2222         out float is_diffuse_ray,
2223         out float is_glossy_ray,
2224         out float is_singular_ray,
2225         out float is_reflection_ray,
2226         out float is_transmission_ray)
2227 {
2228         is_camera_ray = 1.0;
2229         is_shadow_ray = 0.0;
2230         is_diffuse_ray = 0.0;
2231         is_glossy_ray = 0.0;
2232         is_singular_ray = 0.0;
2233         is_reflection_ray = 0.0;
2234         is_transmission_ray = 0.0;
2235 }
2236
2237 /* output */
2238
2239 void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
2240 {
2241         result = surface;
2242 }
2243