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