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