Bicubic bump map filtering.
[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 = dir;
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         vec2 TexDx = dFdx(texco.xy);
1234         vec2 TexDy = dFdy(texco.xy);
1235  
1236         vec2 STl = texco.xy - 0.5 * TexDx ;
1237         vec2 STr = texco.xy + 0.5 * TexDx ;
1238         vec2 STd = texco.xy - 0.5 * TexDy ;
1239         vec2 STu = texco.xy + 0.5 * TexDy ;
1240         
1241         float Hl = texture2D(ima, STl).x;
1242         float Hr = texture2D(ima, STr).x;
1243         float Hd = texture2D(ima, STd).x;
1244         float Hu = texture2D(ima, STu).x;
1245         
1246         vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
1247         float fBlend = clamp(1.0-textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
1248         if(fBlend!=0.0)
1249         {
1250                 // the derivative of the bicubic sampling of level 0
1251                 ivec2 vDim;
1252                 vDim = textureSize(ima, 0);
1253
1254                 vec2 fTexLoc = vDim*texco.xy-vec2(0.5,0.5);
1255                 ivec2 iTexLoc = ivec2(floor(fTexLoc));
1256                 vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0);            // sat just to be pedantic
1257
1258                 ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
1259
1260 /*******************************************************************************************
1261  * This block will replace the one below when one channel textures are properly supported. *
1262  *******************************************************************************************
1263                 vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim );
1264                 vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim );
1265                 vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim );
1266                 vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim );
1267                 
1268                 mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
1269                                         vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
1270                                         vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
1271                                         vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
1272 */      
1273                 mat4 H;
1274                 
1275                 for(int i = 0; i < 4; i++){
1276                         for(int j = 0; j < 4; j++){
1277                                 mtex_rgbtoint(texelFetch(ima, (iTexLocMod + ivec2(i,j)), 0), H[i][j]);
1278                         }
1279                 }
1280                 
1281                 float x = t.x, y = t.y;
1282                 float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y;
1283
1284                 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));
1285                 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));
1286                 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);
1287                 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);
1288         
1289                 // complete derivative in normalized coordinates (mul by vDim)
1290                 vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X));
1291
1292                 // transform derivative to screen-space
1293                 vec2 dHdxy_bicubic = vec2( dHdST.x * TexDx.x + dHdST.y * TexDx.y,
1294                                                                    dHdST.x * TexDy.x + dHdST.y * TexDy.y );
1295
1296                 // blend between the two
1297                 dHdxy = dHdxy*(1-fBlend) + dHdxy_bicubic*fBlend;
1298         }
1299
1300         dBs = hScale * dHdxy.x;
1301         dBt = hScale * dHdxy.y;
1302 }
1303
1304 #endif
1305
1306 void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale, 
1307                      out float dBs, out float dBt ) 
1308 {
1309         vec2 TexDx = dFdx(texco.xy);
1310         vec2 TexDy = dFdy(texco.xy);
1311
1312         vec2 STc = texco.xy;
1313         vec2 STl = texco.xy - 0.5 * TexDx ;
1314         vec2 STr = texco.xy + 0.5 * TexDx ;
1315         vec2 STd = texco.xy - 0.5 * TexDy ;
1316         vec2 STu = texco.xy + 0.5 * TexDy ;
1317         
1318         float Hc,Hl,Hr,Hd,Hu;
1319         rgbtobw( texture2D(ima, STc), Hc );
1320         rgbtobw( texture2D(ima, STl), Hl );
1321         rgbtobw( texture2D(ima, STr), Hr );
1322         rgbtobw( texture2D(ima, STd), Hd );
1323         rgbtobw( texture2D(ima, STu), Hu );
1324         
1325         dBs = hScale * (Hr - Hl);
1326         dBt = hScale * (Hu - Hd);
1327 }
1328
1329 void mtex_bump_deriv( vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, 
1330                      out float dBs, out float dBt ) 
1331 {
1332         float s = 1.0;          // negate this if flipped texture coordinate
1333         vec2 TexDx = dFdx(texco.xy);
1334         vec2 TexDy = dFdy(texco.xy);
1335         
1336         // this variant using a derivative map is described here
1337         // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
1338         vec2 dim = vec2(ima_x, ima_y);
1339         vec2 dBduv = hScale*dim*(2.0*texture2D(ima, texco.xy).xy-1.0);
1340         
1341         dBs = dBduv.x*TexDx.x + s*dBduv.y*TexDx.y;
1342         dBt = dBduv.x*TexDy.x + s*dBduv.y*TexDy.y;
1343 }
1344
1345 void mtex_bump_apply( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
1346                                           out vec3 vNacc_out, out vec3 perturbed_norm ) 
1347 {
1348         vec3 vSurfGrad = sign(fDet) * ( dBs * vR1 + dBt * vR2 );
1349         
1350         vNacc_out = vNacc_in - vSurfGrad;
1351         perturbed_norm = normalize( vNacc_out );
1352 }
1353
1354 void mtex_bump_apply_texspace( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
1355                                sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
1356                                                            out vec3 vNacc_out, out vec3 perturbed_norm ) 
1357 {
1358         vec2 TexDx = dFdx(texco.xy);
1359         vec2 TexDy = dFdy(texco.xy);
1360
1361         vec3 vSurfGrad = sign(fDet) * ( 
1362                     dBs / length( vec2(ima_x*TexDx.x, ima_y*TexDx.y) ) * vR1 + 
1363                     dBt / length( vec2(ima_x*TexDy.x, ima_y*TexDy.y) ) * vR2 );
1364                                 
1365         vNacc_out = vNacc_in - vSurfGrad;
1366         perturbed_norm = normalize( vNacc_out );
1367 }
1368
1369 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1370 {
1371         outnormal = vec3(-normal.x, -normal.y, normal.z);
1372 }
1373
1374 void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1375 {
1376         vec3 B = tangent.w * cross(normal, tangent.xyz);
1377
1378         outnormal = texnormal.x*tangent.xyz + texnormal.y*B + texnormal.z*normal;
1379         outnormal = normalize(outnormal);
1380 }
1381
1382 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1383 {
1384         outnormal = (1.0 - norfac)*normal + norfac*newnormal;
1385         outnormal = normalize(outnormal);
1386 }
1387
1388 /******* MATERIAL *********/
1389
1390 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1391 {
1392         lv = lampvec;
1393         dist = 1.0;
1394         visifac = 1.0;
1395 }
1396
1397 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1398 {
1399         lv = co - lampco;
1400         dist = length(lv);
1401         lv = normalize(lv);
1402         visifac = 1.0;
1403 }
1404
1405 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1406 {
1407         visifac = lampdist/(lampdist + dist);
1408 }
1409
1410 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1411 {
1412         visifac = lampdist/(lampdist + dist*dist);
1413 }
1414
1415 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1416 {
1417         float lampdistkw = lampdist*lampdist;
1418
1419         visifac = lampdist/(lampdist + ld1*dist);
1420         visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
1421 }
1422
1423 void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
1424 {
1425         visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x;
1426 }
1427
1428 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1429 {
1430         float t= lampdist - dist;
1431
1432         outvisifac= visifac*max(t, 0.0)/lampdist;
1433 }
1434
1435 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec3 lv, out float inpr)
1436 {
1437         if(dot(lv, lampvec) > 0.0) {
1438                 vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
1439                 float x = max(abs(lvrot.x/lvrot.z), abs(lvrot.y/lvrot.z));
1440
1441                 inpr = 1.0/sqrt(1.0 + x*x);
1442         }
1443         else
1444                 inpr = 0.0;
1445 }
1446
1447 void lamp_visibility_spot_circle(vec3 lampvec, vec3 lv, out float inpr)
1448 {
1449         inpr = dot(lv, lampvec);
1450 }
1451
1452 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1453 {
1454         float t = spotsi;
1455
1456         if(inpr <= t) {
1457                 outvisifac = 0.0;
1458         }
1459         else {
1460                 t = inpr - t;
1461
1462                 /* soft area */
1463                 if(spotbl != 0.0)
1464                         inpr *= smoothstep(0.0, 1.0, t/spotbl);
1465
1466                 outvisifac = visifac*inpr;
1467         }
1468 }
1469
1470 void lamp_visibility_clamp(float visifac, out float outvisifac)
1471 {
1472         outvisifac = (visifac < 0.001)? 0.0: visifac;
1473 }
1474
1475 void shade_view(vec3 co, out vec3 view)
1476 {
1477         /* handle perspective/orthographic */
1478         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
1479 }
1480
1481 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1482 {
1483         vec3 c = cross(lv, tang);
1484         vec3 vnor = cross(c, tang);
1485
1486         vn = -normalize(vnor);
1487 }
1488
1489 void shade_inp(vec3 vn, vec3 lv, out float inp)
1490 {
1491         inp = dot(vn, lv);
1492 }
1493
1494 void shade_is_no_diffuse(out float is)
1495 {
1496         is = 0.0;
1497 }
1498
1499 void shade_is_hemi(float inp, out float is)
1500 {
1501         is = 0.5*inp + 0.5;
1502 }
1503
1504 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1505 {
1506         vec3 vec[4], c[4];
1507         float rad[4], fac;
1508         
1509         vec[0] = normalize(co - area[0].xyz);
1510         vec[1] = normalize(co - area[1].xyz);
1511         vec[2] = normalize(co - area[2].xyz);
1512         vec[3] = normalize(co - area[3].xyz);
1513
1514         c[0] = normalize(cross(vec[0], vec[1]));
1515         c[1] = normalize(cross(vec[1], vec[2]));
1516         c[2] = normalize(cross(vec[2], vec[3]));
1517         c[3] = normalize(cross(vec[3], vec[0]));
1518
1519         rad[0] = acos(dot(vec[0], vec[1]));
1520         rad[1] = acos(dot(vec[1], vec[2]));
1521         rad[2] = acos(dot(vec[2], vec[3]));
1522         rad[3] = acos(dot(vec[3], vec[0]));
1523
1524         fac=  rad[0]*dot(vn, c[0]);
1525         fac+= rad[1]*dot(vn, c[1]);
1526         fac+= rad[2]*dot(vn, c[2]);
1527         fac+= rad[3]*dot(vn, c[3]);
1528
1529         return max(fac, 0.0);
1530 }
1531
1532 void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
1533 {
1534         vec3 co = position;
1535         vec3 vec = co - lampco;
1536
1537         if(dot(vec, lampvec) < 0.0) {
1538                 inp = 0.0;
1539         }
1540         else {
1541                 float intens = area_lamp_energy(area, co, vn);
1542
1543                 inp = pow(intens*areasize, k);
1544         }
1545 }
1546
1547 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1548 {
1549         vec3 h = normalize(v + l);
1550         float nh = max(dot(n, h), 0.0);
1551         float nv = max(dot(n, v), 0.0);
1552         float realnl = dot(n, l);
1553
1554         if(realnl < 0.0) {
1555                 is = 0.0;
1556         }
1557         else if(nl < 0.0) {
1558                 is = 0.0;
1559         }
1560         else {
1561                 float vh = max(dot(v, h), 0.0);
1562                 float Lit_A = acos(realnl);
1563                 float View_A = acos(nv);
1564
1565                 vec3 Lit_B = normalize(l - realnl*n);
1566                 vec3 View_B = normalize(v - nv*n);
1567
1568                 float t = max(dot(Lit_B, View_B), 0.0);
1569
1570                 float a, b;
1571
1572                 if(Lit_A > View_A) {
1573                         a = Lit_A;
1574                         b = View_A;
1575                 }
1576                 else {
1577                         a = View_A;
1578                         b = Lit_A;
1579                 }
1580
1581                 float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
1582                 float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
1583
1584                 b *= 0.95;
1585                 is = nl*(A + (B * t * sin(a) * tan(b)));
1586         }
1587 }
1588
1589 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1590 {
1591         float rslt = dot(n, l);
1592         float ang = acos(rslt);
1593
1594         if(ang < size) is = 1.0;
1595         else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1596         else is = 1.0 - ((ang - size)/tsmooth);
1597 }
1598
1599 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
1600 {
1601         if(nl <= 0.0) {
1602                 is = 0.0;
1603         }
1604         else {
1605                 float nv = max(dot(n, v), 0.0);
1606
1607                 if(darkness <= 1.0)
1608                         is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
1609                 else
1610                         is = nl*pow(1.0001 - nv, darkness - 1.0);
1611         }
1612 }
1613
1614 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
1615 {
1616         float t1, t2;
1617         float ffac;
1618
1619         if(fac==0.0) {
1620                 ffac = 1.0;
1621         }
1622         else {
1623                 t1= dot(view, vn);
1624                 if(t1>0.0)  t2= 1.0+t1;
1625                 else t2= 1.0-t1;
1626
1627                 t2= grad + (1.0-grad)*pow(t2, fac);
1628
1629                 if(t2<0.0) ffac = 0.0;
1630                 else if(t2>1.0) ffac = 1.0;
1631                 else ffac = t2;
1632         }
1633
1634         return ffac;
1635 }
1636
1637 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
1638 {
1639         is = fresnel_fac(lv, vn, fac_i, fac);
1640 }
1641
1642 void shade_cubic(float is, out float outis)
1643 {
1644         if(is>0.0 && is<1.0)
1645                 outis= smoothstep(0.0, 1.0, is);
1646         else
1647                 outis= is;
1648 }
1649
1650 void shade_visifac(float i, float visifac, float refl, out float outi)
1651 {
1652         /*if(i > 0.0)*/
1653                 outi = max(i*visifac*refl, 0.0);
1654         /*else
1655                 outi = i;*/
1656 }
1657
1658 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
1659 {
1660         vn = tang;
1661 }
1662
1663 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
1664 {
1665         if(i > 0.0)
1666                 outcol = i*lampcol*col;
1667         else
1668                 outcol = vec3(0.0, 0.0, 0.0);
1669 }
1670
1671 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
1672 {
1673         lv += view;
1674         lv = normalize(lv);
1675
1676         t = dot(vn, lv);
1677         t = 0.5*t + 0.5;
1678
1679         t = visifac*spec*pow(t, hard);
1680 }
1681
1682 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1683 {
1684         vec3 h = normalize(l + v);
1685         float rslt = max(dot(h, n), 0.0);
1686
1687         specfac = pow(rslt, hard);
1688 }
1689
1690 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1691 {
1692         vec3 h = normalize(v + l);
1693         float nh = dot(n, h);
1694
1695         if(nh < 0.0) {
1696                 specfac = 0.0;
1697         }
1698         else {
1699                 float nv = max(dot(n, v), 0.0);
1700                 float i = pow(nh, hard);
1701
1702                 i = i/(0.1+nv);
1703                 specfac = i;
1704         }
1705 }
1706
1707 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
1708 {
1709         if(refrac < 1.0) {
1710                 specfac = 0.0;
1711         }
1712         else if(spec_power == 0.0) {
1713                 specfac = 0.0;
1714         }
1715         else {
1716                 if(spec_power<100.0)
1717                         spec_power= sqrt(1.0/spec_power);
1718                 else
1719                         spec_power= 10.0/spec_power;
1720
1721                 vec3 h = normalize(v + l);
1722                 float nh = dot(n, h);
1723                 if(nh < 0.0) {
1724                         specfac = 0.0;
1725                 }
1726                 else {
1727                         float nv = max(dot(n, v), 0.01);
1728                         float nl = dot(n, l);
1729                         if(nl <= 0.01) {
1730                                 specfac = 0.0;
1731                         }
1732                         else {
1733                                 float vh = max(dot(v, h), 0.01);
1734
1735                                 float a = 1.0;
1736                                 float b = (2.0*nh*nv)/vh;
1737                                 float c = (2.0*nh*nl)/vh;
1738
1739                                 float g = 0.0;
1740
1741                                 if(a < b && a < c) g = a;
1742                                 else if(b < a && b < c) g = b;
1743                                 else if(c < a && c < b) g = c;
1744
1745                                 float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
1746                                 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))));
1747                                 float ang = acos(nh);
1748
1749                                 specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
1750                         }
1751                 }
1752         }
1753 }
1754
1755 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
1756 {
1757         vec3 h = normalize(l + v);
1758         float nh = max(dot(n, h), 0.001);
1759         float nv = max(dot(n, v), 0.001);
1760         float nl = max(dot(n, l), 0.001);
1761         float angle = tan(acos(nh));
1762         float alpha = max(rms, 0.001);
1763
1764         specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
1765 }
1766
1767 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
1768 {
1769         vec3 h = normalize(l + v);
1770         float rslt = dot(h, n);
1771         float ang = acos(rslt);
1772
1773         if(ang < size) rslt = 1.0;
1774         else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
1775         else rslt = 1.0 - ((ang - size)/tsmooth);
1776
1777         specfac = rslt;
1778 }
1779
1780 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
1781 {
1782         outspecfac = specfac*inp;
1783 }
1784
1785 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
1786 {
1787         t = shadfac*spec*visifac*specfac;
1788 }
1789
1790 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
1791 {
1792         outcol = t*lampcol*speccol;
1793 }
1794
1795 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
1796 {
1797         outcol = col1 + col2;
1798 }
1799
1800 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1801 {
1802         outcol = col + col1*col2;
1803 }
1804
1805 void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
1806 {
1807         outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0));
1808 }
1809
1810 void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
1811 {
1812         outcol = col + max(col1*col2, vec4(0.0, 0.0, 0.0, 0.0));
1813 }
1814
1815 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
1816 {
1817         outcol = col + f*col1;
1818 }
1819
1820 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
1821 {
1822         outcol = col1*col2;
1823 }
1824
1825 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
1826 {
1827         outcol = col*fac;
1828 }
1829
1830 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1831 {
1832         outcol = vec4(col.rgb*obcol.rgb, col.a);
1833 }
1834
1835 void ramp_rgbtobw(vec3 color, out float outval)
1836 {
1837         outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
1838 }
1839
1840 void shade_only_shadow(float i, float shadfac, float energy, out float outshadfac)
1841 {
1842         outshadfac = i*energy*(1.0 - shadfac);
1843 }
1844
1845 void shade_only_shadow_diffuse(float shadfac, vec3 rgb, vec4 diff, out vec4 outdiff)
1846 {
1847         outdiff = diff - vec4(rgb*shadfac, 0.0);
1848 }
1849
1850 void shade_only_shadow_specular(float shadfac, vec3 specrgb, vec4 spec, out vec4 outspec)
1851 {
1852         outspec = spec - vec4(specrgb*shadfac, 0.0);
1853 }
1854
1855 void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
1856 {
1857         if(inp <= 0.0) {
1858                 result = 0.0;
1859         }
1860         else {
1861                 vec4 co = shadowpersmat*vec4(rco, 1.0);
1862
1863                 //float bias = (1.5 - inp*inp)*shadowbias;
1864                 co.z -= shadowbias*co.w;
1865
1866                 result = shadow2DProj(shadowmap, co).x;
1867         }
1868 }
1869
1870 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
1871 {
1872         outcol = linfac*(1.0 - exp(col*logfac));
1873 }
1874
1875 void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
1876 {
1877         float fac, zcor;
1878
1879         zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
1880         
1881         fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0);
1882         if(misttype == 0.0) fac *= fac;
1883         else if(misttype == 1.0);
1884         else fac = sqrt(fac);
1885
1886         outfac = 1.0 - (1.0-fac)*(1.0-misi);
1887 }
1888
1889 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
1890 {
1891         float fac = clamp(col.a, 0.0, 1.0);
1892         outcol = vec4(mix(hor, col.rgb, fac), col.a);
1893 }
1894
1895 void shade_alpha_opaque(vec4 col, out vec4 outcol)
1896 {
1897         outcol = vec4(col.rgb, 1.0);
1898 }
1899
1900 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
1901 {
1902         outcol = vec4(col.rgb, col.a*obcol.a);
1903 }
1904
1905 /*********** NEW SHADER UTILITIES **************/
1906
1907 float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
1908 {
1909     /* compute fresnel reflectance without explicitly computing
1910        the refracted direction */
1911     float c = abs(dot(Incoming, Normal));
1912     float g = eta * eta - 1.0 + c * c;
1913     float result;
1914
1915     if(g > 0.0) {
1916         g = sqrt(g);
1917         float A =(g - c)/(g + c);
1918         float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
1919         result = 0.5 * A * A *(1.0 + B * B);
1920     }
1921     else
1922         result = 1.0;  /* TIR (no refracted component) */
1923
1924     return result;
1925 }
1926
1927 float hypot(float x, float y)
1928 {
1929         return sqrt(x*x + y*y);
1930 }
1931
1932 /*********** NEW SHADER NODES ***************/
1933
1934 #define NUM_LIGHTS 3
1935
1936 /* bsdfs */
1937
1938 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
1939 {
1940         /* ambient light */
1941         vec3 L = vec3(0.2);
1942
1943         /* directional lights */
1944         for(int i = 0; i < NUM_LIGHTS; i++) {
1945                 vec3 light_position = gl_LightSource[i].position.xyz;
1946                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
1947
1948                 float bsdf = max(dot(N, light_position), 0.0);
1949                 L += light_diffuse*bsdf;
1950         }
1951
1952         result = vec4(L*color.rgb, 1.0);
1953 }
1954
1955 void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result)
1956 {
1957         /* ambient light */
1958         vec3 L = vec3(0.2);
1959
1960         /* directional lights */
1961         for(int i = 0; i < NUM_LIGHTS; i++) {
1962                 vec3 light_position = gl_LightSource[i].position.xyz;
1963                 vec3 H = gl_LightSource[i].halfVector.xyz;
1964                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
1965                 vec3 light_specular = gl_LightSource[i].specular.rgb;
1966
1967                 /* we mix in some diffuse so low roughness still shows up */
1968                 float bsdf = 0.5*pow(max(dot(N, H), 0.0), 1.0/roughness);
1969                 bsdf += 0.5*max(dot(N, light_position), 0.0);
1970                 L += light_specular*bsdf;
1971         }
1972
1973         result = vec4(L*color.rgb, 1.0);
1974 }
1975
1976 void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 I, out vec4 result)
1977 {
1978         node_bsdf_diffuse(color, 0.0, N, result);
1979 }
1980
1981 void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result)
1982 {
1983         node_bsdf_diffuse(color, 0.0, N, result);
1984 }
1985
1986 void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
1987 {
1988         node_bsdf_diffuse(color, 0.0, N, result);
1989 }
1990
1991 void node_bsdf_transparent(vec4 color, out vec4 result)
1992 {
1993         /* this isn't right */
1994         result.r = color.r;
1995         result.g = color.g;
1996         result.b = color.b;
1997         result.a = 0.0;
1998 }
1999
2000 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
2001 {
2002         node_bsdf_diffuse(color, 0.0, N, result);
2003 }
2004
2005 /* emission */
2006
2007 void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
2008 {
2009         result = color*strength;
2010 }
2011
2012 /* closures */
2013
2014 void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
2015 {
2016         shader = mix(shader1, shader2, fac);
2017 }
2018
2019 void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
2020 {
2021         shader = shader1 + shader2;
2022 }
2023
2024 /* fresnel */
2025
2026 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
2027 {
2028         float eta = max(ior, 0.00001);
2029         result = fresnel_dielectric(I, N, eta); //backfacing()? 1.0/eta: eta);
2030 }
2031
2032 /* geometry */
2033
2034 void node_geometry(vec3 I, vec3 N, mat4 toworld,
2035         out vec3 position, out vec3 normal, out vec3 tangent,
2036         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
2037         out float backfacing)
2038 {
2039         position = (toworld*vec4(I, 1.0)).xyz;
2040         normal = N;
2041         tangent = vec3(0.0);
2042         true_normal = N;
2043         incoming = I;
2044         parametric = vec3(0.0);
2045         backfacing = 0.0;
2046 }
2047
2048 void node_tex_coord(vec3 I, vec3 N, mat4 toworld,
2049         vec3 attr_orco, vec3 attr_uv,
2050         out vec3 generated, out vec3 uv, out vec3 object,
2051         out vec3 camera, out vec3 window, out vec3 reflection)
2052 {
2053         generated = attr_orco;
2054         uv = attr_uv;
2055         object = I;
2056         camera = I;
2057         window = gl_FragCoord.xyz;
2058         reflection = reflect(N, I);
2059
2060 }
2061
2062 /* textures */
2063
2064 void node_tex_blend(vec3 co, out float fac)
2065 {
2066         fac = 1.0;
2067 }
2068
2069 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
2070 {
2071         color = vec4(1.0);
2072         fac = 1.0;
2073 }
2074
2075 void node_tex_distnoise(vec3 co, float size, float distortion, out float fac)
2076 {
2077         fac = 1.0;
2078 }
2079
2080 void node_tex_environment(vec3 co, sampler2D ima, out vec4 color)
2081 {
2082         float u = (atan(co.y, co.x) + M_PI)/(2.0*M_PI);
2083         float v = atan(co.z, hypot(co.x, co.y))/M_PI + 0.5;
2084
2085         color = texture2D(ima, vec2(u, v));
2086 }
2087
2088 void node_tex_image(vec3 co, sampler2D ima, out vec4 color)
2089 {
2090         color = texture2D(ima, co.xy);
2091 }
2092
2093 void node_tex_magic(vec3 p, float turbulence, float n, out vec4 color)
2094 {
2095         float turb = turbulence/5.0;
2096
2097         float x = sin((p.x + p.y + p.z)*5.0);
2098         float y = cos((-p.x + p.y - p.z)*5.0);
2099         float z = -cos((-p.x - p.y + p.z)*5.0);
2100
2101         if(n > 0.0) {
2102                 x *= turb;
2103                 y *= turb;
2104                 z *= turb;
2105                 y = -cos(x-y+z);
2106                 y *= turb;
2107
2108                 if(n > 1.0) {
2109                         x= cos(x-y-z);
2110                         x *= turb;
2111
2112                         if(n > 2.0) {
2113                                 z= sin(-x-y-z);
2114                                 z *= turb;
2115
2116                                 if(n > 3.0) {
2117                                         x= -cos(-x+y-z);
2118                                         x *= turb;
2119
2120                                         if(n > 4.0) {
2121                                                 y= -sin(-x+y+z);
2122                                                 y *= turb;
2123
2124                                                 if(n > 5.0) {
2125                                                         y= -cos(-x+y+z);
2126                                                         y *= turb;
2127
2128                                                         if(n > 6.0) {
2129                                                                 x= cos(x+y+z);
2130                                                                 x *= turb;
2131
2132                                                                 if(n > 7.0) {
2133                                                                         z= sin(x+y-z);
2134                                                                         z *= turb;
2135
2136                                                                         if(n > 8.0) {
2137                                                                                 x= -cos(-x-y+z);
2138                                                                                 x *= turb;
2139
2140                                                                                 if(n > 9.0) {
2141                                                                                         y= -sin(x-y+z);
2142                                                                                         y *= turb;
2143                                                                                 }
2144                                                                         }
2145                                                                 }
2146                                                         }
2147                                                 }
2148                                         }
2149                                 }
2150                         }
2151                 }
2152         }
2153
2154         if(turb != 0.0) {
2155                 turb *= 2.0;
2156                 x /= turb;
2157                 y /= turb;
2158                 z /= turb;
2159         }
2160
2161         color = vec4(0.5 - x, 0.5 - y, 0.5 - z, 1.0);
2162 }
2163
2164 void node_tex_marble(vec3 co, float size, float turbulence, out float fac)
2165 {
2166         fac = 1.0;
2167 }
2168
2169 void node_tex_musgrave(vec3 co, float size, float dimension, float lacunarity, float octaves, float offset, float gain, out float fac)
2170 {
2171         fac = 1.0;
2172 }
2173
2174 void node_tex_noise(vec3 co, out vec4 color, out float fac)
2175 {
2176         color = vec4(1.0);
2177         fac = 1.0;
2178 }
2179
2180 void node_tex_sky(vec3 co, out vec4 color)
2181 {
2182         color = vec4(1.0);
2183 }
2184
2185 void node_tex_stucci(vec3 co, float size, float turbulence, out float fac)
2186 {
2187         fac = 1.0;
2188 }
2189
2190 void node_tex_voronoi(vec3 co, float size, float weight1, float weight2, float weight3, float weight4, float exponent, out vec4 color, out float fac)
2191 {
2192         color = vec4(1.0);
2193         fac = 1.0;
2194 }
2195
2196 void node_tex_wood(vec3 co, float size, float turbulence, out float fac)
2197 {
2198         fac = 1.0;
2199 }
2200
2201 /* light path */
2202
2203 void node_light_path(
2204         out float is_camera_ray,
2205         out float is_shadow_ray,
2206         out float is_diffuse_ray,
2207         out float is_glossy_ray,
2208         out float is_singular_ray,
2209         out float is_reflection_ray,
2210         out float is_transmission_ray)
2211 {
2212         is_camera_ray = 1.0;
2213         is_shadow_ray = 0.0;
2214         is_diffuse_ray = 0.0;
2215         is_glossy_ray = 0.0;
2216         is_singular_ray = 0.0;
2217         is_reflection_ray = 0.0;
2218         is_transmission_ray = 0.0;
2219 }
2220
2221 /* output */
2222
2223 void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
2224 {
2225         result = surface;
2226 }
2227