18468c1674f155adc378ff0cf23a3e1cfe41485f
[blender.git] / source / blender / gpu / shaders / gpu_shader_material.glsl
1 /* Converters */
2
3 float convert_rgba_to_float(vec4 color)
4 {
5 #ifdef USE_NEW_SHADING
6         return color.r*0.2126 + color.g*0.7152 + color.b*0.0722;
7 #else
8         return (color.r + color.g + color.b) / 3.0;
9 #endif
10 }
11
12 float exp_blender(float f)
13 {
14         return pow(2.71828182846, f);
15 }
16
17 float compatible_pow(float x, float y)
18 {
19         if(y == 0.0) /* x^0 -> 1, including 0^0 */
20                 return 1.0;
21
22         /* glsl pow doesn't accept negative x */
23         if(x < 0.0) {
24                 if(mod(-y, 2.0) == 0.0)
25                         return pow(-x, y);
26                 else
27                         return -pow(-x, y);
28         }
29         else if(x == 0.0)
30                 return 0.0;
31
32         return pow(x, y);
33 }
34
35 void rgb_to_hsv(vec4 rgb, out vec4 outcol)
36 {
37         float cmax, cmin, h, s, v, cdelta;
38         vec3 c;
39
40         cmax = max(rgb[0], max(rgb[1], rgb[2]));
41         cmin = min(rgb[0], min(rgb[1], rgb[2]));
42         cdelta = cmax-cmin;
43
44         v = cmax;
45         if (cmax!=0.0)
46                 s = cdelta/cmax;
47         else {
48                 s = 0.0;
49                 h = 0.0;
50         }
51
52         if (s == 0.0) {
53                 h = 0.0;
54         }
55         else {
56                 c = (vec3(cmax, cmax, cmax) - rgb.xyz)/cdelta;
57
58                 if (rgb.x==cmax) h = c[2] - c[1];
59                 else if (rgb.y==cmax) h = 2.0 + c[0] -  c[2];
60                 else h = 4.0 + c[1] - c[0];
61
62                 h /= 6.0;
63
64                 if (h<0.0)
65                         h += 1.0;
66         }
67
68         outcol = vec4(h, s, v, rgb.w);
69 }
70
71 void hsv_to_rgb(vec4 hsv, out vec4 outcol)
72 {
73         float i, f, p, q, t, h, s, v;
74         vec3 rgb;
75
76         h = hsv[0];
77         s = hsv[1];
78         v = hsv[2];
79
80         if(s==0.0) {
81                 rgb = vec3(v, v, v);
82         }
83         else {
84                 if(h==1.0)
85                         h = 0.0;
86                 
87                 h *= 6.0;
88                 i = floor(h);
89                 f = h - i;
90                 rgb = vec3(f, f, f);
91                 p = v*(1.0-s);
92                 q = v*(1.0-(s*f));
93                 t = v*(1.0-(s*(1.0-f)));
94                 
95                 if (i == 0.0) rgb = vec3(v, t, p);
96                 else if (i == 1.0) rgb = vec3(q, v, p);
97                 else if (i == 2.0) rgb = vec3(p, v, t);
98                 else if (i == 3.0) rgb = vec3(p, q, v);
99                 else if (i == 4.0) rgb = vec3(t, p, v);
100                 else rgb = vec3(v, p, q);
101         }
102
103         outcol = vec4(rgb, hsv.w);
104 }
105
106 float srgb_to_linearrgb(float c)
107 {
108         if(c < 0.04045)
109                 return (c < 0.0) ? 0.0: c * (1.0 / 12.92);
110         else
111                 return pow((c + 0.055)*(1.0/1.055), 2.4);
112 }
113
114 float linearrgb_to_srgb(float c)
115 {
116         if(c < 0.0031308)
117                 return (c < 0.0) ? 0.0: c * 12.92;
118         else
119                 return 1.055 * pow(c, 1.0/2.4) - 0.055;
120 }
121
122 void srgb_to_linearrgb(vec4 col_from, out vec4 col_to)
123 {
124         col_to.r = srgb_to_linearrgb(col_from.r);
125         col_to.g = srgb_to_linearrgb(col_from.g);
126         col_to.b = srgb_to_linearrgb(col_from.b);
127         col_to.a = col_from.a;
128 }
129
130 void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
131 {
132         col_to.r = linearrgb_to_srgb(col_from.r);
133         col_to.g = linearrgb_to_srgb(col_from.g);
134         col_to.b = linearrgb_to_srgb(col_from.b);
135         col_to.a = col_from.a;
136 }
137
138 #define M_PI 3.14159265358979323846
139 #define M_1_PI 0.31830988618379069
140
141 /*********** SHADER NODES ***************/
142
143 void vcol_attribute(vec4 attvcol, out vec4 vcol)
144 {
145         vcol = vec4(attvcol.x/255.0, attvcol.y/255.0, attvcol.z/255.0, 1.0);
146 }
147
148 void uv_attribute(vec2 attuv, out vec3 uv)
149 {
150         uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0);
151 }
152
153 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)
154 {
155         local = co;
156         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(local): vec3(0.0, 0.0, -1.0);
157         global = (viewinvmat*vec4(local, 1.0)).xyz;
158         orco = attorco;
159         uv_attribute(attuv, uv);
160         normal = -normalize(nor);       /* blender render normal is negated */
161         vcol_attribute(attvcol, vcol);
162         srgb_to_linearrgb(vcol, vcol);
163         vcol_alpha = attvcol.a;
164         frontback = (gl_FrontFacing)? 1.0: 0.0;
165 }
166
167 void particle_info(vec4 sprops, vec3 loc, vec3 vel, vec3 avel, out float index, out float age, out float life_time, out vec3 location, out float size, out vec3 velocity, out vec3 angular_velocity)
168 {
169     index = sprops.x;
170     age = sprops.y;
171     life_time = sprops.z;
172     size = sprops.w;
173
174     location = loc;
175     velocity = vel;
176     angular_velocity = avel;
177 }
178
179 void vect_normalize(vec3 vin, out vec3 vout)
180 {
181         vout = normalize(vin);
182 }
183
184 void direction_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
185 {
186         vout = (mat*vec4(vin, 0.0)).xyz;
187 }
188
189 void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
190 {
191         vout = (mat*vec4(vin, 1.0)).xyz;
192 }
193
194 void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
195 {
196         outvec = (mat * vec4(vec, 1.0)).xyz;
197         if(domin == 1.0)
198                 outvec = max(outvec, minvec);
199         if(domax == 1.0)
200                 outvec = min(outvec, maxvec);
201 }
202
203 void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
204 {
205         outdepth = abs(co.z);
206         outdist = length(co);
207         outview = normalize(co);
208 }
209
210 void lamp(vec4 col, float energy, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
211 {
212         outcol = col * energy;
213         outlv = lv;
214         outdist = dist;
215         outshadow = vec4(shadow, 1.0);
216         outvisifac = visifac;
217 }
218
219 void math_add(float val1, float val2, out float outval)
220 {
221         outval = val1 + val2;
222 }
223
224 void math_subtract(float val1, float val2, out float outval)
225 {
226         outval = val1 - val2;
227 }
228
229 void math_multiply(float val1, float val2, out float outval)
230 {
231         outval = val1 * val2;
232 }
233
234 void math_divide(float val1, float val2, out float outval)
235 {
236         if (val2 == 0.0)
237                 outval = 0.0;
238         else
239                 outval = val1 / val2;
240 }
241
242 void math_sine(float val, out float outval)
243 {
244         outval = sin(val);
245 }
246
247 void math_cosine(float val, out float outval)
248 {
249         outval = cos(val);
250 }
251
252 void math_tangent(float val, out float outval)
253 {
254         outval = tan(val);
255 }
256
257 void math_asin(float val, out float outval)
258 {
259         if (val <= 1.0 && val >= -1.0)
260                 outval = asin(val);
261         else
262                 outval = 0.0;
263 }
264
265 void math_acos(float val, out float outval)
266 {
267         if (val <= 1.0 && val >= -1.0)
268                 outval = acos(val);
269         else
270                 outval = 0.0;
271 }
272
273 void math_atan(float val, out float outval)
274 {
275         outval = atan(val);
276 }
277
278 void math_pow(float val1, float val2, out float outval)
279 {
280         if (val1 >= 0.0) {
281                 outval = compatible_pow(val1, val2);
282         }
283         else {
284                 float val2_mod_1 = mod(abs(val2), 1.0);
285
286                 if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
287                         outval = compatible_pow(val1, floor(val2 + 0.5));
288                 else
289                         outval = 0.0;
290         }
291 }
292
293 void math_log(float val1, float val2, out float outval)
294 {
295         if(val1 > 0.0  && val2 > 0.0)
296                 outval= log2(val1) / log2(val2);
297         else
298                 outval= 0.0;
299 }
300
301 void math_max(float val1, float val2, out float outval)
302 {
303         outval = max(val1, val2);
304 }
305
306 void math_min(float val1, float val2, out float outval)
307 {
308         outval = min(val1, val2);
309 }
310
311 void math_round(float val, out float outval)
312 {
313         outval= floor(val + 0.5);
314 }
315
316 void math_less_than(float val1, float val2, out float outval)
317 {
318         if(val1 < val2)
319                 outval = 1.0;
320         else
321                 outval = 0.0;
322 }
323
324 void math_greater_than(float val1, float val2, out float outval)
325 {
326         if(val1 > val2)
327                 outval = 1.0;
328         else
329                 outval = 0.0;
330 }
331
332 void math_modulo(float val1, float val2, out float outval)
333 {
334         if (val2 == 0.0)
335                 outval = 0.0;
336         else
337                 outval = mod(val1, val2);
338
339         /* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
340          * see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
341         outval = (val1 > 0.0) ? outval : -outval;
342 }
343
344 void math_abs(float val1, out float outval)
345 {
346     outval = abs(val1);
347 }
348
349 void squeeze(float val, float width, float center, out float outval)
350 {
351         outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));
352 }
353
354 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
355 {
356         outvec = v1 + v2;
357         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
358 }
359
360 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
361 {
362         outvec = v1 - v2;
363         outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
364 }
365
366 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
367 {
368         outvec = v1 + v2;
369         outval = length(outvec);
370         outvec = normalize(outvec);
371 }
372
373 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
374 {
375         outvec = vec3(0, 0, 0);
376         outval = dot(v1, v2);
377 }
378
379 void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
380 {
381         outvec = cross(v1, v2);
382         outval = length(outvec);
383         outvec /= outval;
384 }
385
386 void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
387 {
388         outval = length(v);
389         outvec = normalize(v);
390 }
391
392 void vec_math_negate(vec3 v, out vec3 outv)
393 {
394         outv = -v;
395 }
396
397 void invert_z(vec3 v, out vec3 outv)
398 {
399         v.z = -v.z;
400         outv = v;
401 }
402
403 void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
404 {
405         outnor = nor;
406         outdot = -dot(dir, nor);
407 }
408
409 void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
410 {
411         outnor = normalize(nor);
412         outdot = dot(normalize(dir), nor);
413 }
414
415 void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
416 {
417         outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x;
418         outvec.y = texture2D(curvemap, vec2((vec.y + 1.0)*0.5, 0.0)).y;
419         outvec.z = texture2D(curvemap, vec2((vec.z + 1.0)*0.5, 0.0)).z;
420
421         if (fac != 1.0)
422                 outvec = (outvec*fac) + (vec*(1.0-fac));
423
424 }
425
426 void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
427 {
428         outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
429         outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
430         outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
431
432         if (fac != 1.0)
433                 outcol = (outcol*fac) + (col*(1.0-fac));
434
435         outcol.a = col.a;
436 }
437
438 void set_value(float val, out float outval)
439 {
440         outval = val;
441 }
442
443 void set_rgb(vec3 col, out vec3 outcol)
444 {
445         outcol = col;
446 }
447
448 void set_rgba(vec4 col, out vec4 outcol)
449 {
450         outcol = col;
451 }
452
453 void set_value_zero(out float outval)
454 {
455         outval = 0.0;
456 }
457
458 void set_value_one(out float outval)
459 {
460         outval = 1.0;
461 }
462
463 void set_rgb_zero(out vec3 outval)
464 {
465         outval = vec3(0.0);
466 }
467
468 void set_rgb_one(out vec3 outval)
469 {
470         outval = vec3(1.0);
471 }
472
473 void set_rgba_zero(out vec4 outval)
474 {
475         outval = vec4(0.0);
476 }
477
478 void set_rgba_one(out vec4 outval)
479 {
480         outval = vec4(1.0);
481 }
482
483 void brightness_contrast(vec4 col, float brightness, float contrast, out vec4 outcol)
484 {
485         float a = 1.0 + contrast;
486         float b = brightness - contrast*0.5;
487
488         outcol.r = max(a*col.r + b, 0.0);
489         outcol.g = max(a*col.g + b, 0.0);
490         outcol.b = max(a*col.b + b, 0.0);
491         outcol.a = col.a;
492 }
493
494 void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
495 {
496         fac = clamp(fac, 0.0, 1.0);
497         outcol = mix(col1, col2, fac);
498         outcol.a = col1.a;
499 }
500
501 void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
502 {
503         fac = clamp(fac, 0.0, 1.0);
504         outcol = mix(col1, col1 + col2, fac);
505         outcol.a = col1.a;
506 }
507
508 void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
509 {
510         fac = clamp(fac, 0.0, 1.0);
511         outcol = mix(col1, col1 * col2, fac);
512         outcol.a = col1.a;
513 }
514
515 void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
516 {
517         fac = clamp(fac, 0.0, 1.0);
518         float facm = 1.0 - fac;
519
520         outcol = vec4(1.0) - (vec4(facm) + fac*(vec4(1.0) - col2))*(vec4(1.0) - col1);
521         outcol.a = col1.a;
522 }
523
524 void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
525 {
526         fac = clamp(fac, 0.0, 1.0);
527         float facm = 1.0 - fac;
528
529         outcol = col1;
530
531         if(outcol.r < 0.5)
532                 outcol.r *= facm + 2.0*fac*col2.r;
533         else
534                 outcol.r = 1.0 - (facm + 2.0*fac*(1.0 - col2.r))*(1.0 - outcol.r);
535
536         if(outcol.g < 0.5)
537                 outcol.g *= facm + 2.0*fac*col2.g;
538         else
539                 outcol.g = 1.0 - (facm + 2.0*fac*(1.0 - col2.g))*(1.0 - outcol.g);
540
541         if(outcol.b < 0.5)
542                 outcol.b *= facm + 2.0*fac*col2.b;
543         else
544                 outcol.b = 1.0 - (facm + 2.0*fac*(1.0 - col2.b))*(1.0 - outcol.b);
545 }
546
547 void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
548 {
549         fac = clamp(fac, 0.0, 1.0);
550         outcol = mix(col1, col1 - col2, fac);
551         outcol.a = col1.a;
552 }
553
554 void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
555 {
556         fac = clamp(fac, 0.0, 1.0);
557         float facm = 1.0 - fac;
558
559         outcol = col1;
560
561         if(col2.r != 0.0) outcol.r = facm*outcol.r + fac*outcol.r/col2.r;
562         if(col2.g != 0.0) outcol.g = facm*outcol.g + fac*outcol.g/col2.g;
563         if(col2.b != 0.0) outcol.b = facm*outcol.b + fac*outcol.b/col2.b;
564 }
565
566 void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
567 {
568         fac = clamp(fac, 0.0, 1.0);
569         outcol = mix(col1, abs(col1 - col2), fac);
570         outcol.a = col1.a;
571 }
572
573 void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
574 {
575         fac = clamp(fac, 0.0, 1.0);
576         outcol.rgb = min(col1.rgb, col2.rgb*fac);
577         outcol.a = col1.a;
578 }
579
580 void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
581 {
582         fac = clamp(fac, 0.0, 1.0);
583         outcol.rgb = max(col1.rgb, col2.rgb*fac);
584         outcol.a = col1.a;
585 }
586
587 void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
588 {
589         fac = clamp(fac, 0.0, 1.0);
590         outcol = col1;
591
592         if(outcol.r != 0.0) {
593                 float tmp = 1.0 - fac*col2.r;
594                 if(tmp <= 0.0)
595                         outcol.r = 1.0;
596                 else if((tmp = outcol.r/tmp) > 1.0)
597                         outcol.r = 1.0;
598                 else
599                         outcol.r = tmp;
600         }
601         if(outcol.g != 0.0) {
602                 float tmp = 1.0 - fac*col2.g;
603                 if(tmp <= 0.0)
604                         outcol.g = 1.0;
605                 else if((tmp = outcol.g/tmp) > 1.0)
606                         outcol.g = 1.0;
607                 else
608                         outcol.g = tmp;
609         }
610         if(outcol.b != 0.0) {
611                 float tmp = 1.0 - fac*col2.b;
612                 if(tmp <= 0.0)
613                         outcol.b = 1.0;
614                 else if((tmp = outcol.b/tmp) > 1.0)
615                         outcol.b = 1.0;
616                 else
617                         outcol.b = tmp;
618         }
619 }
620
621 void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
622 {
623         fac = clamp(fac, 0.0, 1.0);
624         float tmp, facm = 1.0 - fac;
625
626         outcol = col1;
627
628         tmp = facm + fac*col2.r;
629         if(tmp <= 0.0)
630                 outcol.r = 0.0;
631         else if((tmp = (1.0 - (1.0 - outcol.r)/tmp)) < 0.0)
632                 outcol.r = 0.0;
633         else if(tmp > 1.0)
634                 outcol.r = 1.0;
635         else
636                 outcol.r = tmp;
637
638         tmp = facm + fac*col2.g;
639         if(tmp <= 0.0)
640                 outcol.g = 0.0;
641         else if((tmp = (1.0 - (1.0 - outcol.g)/tmp)) < 0.0)
642                 outcol.g = 0.0;
643         else if(tmp > 1.0)
644                 outcol.g = 1.0;
645         else
646                 outcol.g = tmp;
647
648         tmp = facm + fac*col2.b;
649         if(tmp <= 0.0)
650                 outcol.b = 0.0;
651         else if((tmp = (1.0 - (1.0 - outcol.b)/tmp)) < 0.0)
652                 outcol.b = 0.0;
653         else if(tmp > 1.0)
654                 outcol.b = 1.0;
655         else
656                 outcol.b = tmp;
657 }
658
659 void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
660 {
661         fac = clamp(fac, 0.0, 1.0);
662         float facm = 1.0 - fac;
663
664         outcol = col1;
665
666         vec4 hsv, hsv2, tmp;
667         rgb_to_hsv(col2, hsv2);
668
669         if(hsv2.y != 0.0) {
670                 rgb_to_hsv(outcol, hsv);
671                 hsv.x = hsv2.x;
672                 hsv_to_rgb(hsv, tmp); 
673
674                 outcol = mix(outcol, tmp, fac);
675                 outcol.a = col1.a;
676         }
677 }
678
679 void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
680 {
681         fac = clamp(fac, 0.0, 1.0);
682         float facm = 1.0 - fac;
683
684         outcol = col1;
685
686         vec4 hsv, hsv2;
687         rgb_to_hsv(outcol, hsv);
688
689         if(hsv.y != 0.0) {
690                 rgb_to_hsv(col2, hsv2);
691
692                 hsv.y = facm*hsv.y + fac*hsv2.y;
693                 hsv_to_rgb(hsv, outcol);
694         }
695 }
696
697 void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
698 {
699         fac = clamp(fac, 0.0, 1.0);
700         float facm = 1.0 - fac;
701
702         vec4 hsv, hsv2;
703         rgb_to_hsv(col1, hsv);
704         rgb_to_hsv(col2, hsv2);
705
706         hsv.z = facm*hsv.z + fac*hsv2.z;
707         hsv_to_rgb(hsv, outcol);
708 }
709
710 void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
711 {
712         fac = clamp(fac, 0.0, 1.0);
713         float facm = 1.0 - fac;
714
715         outcol = col1;
716
717         vec4 hsv, hsv2, tmp;
718         rgb_to_hsv(col2, hsv2);
719
720         if(hsv2.y != 0.0) {
721                 rgb_to_hsv(outcol, hsv);
722                 hsv.x = hsv2.x;
723                 hsv.y = hsv2.y;
724                 hsv_to_rgb(hsv, tmp); 
725
726                 outcol = mix(outcol, tmp, fac);
727                 outcol.a = col1.a;
728         }
729 }
730
731 void mix_soft(float fac, vec4 col1, vec4 col2, out vec4 outcol)
732 {
733         fac = clamp(fac, 0.0, 1.0);
734         float facm = 1.0 - fac;
735
736         vec4 one= vec4(1.0);
737         vec4 scr= one - (one - col2)*(one - col1);
738         outcol = facm*col1 + fac*((one - col1)*col2*col1 + col1*scr);
739 }
740
741 void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
742 {
743         fac = clamp(fac, 0.0, 1.0);
744
745         outcol = col1 + fac*(2.0*(col2 - vec4(0.5)));
746 }
747
748 void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
749 {
750         outcol = texture2D(colormap, vec2(fac, 0.0));
751         outalpha = outcol.a;
752 }
753
754 void rgbtobw(vec4 color, out float outval)  
755 {
756 #ifdef USE_NEW_SHADING
757         outval = color.r*0.2126 + color.g*0.7152 + color.b*0.0722;
758 #else
759         outval = color.r*0.35 + color.g*0.45 + color.b*0.2; /* keep these factors in sync with texture.h:RGBTOBW */
760 #endif
761 }
762
763 void invert(float fac, vec4 col, out vec4 outcol)
764 {
765         outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
766         outcol.w = col.w;
767 }
768
769 void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
770 {
771         out_vec = clamp(vec, min, max);
772 }
773
774 void clamp_val(float value, float min, float max, out float out_value)
775 {
776         out_value = clamp(value, min, max);
777 }
778
779 void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
780 {
781         vec4 hsv;
782
783         rgb_to_hsv(col, hsv);
784
785         hsv[0] += (hue - 0.5);
786         if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
787         hsv[1] *= sat;
788         if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
789         hsv[2] *= value;
790         if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
791
792         hsv_to_rgb(hsv, outcol);
793
794         outcol = mix(col, outcol, fac);
795 }
796
797 void separate_rgb(vec4 col, out float r, out float g, out float b)
798 {
799         r = col.r;
800         g = col.g;
801         b = col.b;
802 }
803
804 void combine_rgb(float r, float g, float b, out vec4 col)
805 {
806         col = vec4(r, g, b, 1.0);
807 }
808
809 void separate_xyz(vec3 vec, out float x, out float y, out float z)
810 {
811         x = vec.r;
812         y = vec.g;
813         z = vec.b;
814 }
815
816 void combine_xyz(float x, float y, float z, out vec3 vec)
817 {
818         vec = vec3(x, y, z);
819 }
820
821 void separate_hsv(vec4 col, out float h, out float s, out float v)
822 {
823         vec4 hsv;
824
825         rgb_to_hsv(col, hsv);
826         h = hsv[0];
827         s = hsv[1];
828         v = hsv[2];
829 }
830
831 void combine_hsv(float h, float s, float v, out vec4 col)
832 {
833         hsv_to_rgb(vec4(h, s, v, 1.0), col);
834 }
835
836 void output_node(vec4 rgb, float alpha, out vec4 outrgb)
837 {
838         outrgb = vec4(rgb.rgb, alpha);
839 }
840
841 /*********** TEXTURES ***************/
842
843 void texture_flip_blend(vec3 vec, out vec3 outvec)
844 {
845         outvec = vec.yxz;
846 }
847
848 void texture_blend_lin(vec3 vec, out float outval)
849 {
850         outval = (1.0+vec.x)/2.0;
851 }
852
853 void texture_blend_quad(vec3 vec, out float outval)
854 {
855         outval = max((1.0+vec.x)/2.0, 0.0);
856         outval *= outval;
857 }
858
859 void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
860 {
861         float a = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z)*20.0;
862         float wi = 0.5 + 0.5*sin(a);
863
864         value = wi;
865         color = vec4(wi, wi, wi, 1.0);
866         normal = vec3(0.0, 0.0, 0.0);
867 }
868
869 void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
870 {
871         color = texture2D(ima, (vec.xy + vec2(1.0, 1.0))*0.5);
872         value = color.a;
873
874         normal.x = 2.0*(color.r - 0.5);
875         normal.y = 2.0*(0.5 - color.g);
876         normal.z = 2.0*(color.b - 0.5);
877 }
878
879 /************* MTEX *****************/
880
881 void texco_orco(vec3 attorco, out vec3 orco)
882 {
883         orco = attorco;
884 }
885
886 void texco_uv(vec2 attuv, out vec3 uv)
887 {
888         /* disabled for now, works together with leaving out mtex_2d_mapping
889            uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
890         uv = vec3(attuv, 0.0);
891 }
892
893 void texco_norm(vec3 normal, out vec3 outnormal)
894 {
895         /* corresponds to shi->orn, which is negated so cancels
896            out blender normal negation */
897         outnormal = normalize(normal);
898 }
899
900 void texco_tangent(vec4 tangent, out vec3 outtangent)
901 {
902         outtangent = normalize(tangent.xyz);
903 }
904
905 void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
906 {
907         global = (viewinvmat*vec4(co, 1.0)).xyz;
908 }
909
910 void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
911 {
912         object = (obinvmat*(viewinvmat*vec4(co, 1.0))).xyz;
913 }
914
915 void texco_refl(vec3 vn, vec3 view, out vec3 ref)
916 {
917         ref = view - 2.0*dot(vn, view)*vn;
918 }
919
920 void shade_norm(vec3 normal, out vec3 outnormal)
921 {
922         /* blender render normal is negated */
923         outnormal = -normalize(normal);
924 }
925
926 void mtex_mirror(vec3 tcol, vec4 refcol, float tin, float colmirfac, out vec4 outrefcol)
927 {
928     outrefcol = mix(refcol, vec4(1.0, tcol), tin*colmirfac);
929 }
930
931 void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
932 {
933         float facm;
934
935         fact *= facg;
936         facm = 1.0-fact;
937
938         incol = fact*texcol + facm*outcol;
939 }
940
941 void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
942 {
943         float facm;
944
945         fact *= facg;
946         facm = 1.0-fact;
947
948         incol = (facm + fact*texcol)*outcol;
949 }
950
951 void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
952 {
953         float facm;
954
955         fact *= facg;
956         facm = 1.0-fact;
957
958         incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
959 }
960
961 void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
962 {
963         float facm;
964
965         fact *= facg;
966         facm = 1.0-fact;
967
968         if(outcol.r < 0.5)
969                 incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
970         else
971                 incol.r = 1.0 - (facm + 2.0*fact*(1.0 - texcol.r))*(1.0 - outcol.r);
972
973         if(outcol.g < 0.5)
974                 incol.g = outcol.g*(facm + 2.0*fact*texcol.g);
975         else
976                 incol.g = 1.0 - (facm + 2.0*fact*(1.0 - texcol.g))*(1.0 - outcol.g);
977
978         if(outcol.b < 0.5)
979                 incol.b = outcol.b*(facm + 2.0*fact*texcol.b);
980         else
981                 incol.b = 1.0 - (facm + 2.0*fact*(1.0 - texcol.b))*(1.0 - outcol.b);
982 }
983
984 void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
985 {
986         incol = -fact*facg*texcol + outcol;
987 }
988
989 void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
990 {
991         incol = fact*facg*texcol + outcol;
992 }
993
994 void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
995 {
996         float facm;
997
998         fact *= facg;
999         facm = 1.0-fact;
1000
1001         if(texcol.r != 0.0) incol.r = facm*outcol.r + fact*outcol.r/texcol.r;
1002         if(texcol.g != 0.0) incol.g = facm*outcol.g + fact*outcol.g/texcol.g;
1003         if(texcol.b != 0.0) incol.b = facm*outcol.b + fact*outcol.b/texcol.b;
1004 }
1005
1006 void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1007 {
1008         float facm;
1009
1010         fact *= facg;
1011         facm = 1.0-fact;
1012
1013         incol = facm*outcol + fact*abs(texcol - outcol);
1014 }
1015
1016 void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1017 {
1018         float facm, col;
1019
1020         fact *= facg;
1021         facm = 1.0-fact;
1022
1023         incol.r = min(outcol.r, texcol.r) * fact + outcol.r * facm;
1024         incol.g = min(outcol.g, texcol.g) * fact + outcol.g * facm;
1025         incol.b = min(outcol.b, texcol.b) * fact + outcol.b * facm;
1026 }
1027
1028 void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1029 {
1030         float facm, col;
1031
1032         fact *= facg;
1033
1034         col = fact*texcol.r;
1035         if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
1036         col = fact*texcol.g;
1037         if(col > outcol.g) incol.g = col; else incol.g = outcol.g;
1038         col = fact*texcol.b;
1039         if(col > outcol.b) incol.b = col; else incol.b = outcol.b;
1040 }
1041
1042 void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1043 {
1044         vec4 col;
1045
1046         mix_hue(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1047         incol.rgb = col.rgb;
1048 }
1049
1050 void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1051 {
1052         vec4 col;
1053
1054         mix_sat(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1055         incol.rgb = col.rgb;
1056 }
1057
1058 void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1059 {
1060         vec4 col;
1061
1062         mix_val(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1063         incol.rgb = col.rgb;
1064 }
1065
1066 void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1067 {
1068         vec4 col;
1069
1070         mix_color(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
1071         incol.rgb = col.rgb;
1072 }
1073
1074 void mtex_rgb_soft(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1075 {
1076         float facm;
1077
1078         fact *= facg;
1079         facm = 1.0-fact;
1080
1081         vec3 one = vec3(1.0);
1082         vec3 scr = one - (one - texcol)*(one - outcol);
1083         incol = facm*outcol + fact*((one - texcol)*outcol*texcol + outcol*scr);
1084 }
1085
1086 void mtex_rgb_linear(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
1087 {
1088         fact *= facg;
1089
1090         if(texcol.r > 0.5)
1091                 incol.r = outcol.r + fact*(2.0*(texcol.r - 0.5));
1092         else
1093                 incol.r = outcol.r + fact*(2.0*(texcol.r) - 1.0);
1094
1095         if(texcol.g > 0.5)
1096                 incol.g = outcol.g + fact*(2.0*(texcol.g - 0.5));
1097         else
1098                 incol.g = outcol.g + fact*(2.0*(texcol.g) - 1.0);
1099
1100         if(texcol.b > 0.5)
1101                 incol.b = outcol.b + fact*(2.0*(texcol.b - 0.5));
1102         else
1103                 incol.b = outcol.b + fact*(2.0*(texcol.b) - 1.0);
1104 }
1105
1106 void mtex_value_vars(inout float fact, float facg, out float facm)
1107 {
1108         fact *= abs(facg);
1109         facm = 1.0-fact;
1110
1111         if(facg < 0.0) {
1112                 float tmp = fact;
1113                 fact = facm;
1114                 facm = tmp;
1115         }
1116 }
1117
1118 void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
1119 {
1120         float facm;
1121         mtex_value_vars(fact, facg, facm);
1122
1123         incol = fact*texcol + facm*outcol;
1124 }
1125
1126 void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
1127 {
1128         float facm;
1129         mtex_value_vars(fact, facg, facm);
1130
1131         facm = 1.0 - facg;
1132         incol = (facm + fact*texcol)*outcol;
1133 }
1134
1135 void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
1136 {
1137         float facm;
1138         mtex_value_vars(fact, facg, facm);
1139
1140         facm = 1.0 - facg;
1141         incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol);
1142 }
1143
1144 void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
1145 {
1146         float facm;
1147         mtex_value_vars(fact, facg, facm);
1148
1149         fact = -fact;
1150         incol = fact*texcol + outcol;
1151 }
1152
1153 void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
1154 {
1155         float facm;
1156         mtex_value_vars(fact, facg, facm);
1157
1158         fact = fact;
1159         incol = fact*texcol + outcol;
1160 }
1161
1162 void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
1163 {
1164         float facm;
1165         mtex_value_vars(fact, facg, facm);
1166
1167         if(texcol != 0.0)
1168                 incol = facm*outcol + fact*outcol/texcol;
1169         else
1170                 incol = 0.0;
1171 }
1172
1173 void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
1174 {
1175         float facm;
1176         mtex_value_vars(fact, facg, facm);
1177
1178         incol = facm*outcol + fact*abs(texcol - outcol);
1179 }
1180
1181 void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
1182 {
1183         float facm;
1184         mtex_value_vars(fact, facg, facm);
1185
1186         incol = facm*outcol + fact*min(outcol, texcol);
1187 }
1188
1189 void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
1190 {
1191         float facm;
1192         mtex_value_vars(fact, facg, facm);
1193
1194         float col = fact*texcol;
1195         if(col > outcol) incol = col; else incol = outcol;
1196 }
1197
1198 void mtex_value_clamp_positive(float fac, out float outfac)
1199 {
1200         outfac = max(fac, 0.0);
1201 }
1202
1203 void mtex_value_clamp(float fac, out float outfac)
1204 {
1205         outfac = clamp(fac, 0.0, 1.0);
1206 }
1207
1208 void mtex_har_divide(float har, out float outhar)
1209 {
1210         outhar = har/128.0;
1211 }
1212
1213 void mtex_har_multiply_clamp(float har, out float outhar)
1214 {
1215         har *= 128.0;
1216
1217         if(har < 1.0) outhar = 1.0;
1218         else if(har > 511.0) outhar = 511.0;
1219         else outhar = har;
1220 }
1221
1222 void mtex_alpha_from_col(vec4 col, out float alpha)
1223 {
1224         alpha = col.a;
1225 }
1226
1227 void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
1228 {
1229         outcol = vec4(col.rgb, alpha);
1230 }
1231
1232 void mtex_alpha_multiply_value(vec4 col, float value, out vec4 outcol)
1233 {
1234     outcol = vec4(col.rgb, col.a * value);
1235 }
1236
1237 void mtex_rgbtoint(vec4 rgb, out float intensity)
1238 {
1239         intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
1240 }
1241
1242 void mtex_value_invert(float invalue, out float outvalue)
1243 {
1244         outvalue = 1.0 - invalue;
1245 }
1246
1247 void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
1248 {
1249         outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
1250 }
1251
1252 void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
1253 {
1254         float fact = intensity;
1255         outintensity = intensity*stencil;
1256         outstencil = stencil*fact;
1257 }
1258
1259 void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
1260 {
1261         float fact = rgb.a;
1262         outrgb = vec4(rgb.rgb, rgb.a*stencil);
1263         outstencil = stencil*fact;
1264 }
1265
1266 void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
1267 {
1268         outtexco = texco + ofs;
1269 }
1270
1271 void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
1272 {
1273         outtexco = size*texco;
1274 }
1275
1276 void mtex_2d_mapping(vec3 vec, out vec3 outvec)
1277 {
1278         outvec = vec3(vec.xy*0.5 + vec2(0.5), vec.z);
1279 }
1280
1281 vec3 mtex_2d_mapping(vec3 vec)
1282 {
1283         return vec3(vec.xy*0.5 + vec2(0.5), vec.z);
1284 }
1285
1286 void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
1287 {
1288         color = textureCube(ima, co);
1289         value = 1.0;
1290 }
1291
1292 void mtex_cube_map_refl(samplerCube ima, vec3 vp, vec3 vn, mat4 viewmatrixinverse, mat4 viewmatrix, out float value, out vec4 color)
1293 {
1294         vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0));
1295         vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix));
1296         vec3 reflecteddirection = reflect(viewdirection, normaldirection);
1297         color = textureCube(ima, reflecteddirection);
1298         value = 1.0;
1299 }
1300
1301 void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
1302 {
1303         color = texture2D(ima, texco.xy);
1304         value = 1.0;
1305 }
1306
1307 void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
1308 {
1309         // The invert of the red channel is to make
1310         // the normal map compliant with the outside world.
1311         // It needs to be done because in Blender
1312         // the normal used points inward.
1313         // Should this ever change this negate must be removed.
1314         vec4 color = texture2D(ima, texco.xy);
1315         normal = 2.0*(vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
1316 }
1317
1318 void mtex_bump_normals_init( vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude )
1319 {
1320         vNorg = vN;
1321         vNacc = vN;
1322         fPrevMagnitude = 1.0;
1323 }
1324
1325 /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
1326 mat3 to_mat3(mat4 m4)
1327 {
1328         mat3 m3;
1329         m3[0] = m4[0].xyz;
1330         m3[1] = m4[1].xyz;
1331         m3[2] = m4[2].xyz;
1332         return m3;
1333 }
1334
1335 void mtex_bump_init_objspace( vec3 surf_pos, vec3 surf_norm,
1336                                                           mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv, 
1337                                                           float fPrevMagnitude_in, vec3 vNacc_in,
1338                                                           out float fPrevMagnitude_out, out vec3 vNacc_out, 
1339                                                           out vec3 vR1, out vec3 vR2, out float fDet ) 
1340 {
1341         mat3 obj2view = to_mat3(gl_ModelViewMatrix);
1342         mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse);
1343         
1344         vec3 vSigmaS = view2obj * dFdx( surf_pos );
1345         vec3 vSigmaT = view2obj * dFdy( surf_pos );
1346         vec3 vN = normalize( surf_norm * obj2view );
1347
1348         vR1 = cross( vSigmaT, vN );
1349         vR2 = cross( vN, vSigmaS ) ;
1350         fDet = dot ( vSigmaS, vR1 );
1351         
1352         /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */
1353         vR1 = vR1 * view2obj;
1354         vR2 = vR2 * view2obj;
1355         vN = vN * view2obj;
1356         
1357         float fMagnitude = abs(fDet) * length(vN);
1358         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1359         fPrevMagnitude_out = fMagnitude;
1360 }
1361
1362 void mtex_bump_init_texturespace( vec3 surf_pos, vec3 surf_norm, 
1363                                                                   float fPrevMagnitude_in, vec3 vNacc_in,
1364                                                                   out float fPrevMagnitude_out, out vec3 vNacc_out, 
1365                                                                   out vec3 vR1, out vec3 vR2, out float fDet ) 
1366 {
1367         vec3 vSigmaS = dFdx( surf_pos );
1368         vec3 vSigmaT = dFdy( surf_pos );
1369         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1370         
1371         vR1 = normalize( cross( vSigmaT, vN ) );
1372         vR2 = normalize( cross( vN, vSigmaS ) );
1373         fDet = sign( dot(vSigmaS, vR1) );
1374         
1375         float fMagnitude = abs(fDet);
1376         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1377         fPrevMagnitude_out = fMagnitude;
1378 }
1379
1380 void mtex_bump_init_viewspace( vec3 surf_pos, vec3 surf_norm, 
1381                                                            float fPrevMagnitude_in, vec3 vNacc_in,
1382                                                            out float fPrevMagnitude_out, out vec3 vNacc_out, 
1383                                                            out vec3 vR1, out vec3 vR2, out float fDet ) 
1384 {
1385         vec3 vSigmaS = dFdx( surf_pos );
1386         vec3 vSigmaT = dFdy( surf_pos );
1387         vec3 vN = surf_norm; /* normalized interpolated vertex normal */
1388         
1389         vR1 = cross( vSigmaT, vN );
1390         vR2 = cross( vN, vSigmaS ) ;
1391         fDet = dot ( vSigmaS, vR1 );
1392         
1393         float fMagnitude = abs(fDet);
1394         vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
1395         fPrevMagnitude_out = fMagnitude;
1396 }
1397
1398 void mtex_bump_tap3( vec3 texco, sampler2D ima, float hScale, 
1399                      out float dBs, out float dBt )
1400 {
1401         vec2 STll = texco.xy;
1402         vec2 STlr = texco.xy + dFdx(texco.xy) ;
1403         vec2 STul = texco.xy + dFdy(texco.xy) ;
1404         
1405         float Hll,Hlr,Hul;
1406         rgbtobw( texture2D(ima, STll), Hll );
1407         rgbtobw( texture2D(ima, STlr), Hlr );
1408         rgbtobw( texture2D(ima, STul), Hul );
1409         
1410         dBs = hScale * (Hlr - Hll);
1411         dBt = hScale * (Hul - Hll);
1412 }
1413
1414 #ifdef BUMP_BICUBIC
1415
1416 void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale, 
1417                      out float dBs, out float dBt ) 
1418 {
1419         float Hl;
1420         float Hr;
1421         float Hd;
1422         float Hu;
1423         
1424         vec2 TexDx = dFdx(texco.xy);
1425         vec2 TexDy = dFdy(texco.xy);
1426  
1427         vec2 STl = texco.xy - 0.5 * TexDx ;
1428         vec2 STr = texco.xy + 0.5 * TexDx ;
1429         vec2 STd = texco.xy - 0.5 * TexDy ;
1430         vec2 STu = texco.xy + 0.5 * TexDy ;
1431         
1432         rgbtobw(texture2D(ima, STl), Hl);
1433         rgbtobw(texture2D(ima, STr), Hr);
1434         rgbtobw(texture2D(ima, STd), Hd);
1435         rgbtobw(texture2D(ima, STu), Hu);
1436         
1437         vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
1438         float fBlend = clamp(1.0-textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
1439         if(fBlend!=0.0)
1440         {
1441                 // the derivative of the bicubic sampling of level 0
1442                 ivec2 vDim;
1443                 vDim = textureSize(ima, 0);
1444
1445                 // taking the fract part of the texture coordinate is a hardcoded wrap mode.
1446                 // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender. 
1447                 // this is done so that we can still get a valid texel with uvs outside the 0,1 range
1448                 // by texelFetch below, as coordinates are clamped when using this function.
1449                 vec2 fTexLoc = vDim*fract(texco.xy) - vec2(0.5, 0.5);
1450                 ivec2 iTexLoc = ivec2(floor(fTexLoc));
1451                 vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0);            // sat just to be pedantic
1452
1453 /*******************************************************************************************
1454  * This block will replace the one below when one channel textures are properly supported. *
1455  *******************************************************************************************
1456                 vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim );
1457                 vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim );
1458                 vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim );
1459                 vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim );
1460
1461                 mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
1462                                         vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
1463                                         vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
1464                                         vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
1465 */      
1466                 ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
1467
1468                 mat4 H;
1469                 
1470                 for(int i = 0; i < 4; i++) {
1471                         for(int j = 0; j < 4; j++) {
1472                                 ivec2 iTexTmp = iTexLocMod + ivec2(i,j);
1473                                 
1474                                 // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range.
1475                                 // this is guaranteed to work since we take the fractional part of the uv above.
1476                                 iTexTmp.x = (iTexTmp.x < 0)? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x)? iTexTmp.x - vDim.x : iTexTmp.x);
1477                                 iTexTmp.y = (iTexTmp.y < 0)? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y)? iTexTmp.y - vDim.y : iTexTmp.y);
1478
1479                                 rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]);
1480                         }
1481                 }
1482                 
1483                 float x = t.x, y = t.y;
1484                 float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y;
1485
1486                 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));
1487                 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));
1488                 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);
1489                 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);
1490         
1491                 // complete derivative in normalized coordinates (mul by vDim)
1492                 vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X));
1493
1494                 // transform derivative to screen-space
1495                 vec2 dHdxy_bicubic = vec2( dHdST.x * TexDx.x + dHdST.y * TexDx.y,
1496                                                                    dHdST.x * TexDy.x + dHdST.y * TexDy.y );
1497
1498                 // blend between the two
1499                 dHdxy = dHdxy*(1-fBlend) + dHdxy_bicubic*fBlend;
1500         }
1501
1502         dBs = hScale * dHdxy.x;
1503         dBt = hScale * dHdxy.y;
1504 }
1505
1506 #endif
1507
1508 void mtex_bump_tap5( vec3 texco, sampler2D ima, float hScale, 
1509                      out float dBs, out float dBt ) 
1510 {
1511         vec2 TexDx = dFdx(texco.xy);
1512         vec2 TexDy = dFdy(texco.xy);
1513
1514         vec2 STc = texco.xy;
1515         vec2 STl = texco.xy - 0.5 * TexDx ;
1516         vec2 STr = texco.xy + 0.5 * TexDx ;
1517         vec2 STd = texco.xy - 0.5 * TexDy ;
1518         vec2 STu = texco.xy + 0.5 * TexDy ;
1519         
1520         float Hc,Hl,Hr,Hd,Hu;
1521         rgbtobw( texture2D(ima, STc), Hc );
1522         rgbtobw( texture2D(ima, STl), Hl );
1523         rgbtobw( texture2D(ima, STr), Hr );
1524         rgbtobw( texture2D(ima, STd), Hd );
1525         rgbtobw( texture2D(ima, STu), Hu );
1526         
1527         dBs = hScale * (Hr - Hl);
1528         dBt = hScale * (Hu - Hd);
1529 }
1530
1531 void mtex_bump_deriv( vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, 
1532                      out float dBs, out float dBt ) 
1533 {
1534         float s = 1.0;          // negate this if flipped texture coordinate
1535         vec2 TexDx = dFdx(texco.xy);
1536         vec2 TexDy = dFdy(texco.xy);
1537         
1538         // this variant using a derivative map is described here
1539         // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
1540         vec2 dim = vec2(ima_x, ima_y);
1541         vec2 dBduv = hScale*dim*(2.0*texture2D(ima, texco.xy).xy-1.0);
1542         
1543         dBs = dBduv.x*TexDx.x + s*dBduv.y*TexDx.y;
1544         dBt = dBduv.x*TexDy.x + s*dBduv.y*TexDy.y;
1545 }
1546
1547 void mtex_bump_apply( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
1548                                           out vec3 vNacc_out, out vec3 perturbed_norm ) 
1549 {
1550         vec3 vSurfGrad = sign(fDet) * ( dBs * vR1 + dBt * vR2 );
1551         
1552         vNacc_out = vNacc_in - vSurfGrad;
1553         perturbed_norm = normalize( vNacc_out );
1554 }
1555
1556 void mtex_bump_apply_texspace( float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
1557                                sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
1558                                                            out vec3 vNacc_out, out vec3 perturbed_norm ) 
1559 {
1560         vec2 TexDx = dFdx(texco.xy);
1561         vec2 TexDy = dFdy(texco.xy);
1562
1563         vec3 vSurfGrad = sign(fDet) * ( 
1564                     dBs / length( vec2(ima_x*TexDx.x, ima_y*TexDx.y) ) * vR1 + 
1565                     dBt / length( vec2(ima_x*TexDy.x, ima_y*TexDy.y) ) * vR2 );
1566                                 
1567         vNacc_out = vNacc_in - vSurfGrad;
1568         perturbed_norm = normalize( vNacc_out );
1569 }
1570
1571 void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
1572 {
1573         outnormal = vec3(-normal.x, -normal.y, normal.z);
1574 }
1575
1576 void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
1577 {
1578         vec3 B = tangent.w * cross(normal, tangent.xyz);
1579
1580         outnormal = texnormal.x*tangent.xyz + texnormal.y*B + texnormal.z*normal;
1581         outnormal = normalize(outnormal);
1582 }
1583
1584 void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
1585 {
1586         outnormal = normalize((viewmat*vec4(texnormal, 0.0)).xyz);
1587 }
1588
1589 void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
1590 {
1591         outnormal = normalize(gl_NormalMatrix * texnormal);
1592 }
1593
1594 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
1595 {
1596         outnormal = (1.0 - norfac)*normal + norfac*newnormal;
1597         outnormal = normalize(outnormal);
1598 }
1599
1600 /******* MATERIAL *********/
1601
1602 void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
1603 {
1604         lv = lampvec;
1605         dist = 1.0;
1606         visifac = 1.0;
1607 }
1608
1609 void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
1610 {
1611         lv = co - lampco;
1612         dist = length(lv);
1613         lv = normalize(lv);
1614         visifac = 1.0;
1615 }
1616
1617 void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
1618 {
1619         visifac = lampdist/(lampdist + dist);
1620 }
1621
1622 void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
1623 {
1624         visifac = lampdist/(lampdist + dist*dist);
1625 }
1626
1627 void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
1628 {
1629         float lampdistkw = lampdist*lampdist;
1630
1631         visifac = lampdist/(lampdist + ld1*dist);
1632         visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
1633 }
1634
1635 void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coeff_quad, float dist, out float visifac)
1636 {
1637         vec3 coeff = vec3(coeff_const, coeff_lin, coeff_quad);
1638         vec3 d_coeff = vec3(1.0, dist, dist*dist);
1639         float visifac_r = dot(coeff, d_coeff);
1640         if (visifac_r > 0.0)
1641                 visifac = 1.0 / visifac_r;
1642         else
1643                 visifac = 0.0;
1644 }
1645
1646 void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
1647 {
1648         visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x;
1649 }
1650
1651 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
1652 {
1653         float t= lampdist - dist;
1654
1655         outvisifac= visifac*max(t, 0.0)/lampdist;
1656 }
1657
1658 void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
1659 {
1660         if(dot(lv, lampvec) > 0.0) {
1661                 vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
1662                 /* without clever non-uniform scale, we could do: */
1663                 // float x = max(abs(lvrot.x / lvrot.z), abs(lvrot.y / lvrot.z));
1664                 float x = max(abs((lvrot.x / scale.x) / lvrot.z), abs((lvrot.y / scale.y) / lvrot.z));
1665
1666                 inpr = 1.0/sqrt(1.0 + x*x);
1667         }
1668         else
1669                 inpr = 0.0;
1670 }
1671
1672 void lamp_visibility_spot_circle(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
1673 {
1674         /* without clever non-uniform scale, we could do: */
1675         // inpr = dot(lv, lampvec);
1676         if (dot(lv, lampvec) > 0.0) {
1677                 vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz;
1678                 float x = abs(lvrot.x / lvrot.z);
1679                 float y = abs(lvrot.y / lvrot.z);
1680
1681                 float ellipse = abs((x * x) / (scale.x * scale.x) + (y * y) / (scale.y * scale.y));
1682
1683                 inpr = 1.0 / sqrt(1.0 + ellipse);
1684         }
1685         else
1686                 inpr = 0.0;
1687 }
1688
1689 void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
1690 {
1691         float t = spotsi;
1692
1693         if(inpr <= t) {
1694                 outvisifac = 0.0;
1695         }
1696         else {
1697                 t = inpr - t;
1698
1699                 /* soft area */
1700                 if(spotbl != 0.0)
1701                         inpr *= smoothstep(0.0, 1.0, t/spotbl);
1702
1703                 outvisifac = visifac*inpr;
1704         }
1705 }
1706
1707 void lamp_visibility_clamp(float visifac, out float outvisifac)
1708 {
1709         outvisifac = (visifac < 0.001)? 0.0: visifac;
1710 }
1711
1712 void world_paper_view(vec3 vec, out vec3 outvec)
1713 {
1714         vec3 nvec = normalize(vec);
1715         outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
1716 }
1717
1718 void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
1719 {
1720         if (view.z >= 0.0)
1721                 zenfac = zenup;
1722         else
1723                 zenfac = zendown;
1724 }
1725
1726 void world_blend_paper_real(vec3 vec, out float blend)
1727 {
1728         blend = abs(vec.y);
1729 }
1730
1731 void world_blend_paper(vec3 vec, out float blend)
1732 {
1733         blend = (vec.y + 1.0) * 0.5;
1734 }
1735
1736 void world_blend_real(vec3 vec, out float blend)
1737 {
1738         blend = abs(normalize(vec).z);
1739 }
1740
1741 void world_blend(vec3 vec, out float blend)
1742 {
1743         blend = (normalize(vec).z + 1) * 0.5;
1744 }
1745
1746 void shade_view(vec3 co, out vec3 view)
1747 {
1748         /* handle perspective/orthographic */
1749         view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
1750 }
1751
1752 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
1753 {
1754         vec3 c = cross(lv, tang);
1755         vec3 vnor = cross(c, tang);
1756
1757         vn = -normalize(vnor);
1758 }
1759
1760 void shade_inp(vec3 vn, vec3 lv, out float inp)
1761 {
1762         inp = dot(vn, lv);
1763 }
1764
1765 void shade_is_no_diffuse(out float is)
1766 {
1767         is = 0.0;
1768 }
1769
1770 void shade_is_hemi(float inp, out float is)
1771 {
1772         is = 0.5*inp + 0.5;
1773 }
1774
1775 float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
1776 {
1777         vec3 vec[4], c[4];
1778         float rad[4], fac;
1779         
1780         vec[0] = normalize(co - area[0].xyz);
1781         vec[1] = normalize(co - area[1].xyz);
1782         vec[2] = normalize(co - area[2].xyz);
1783         vec[3] = normalize(co - area[3].xyz);
1784
1785         c[0] = normalize(cross(vec[0], vec[1]));
1786         c[1] = normalize(cross(vec[1], vec[2]));
1787         c[2] = normalize(cross(vec[2], vec[3]));
1788         c[3] = normalize(cross(vec[3], vec[0]));
1789
1790         rad[0] = acos(dot(vec[0], vec[1]));
1791         rad[1] = acos(dot(vec[1], vec[2]));
1792         rad[2] = acos(dot(vec[2], vec[3]));
1793         rad[3] = acos(dot(vec[3], vec[0]));
1794
1795         fac=  rad[0]*dot(vn, c[0]);
1796         fac+= rad[1]*dot(vn, c[1]);
1797         fac+= rad[2]*dot(vn, c[2]);
1798         fac+= rad[3]*dot(vn, c[3]);
1799
1800         return max(fac, 0.0);
1801 }
1802
1803 void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
1804 {
1805         vec3 co = position;
1806         vec3 vec = co - lampco;
1807
1808         if(dot(vec, lampvec) < 0.0) {
1809                 inp = 0.0;
1810         }
1811         else {
1812                 float intens = area_lamp_energy(area, co, vn);
1813
1814                 inp = pow(intens*areasize, k);
1815         }
1816 }
1817
1818 void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
1819 {
1820         vec3 h = normalize(v + l);
1821         float nh = max(dot(n, h), 0.0);
1822         float nv = max(dot(n, v), 0.0);
1823         float realnl = dot(n, l);
1824
1825         if(realnl < 0.0) {
1826                 is = 0.0;
1827         }
1828         else if(nl < 0.0) {
1829                 is = 0.0;
1830         }
1831         else {
1832                 float vh = max(dot(v, h), 0.0);
1833                 float Lit_A = acos(realnl);
1834                 float View_A = acos(nv);
1835
1836                 vec3 Lit_B = normalize(l - realnl*n);
1837                 vec3 View_B = normalize(v - nv*n);
1838
1839                 float t = max(dot(Lit_B, View_B), 0.0);
1840
1841                 float a, b;
1842
1843                 if(Lit_A > View_A) {
1844                         a = Lit_A;
1845                         b = View_A;
1846                 }
1847                 else {
1848                         a = View_A;
1849                         b = Lit_A;
1850                 }
1851
1852                 float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
1853                 float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
1854
1855                 b *= 0.95;
1856                 is = nl*(A + (B * t * sin(a) * tan(b)));
1857         }
1858 }
1859
1860 void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
1861 {
1862         float rslt = dot(n, l);
1863         float ang = acos(rslt);
1864
1865         if(ang < size) is = 1.0;
1866         else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
1867         else is = 1.0 - ((ang - size)/tsmooth);
1868 }
1869
1870 void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
1871 {
1872         if(nl <= 0.0) {
1873                 is = 0.0;
1874         }
1875         else {
1876                 float nv = max(dot(n, v), 0.0);
1877
1878                 if(darkness <= 1.0)
1879                         is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
1880                 else
1881                         is = nl*pow(1.0001 - nv, darkness - 1.0);
1882         }
1883 }
1884
1885 float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
1886 {
1887         float t1, t2;
1888         float ffac;
1889
1890         if(fac==0.0) {
1891                 ffac = 1.0;
1892         }
1893         else {
1894                 t1= dot(view, vn);
1895                 if(t1>0.0)  t2= 1.0+t1;
1896                 else t2= 1.0-t1;
1897
1898                 t2= grad + (1.0-grad)*pow(t2, fac);
1899
1900                 if(t2<0.0) ffac = 0.0;
1901                 else if(t2>1.0) ffac = 1.0;
1902                 else ffac = t2;
1903         }
1904
1905         return ffac;
1906 }
1907
1908 void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
1909 {
1910         is = fresnel_fac(lv, vn, fac_i, fac);
1911 }
1912
1913 void shade_cubic(float is, out float outis)
1914 {
1915         if(is>0.0 && is<1.0)
1916                 outis= smoothstep(0.0, 1.0, is);
1917         else
1918                 outis= is;
1919 }
1920
1921 void shade_visifac(float i, float visifac, float refl, out float outi)
1922 {
1923         /*if(i > 0.0)*/
1924                 outi = max(i*visifac*refl, 0.0);
1925         /*else
1926                 outi = i;*/
1927 }
1928
1929 void shade_tangent_v_spec(vec3 tang, out vec3 vn)
1930 {
1931         vn = tang;
1932 }
1933
1934 void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
1935 {
1936         if(i > 0.0)
1937                 outcol = i*lampcol*col;
1938         else
1939                 outcol = vec3(0.0, 0.0, 0.0);
1940 }
1941
1942 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
1943 {
1944         lv += view;
1945         lv = normalize(lv);
1946
1947         t = dot(vn, lv);
1948         t = 0.5*t + 0.5;
1949
1950         t = visifac*spec*pow(t, hard);
1951 }
1952
1953 void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1954 {
1955         vec3 h = normalize(l + v);
1956         float rslt = max(dot(h, n), 0.0);
1957
1958         specfac = pow(rslt, hard);
1959 }
1960
1961 void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
1962 {
1963         vec3 h = normalize(v + l);
1964         float nh = dot(n, h);
1965
1966         if(nh < 0.0) {
1967                 specfac = 0.0;
1968         }
1969         else {
1970                 float nv = max(dot(n, v), 0.0);
1971                 float i = pow(nh, hard);
1972
1973                 i = i/(0.1+nv);
1974                 specfac = i;
1975         }
1976 }
1977
1978 void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
1979 {
1980         if(refrac < 1.0) {
1981                 specfac = 0.0;
1982         }
1983         else if(spec_power == 0.0) {
1984                 specfac = 0.0;
1985         }
1986         else {
1987                 if(spec_power<100.0)
1988                         spec_power= sqrt(1.0/spec_power);
1989                 else
1990                         spec_power= 10.0/spec_power;
1991
1992                 vec3 h = normalize(v + l);
1993                 float nh = dot(n, h);
1994                 if(nh < 0.0) {
1995                         specfac = 0.0;
1996                 }
1997                 else {
1998                         float nv = max(dot(n, v), 0.01);
1999                         float nl = dot(n, l);
2000                         if(nl <= 0.01) {
2001                                 specfac = 0.0;
2002                         }
2003                         else {
2004                                 float vh = max(dot(v, h), 0.01);
2005
2006                                 float a = 1.0;
2007                                 float b = (2.0*nh*nv)/vh;
2008                                 float c = (2.0*nh*nl)/vh;
2009
2010                                 float g = 0.0;
2011
2012                                 if(a < b && a < c) g = a;
2013                                 else if(b < a && b < c) g = b;
2014                                 else if(c < a && c < b) g = c;
2015
2016                                 float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
2017                                 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))));
2018                                 float ang = acos(nh);
2019
2020                                 specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
2021                         }
2022                 }
2023         }
2024 }
2025
2026 void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
2027 {
2028         vec3 h = normalize(l + v);
2029         float nh = max(dot(n, h), 0.001);
2030         float nv = max(dot(n, v), 0.001);
2031         float nl = max(dot(n, l), 0.001);
2032         float angle = tan(acos(nh));
2033         float alpha = max(rms, 0.001);
2034
2035         specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
2036 }
2037
2038 void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
2039 {
2040         vec3 h = normalize(l + v);
2041         float rslt = dot(h, n);
2042         float ang = acos(rslt);
2043
2044         if(ang < size) rslt = 1.0;
2045         else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
2046         else rslt = 1.0 - ((ang - size)/tsmooth);
2047
2048         specfac = rslt;
2049 }
2050
2051 void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
2052 {
2053         outspecfac = specfac*inp;
2054 }
2055
2056 void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
2057 {
2058         t = shadfac*spec*visifac*specfac;
2059 }
2060
2061 void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
2062 {
2063         outcol = t*lampcol*speccol;
2064 }
2065
2066 void shade_add_mirror(vec3 mir, vec4 refcol, vec3 combined, out vec3 result)
2067 {
2068     result = mir*refcol.gba + (vec3(1.0) - mir*refcol.rrr)*combined;
2069 }
2070
2071 void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha)
2072 {
2073         if (spectra > 0.0) {
2074                 float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0);
2075                 outalpha = (1.0 - t) * alpha + t;
2076         }
2077         else {
2078                 outalpha = alpha;
2079         }
2080 }
2081
2082 void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
2083 {
2084         outcol = col1 + col2;
2085 }
2086
2087 void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
2088 {
2089         outcol = col + col1*col2;
2090 }
2091
2092 void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
2093 {
2094         outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0));
2095 }
2096
2097 void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
2098 {
2099         outcol = col + max(col1*col2, vec4(0.0, 0.0, 0.0, 0.0));
2100 }
2101
2102 void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
2103 {
2104         outcol = col + f*col1;
2105 }
2106
2107 void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
2108 {
2109         outcol = col1*col2;
2110 }
2111
2112 void shade_mul_value(float fac, vec4 col, out vec4 outcol)
2113 {
2114         outcol = col*fac;
2115 }
2116
2117 void shade_mul_value_v3(float fac, vec3 col, out vec3 outcol)
2118 {
2119         outcol = col*fac;
2120 }
2121
2122 void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
2123 {
2124         outcol = vec4(col.rgb*obcol.rgb, col.a);
2125 }
2126
2127 void ramp_rgbtobw(vec3 color, out float outval)
2128 {
2129         outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
2130 }
2131
2132 void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb)
2133 {
2134         outshadrgb = i*energy*(1.0 - shadfac)*(vec3(1.0)-shadcol);
2135 }
2136
2137 void shade_only_shadow_diffuse(vec3 shadrgb, vec3 rgb, vec4 diff, out vec4 outdiff)
2138 {
2139         outdiff = diff - vec4(rgb*shadrgb, 0.0);
2140 }
2141
2142 void shade_only_shadow_specular(vec3 shadrgb, vec3 specrgb, vec4 spec, out vec4 outspec)
2143 {
2144         outspec = spec - vec4(specrgb*shadrgb, 0.0);
2145 }
2146
2147 void shade_clamp_positive(vec4 col, out vec4 outcol)
2148 {
2149         outcol = max(col, vec4(0.0));
2150 }
2151
2152 void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
2153 {
2154         if(inp <= 0.0) {
2155                 result = 0.0;
2156         }
2157         else {
2158                 vec4 co = shadowpersmat*vec4(rco, 1.0);
2159
2160                 //float bias = (1.5 - inp*inp)*shadowbias;
2161                 co.z -= shadowbias*co.w;
2162                 
2163                 if (co.w > 0.0 && co.x > 0.0 && co.x/co.w < 1.0 && co.y > 0.0 && co.y/co.w < 1.0)
2164                         result = shadow2DProj(shadowmap, co).x;
2165                 else
2166                         result = 1.0;
2167         }
2168 }
2169
2170 void test_shadowbuf_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, float inp, out float result)
2171 {
2172         if(inp <= 0.0) {
2173                 result = 0.0;
2174         }
2175         else {
2176                 vec4 co = shadowpersmat*vec4(rco, 1.0);
2177                 if (co.w > 0.0 && co.x > 0.0 && co.x/co.w < 1.0 && co.y > 0.0 && co.y/co.w < 1.0) {
2178                         vec2 moments = texture2DProj(shadowmap, co).rg;
2179                         float dist = co.z/co.w;
2180                         float p = 0.0;
2181                         
2182                         if(dist <= moments.x)
2183                                 p = 1.0;
2184
2185                         float variance = moments.y - (moments.x*moments.x);
2186                         variance = max(variance, shadowbias/10.0);
2187
2188                         float d = moments.x - dist;
2189                         float p_max = variance / (variance + d*d);
2190
2191                         // Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1]
2192                         p_max = clamp((p_max-bleedbias)/(1.0-bleedbias), 0.0, 1.0);
2193
2194                         result = max(p, p_max);
2195                 }
2196                 else {
2197                         result = 1.0;
2198                 }
2199         }
2200 }
2201
2202 void shadows_only(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, vec3 shadowcolor, float inp, out vec3 result)
2203 {
2204         result = vec3(1.0);
2205
2206         if(inp > 0.0) {
2207                 float shadfac;
2208
2209                 test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac);
2210                 result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
2211         }
2212 }
2213
2214 void shadows_only_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, vec3 shadowcolor, float inp, out vec3 result)
2215 {
2216         result = vec3(1.0);
2217
2218         if(inp > 0.0) {
2219                 float shadfac;
2220
2221                 test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac);
2222                 result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
2223         }
2224 }
2225
2226 void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result)
2227 {
2228
2229         vec4 co = shadowpersmat*vec4(rco, 1.0);
2230
2231         result = texture2DProj(cookie, co);
2232 }
2233
2234 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
2235 {
2236         outcol = linfac*(1.0 - exp(col*logfac));
2237 }
2238
2239 void shade_mist_factor(vec3 co, float enable, float miststa, float mistdist, float misttype, float misi, out float outfac)
2240 {
2241         if(enable == 1.0) {
2242                 float fac, zcor;
2243
2244                 zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
2245                 
2246                 fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
2247                 if(misttype == 0.0) fac *= fac;
2248                 else if(misttype == 1.0);
2249                 else fac = sqrt(fac);
2250
2251                 outfac = 1.0 - (1.0 - fac) * (1.0 - misi);
2252         }
2253         else {
2254                 outfac = 0.0;
2255         }
2256 }
2257
2258 void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
2259 {
2260         float fac = clamp(col.a, 0.0, 1.0);
2261         outcol = vec4(mix(hor, col.rgb, fac), col.a);
2262 }
2263
2264 void shade_alpha_opaque(vec4 col, out vec4 outcol)
2265 {
2266         outcol = vec4(col.rgb, 1.0);
2267 }
2268
2269 void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
2270 {
2271         outcol = vec4(col.rgb, col.a*obcol.a);
2272 }
2273
2274 /*********** NEW SHADER UTILITIES **************/
2275
2276 float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
2277 {
2278         /* compute fresnel reflectance without explicitly computing
2279          * the refracted direction */
2280         float c = abs(dot(Incoming, Normal));
2281         float g = eta * eta - 1.0 + c * c;
2282         float result;
2283
2284         if(g > 0.0) {
2285                 g = sqrt(g);
2286                 float A =(g - c)/(g + c);
2287                 float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
2288                 result = 0.5 * A * A *(1.0 + B * B);
2289         }
2290         else {
2291                 result = 1.0;  /* TIR (no refracted component) */
2292         }
2293
2294         return result;
2295 }
2296
2297 float hypot(float x, float y)
2298 {
2299         return sqrt(x*x + y*y);
2300 }
2301
2302 /*********** NEW SHADER NODES ***************/
2303
2304 #define NUM_LIGHTS 3
2305
2306 /* bsdfs */
2307
2308 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
2309 {
2310         /* ambient light */
2311         vec3 L = vec3(0.2);
2312
2313         /* directional lights */
2314         for(int i = 0; i < NUM_LIGHTS; i++) {
2315                 vec3 light_position = gl_LightSource[i].position.xyz;
2316                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
2317
2318                 float bsdf = max(dot(N, light_position), 0.0);
2319                 L += light_diffuse*bsdf;
2320         }
2321
2322         result = vec4(L*color.rgb, 1.0);
2323 }
2324
2325 void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
2326 {
2327         /* ambient light */
2328         vec3 L = vec3(0.2);
2329
2330         /* directional lights */
2331         for(int i = 0; i < NUM_LIGHTS; i++) {
2332                 vec3 light_position = gl_LightSource[i].position.xyz;
2333                 vec3 H = gl_LightSource[i].halfVector.xyz;
2334                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
2335                 vec3 light_specular = gl_LightSource[i].specular.rgb;
2336
2337                 /* we mix in some diffuse so low roughness still shows up */
2338                 float bsdf = 0.5*pow(max(dot(N, H), 0.0), 1.0/roughness);
2339                 bsdf += 0.5*max(dot(N, light_position), 0.0);
2340                 L += light_specular*bsdf;
2341         }
2342
2343         result = vec4(L*color.rgb, 1.0);
2344 }
2345
2346 void node_bsdf_anisotropic(vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, out vec4 result)
2347 {
2348         node_bsdf_diffuse(color, 0.0, N, result);
2349 }
2350
2351 void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
2352 {
2353         node_bsdf_diffuse(color, 0.0, N, result);
2354 }
2355
2356 void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result)
2357 {
2358         node_bsdf_diffuse(color, 0.0, N, result);
2359 }
2360
2361 void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
2362 {
2363         node_bsdf_diffuse(color, 0.0, N, result);
2364 }
2365
2366 void node_bsdf_transparent(vec4 color, out vec4 result)
2367 {
2368         /* this isn't right */
2369         result.r = color.r;
2370         result.g = color.g;
2371         result.b = color.b;
2372         result.a = 0.0;
2373 }
2374
2375 void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
2376 {
2377         node_bsdf_diffuse(color, 0.0, N, result);
2378 }
2379
2380 void node_subsurface_scattering(vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, out vec4 result)
2381 {
2382         node_bsdf_diffuse(color, 0.0, N, result);
2383 }
2384
2385 void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result)
2386 {
2387         result = color;
2388 }
2389
2390 void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
2391 {
2392         node_bsdf_diffuse(color, 0.0, N, result);
2393 }
2394
2395 void node_ambient_occlusion(vec4 color, out vec4 result)
2396 {
2397         result = color;
2398 }
2399
2400 /* emission */
2401
2402 void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
2403 {
2404         result = color*strength;
2405 }
2406
2407 /* background */
2408
2409 void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
2410 {
2411         vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
2412         vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
2413
2414         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
2415         worldvec = (gl_ModelViewMatrixInverse * co).xyz;
2416 }
2417
2418 void node_background(vec4 color, float strength, vec3 N, out vec4 result)
2419 {
2420         result = color*strength;
2421 }
2422
2423 /* closures */
2424
2425 void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
2426 {
2427         shader = mix(shader1, shader2, fac);
2428 }
2429
2430 void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
2431 {
2432         shader = shader1 + shader2;
2433 }
2434
2435 /* fresnel */
2436
2437 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
2438 {
2439         /* handle perspective/orthographic */
2440         vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0);
2441
2442         float eta = max(ior, 0.00001);
2443         result = fresnel_dielectric(I_view, N, (gl_FrontFacing)? eta: 1.0/eta);
2444 }
2445
2446 /* layer_weight */
2447
2448 void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float facing)
2449 {
2450         /* fresnel */
2451         float eta = max(1.0 - blend, 0.00001);
2452         vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0);
2453
2454         fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing)? 1.0/eta : eta );
2455
2456         /* facing */
2457         facing = abs(dot(I_view, N));
2458         if(blend != 0.5) {
2459                 blend = clamp(blend, 0.0, 0.99999);
2460                 blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend);
2461                 facing = pow(facing, blend);
2462         }
2463         facing = 1.0 - facing;
2464 }
2465
2466 /* gamma */
2467
2468 void node_gamma(vec4 col, float gamma, out vec4 outcol)
2469 {
2470         outcol = col;
2471
2472         if(col.r > 0.0)
2473                 outcol.r = compatible_pow(col.r, gamma);
2474         if(col.g > 0.0)
2475                 outcol.g = compatible_pow(col.g, gamma);
2476         if(col.b > 0.0)
2477                 outcol.b = compatible_pow(col.b, gamma);
2478 }
2479
2480 /* geometry */
2481
2482 void node_attribute(vec3 attr_uv, out vec4 outcol, out vec3 outvec, out float outf)
2483 {
2484         outcol = vec4(attr_uv, 1.0);
2485         outvec = attr_uv;
2486         outf = (attr_uv.x + attr_uv.y + attr_uv.z)/3.0;
2487 }
2488
2489 void node_uvmap(vec3 attr_uv, out vec3 outvec)
2490 {
2491         outvec = attr_uv;
2492 }
2493
2494 void node_geometry(vec3 I, vec3 N, mat4 toworld,
2495         out vec3 position, out vec3 normal, out vec3 tangent,
2496         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
2497         out float backfacing, out float pointiness)
2498 {
2499         position = (toworld*vec4(I, 1.0)).xyz;
2500         normal = (toworld*vec4(N, 0.0)).xyz;
2501         tangent = vec3(0.0);
2502         true_normal = normal;
2503
2504         /* handle perspective/orthographic */
2505         vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0);
2506         incoming = -(toworld*vec4(I_view, 0.0)).xyz;
2507
2508         parametric = vec3(0.0);
2509         backfacing = (gl_FrontFacing)? 0.0: 1.0;
2510         pointiness = 0.0;
2511 }
2512
2513 void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
2514         vec3 attr_orco, vec3 attr_uv,
2515         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
2516         out vec3 camera, out vec3 window, out vec3 reflection)
2517 {
2518         generated = attr_orco * 0.5 + vec3(0.5);
2519         normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz);
2520         uv = attr_uv;
2521         object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz;
2522         camera = vec3(I.xy, -I.z);
2523         vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
2524         window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
2525
2526         vec3 shade_I;
2527         shade_view(I, shade_I);
2528         vec3 view_reflection = reflect(shade_I, normalize(N));
2529         reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
2530 }
2531
2532 void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
2533         vec3 attr_orco, vec3 attr_uv,
2534         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
2535         out vec3 camera, out vec3 window, out vec3 reflection)
2536 {
2537         vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
2538         vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
2539
2540         vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
2541
2542         co = normalize(co);
2543         vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
2544
2545         generated = coords;
2546         normal = -coords;
2547         uv = vec3(attr_uv.xy, 0.0);
2548         object = coords;
2549
2550         camera = vec3(co.xy, -co.z);
2551         window = (gl_ProjectionMatrix[3][3] == 0.0) ? 
2552                       vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) : 
2553                       vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
2554
2555         reflection = -coords;
2556 }
2557
2558 /* textures */
2559
2560 void node_tex_gradient(vec3 co, out vec4 color, out float fac)
2561 {
2562         color = vec4(1.0);
2563         fac = 1.0;
2564 }
2565
2566 void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 color, out float fac)
2567 {
2568         color = vec4(1.0);
2569         fac = 1.0;
2570 }
2571
2572 void node_tex_brick(vec3 co, vec4 color1, vec4 color2, vec4 mortar, float scale, float mortar_size, float bias, float brick_width, float row_height, out vec4 color, out float fac)
2573 {
2574         color = vec4(1.0);
2575         fac = 1.0;
2576 }
2577
2578 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
2579 {
2580         color = vec4(1.0);
2581         fac = 1.0;
2582 }
2583
2584 void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
2585 {
2586         vec3 nco = normalize(co);
2587         float u = -atan(nco.y, nco.x)/(2.0*M_PI) + 0.5;
2588         float v = atan(nco.z, hypot(nco.x, nco.y))/M_PI + 0.5;
2589
2590         color = texture2D(ima, vec2(u, v));
2591 }
2592
2593 void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
2594 {
2595         vec3 nco = normalize(co);
2596
2597         nco.y -= 1.0;
2598
2599         float div = 2.0*sqrt(max(-0.5*nco.y, 0.0));
2600         if(div > 0.0)
2601                 nco /= div;
2602
2603         float u = 0.5*(nco.x + 1.0);
2604         float v = 0.5*(nco.z + 1.0);
2605
2606         color = texture2D(ima, vec2(u, v));
2607 }
2608
2609 void node_tex_environment_empty(vec3 co, out vec4 color)
2610 {
2611         color = vec4(1.0, 0.0, 1.0, 1.0);
2612 }
2613
2614 void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
2615 {
2616         color = texture2D(ima, co.xy);
2617         alpha = color.a;
2618 }
2619
2620 void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
2621 {
2622         color = vec4(0.0);
2623         alpha = 0.0;
2624 }
2625
2626 void node_tex_magic(vec3 p, float scale, float distortion, out vec4 color, out float fac)
2627 {
2628         color = vec4(1.0);
2629         fac = 1.0;
2630 }
2631
2632 void node_tex_musgrave(vec3 co, float scale, float detail, float dimension, float lacunarity, float offset, float gain, out vec4 color, out float fac)
2633 {
2634         color = vec4(1.0);
2635         fac = 1.0;
2636 }
2637
2638 void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
2639 {
2640         color = vec4(1.0);
2641         fac = 1.0;
2642 }
2643
2644 void node_tex_sky(vec3 co, out vec4 color)
2645 {
2646         color = vec4(1.0);
2647 }
2648
2649 void node_tex_voronoi(vec3 co, float scale, out vec4 color, out float fac)
2650 {
2651         color = vec4(1.0);
2652         fac = 1.0;
2653 }
2654
2655 void node_tex_wave(vec3 co, float scale, float distortion, float detail, float detail_scale, out vec4 color, out float fac)
2656 {
2657         color = vec4(1.0);
2658         fac = 1.0;
2659 }
2660
2661 /* light path */
2662
2663 void node_light_path(
2664         out float is_camera_ray,
2665         out float is_shadow_ray,
2666         out float is_diffuse_ray,
2667         out float is_glossy_ray,
2668         out float is_singular_ray,
2669         out float is_reflection_ray,
2670         out float is_transmission_ray,
2671         out float ray_length,
2672         out float ray_depth,
2673         out float transparent_depth,
2674         out float transmission_depth)
2675 {
2676         is_camera_ray = 1.0;
2677         is_shadow_ray = 0.0;
2678         is_diffuse_ray = 0.0;
2679         is_glossy_ray = 0.0;
2680         is_singular_ray = 0.0;
2681         is_reflection_ray = 0.0;
2682         is_transmission_ray = 0.0;
2683         ray_length = 1.0;
2684         ray_depth = 1.0;
2685         transparent_depth = 1.0;
2686         transmission_depth = 1.0;
2687 }
2688
2689 void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)
2690 {
2691         quadratic = strength;
2692         linear = strength;
2693         constant = strength;
2694 }
2695
2696 void node_object_info(out vec3 location, out float object_index, out float material_index, out float random)
2697 {
2698         location = vec3(0.0);
2699         object_index = 0.0;
2700         material_index = 0.0;
2701         random = 0.0;
2702 }
2703
2704 void node_normal_map(float strength, vec4 color, vec3 N, out vec3 result)
2705 {
2706         result = N;
2707 }
2708
2709 void node_bump(float strength, float dist, float height, vec3 N, out vec3 result)
2710 {
2711         result = N;
2712 }
2713
2714 /* output */
2715
2716 void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)
2717 {
2718         result = surface;
2719 }
2720
2721 void node_output_world(vec4 surface, vec4 volume, out vec4 result)
2722 {
2723         result = surface;
2724 }
2725
2726 /* ********************** matcap style render ******************** */
2727
2728 void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
2729 {
2730         vec3 normal;
2731         vec2 tex;
2732         
2733 #ifndef USE_OPENSUBDIV
2734         /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors 
2735          * between shader stages and we want the full range of the normal */
2736         normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0);
2737         if (normal.z < 0.0) {
2738                 normal.z = 0.0;
2739         }
2740         normal = normalize(normal);
2741 #else
2742         normal = inpt.v.normal;
2743         mask = vec4(1.0, 1.0, 1.0, 1.0);
2744 #endif
2745
2746         tex.x = 0.5 + 0.49 * normal.x;
2747         tex.y = 0.5 + 0.49 * normal.y;
2748         result = texture2D(ima, tex) * mask;
2749 }