ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / shaders / stdosl.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.  All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 // * Redistributions of source code must retain the above copyright
8 //   notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 //   notice, this list of conditions and the following disclaimer in the
11 //   documentation and/or other materials provided with the distribution.
12 // * Neither the name of Sony Pictures Imageworks nor the names of its
13 //   contributors may be used to endorse or promote products derived from
14 //   this software without specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 /////////////////////////////////////////////////////////////////////////////
27
28 #ifndef CCL_STDOSL_H
29 #define CCL_STDOSL_H
30
31 #ifndef M_PI
32 #  define M_PI 3.1415926535897932       /* pi */
33 #  define M_PI_2 1.5707963267948966     /* pi/2 */
34 #  define M_PI_4 0.7853981633974483     /* pi/4 */
35 #  define M_2_PI 0.6366197723675813     /* 2/pi */
36 #  define M_2PI 6.2831853071795865      /* 2*pi */
37 #  define M_4PI 12.566370614359173      /* 4*pi */
38 #  define M_2_SQRTPI 1.1283791670955126 /* 2/sqrt(pi) */
39 #  define M_E 2.7182818284590452        /* e (Euler's number) */
40 #  define M_LN2 0.6931471805599453      /* ln(2) */
41 #  define M_LN10 2.3025850929940457     /* ln(10) */
42 #  define M_LOG2E 1.4426950408889634    /* log_2(e) */
43 #  define M_LOG10E 0.4342944819032518   /* log_10(e) */
44 #  define M_SQRT2 1.4142135623730950    /* sqrt(2) */
45 #  define M_SQRT1_2 0.7071067811865475  /* 1/sqrt(2) */
46 #endif
47
48 // Declaration of built-in functions and closures
49 #define BUILTIN [[int builtin = 1]]
50 #define BUILTIN_DERIV [[ int builtin = 1, int deriv = 1 ]]
51
52 #define PERCOMP1(name) \
53   normal name(normal x) BUILTIN; \
54   vector name(vector x) BUILTIN; \
55   point name(point x) BUILTIN; \
56   color name(color x) BUILTIN; \
57   float name(float x) BUILTIN;
58
59 #define PERCOMP2(name) \
60   normal name(normal x, normal y) BUILTIN; \
61   vector name(vector x, vector y) BUILTIN; \
62   point name(point x, point y) BUILTIN; \
63   color name(color x, color y) BUILTIN; \
64   float name(float x, float y) BUILTIN;
65
66 #define PERCOMP2F(name) \
67   normal name(normal x, float y) BUILTIN; \
68   vector name(vector x, float y) BUILTIN; \
69   point name(point x, float y) BUILTIN; \
70   color name(color x, float y) BUILTIN; \
71   float name(float x, float y) BUILTIN;
72
73 // Basic math
74 normal degrees(normal x)
75 {
76   return x * (180.0 / M_PI);
77 }
78 vector degrees(vector x)
79 {
80   return x * (180.0 / M_PI);
81 }
82 point degrees(point x)
83 {
84   return x * (180.0 / M_PI);
85 }
86 color degrees(color x)
87 {
88   return x * (180.0 / M_PI);
89 }
90 float degrees(float x)
91 {
92   return x * (180.0 / M_PI);
93 }
94 normal radians(normal x)
95 {
96   return x * (M_PI / 180.0);
97 }
98 vector radians(vector x)
99 {
100   return x * (M_PI / 180.0);
101 }
102 point radians(point x)
103 {
104   return x * (M_PI / 180.0);
105 }
106 color radians(color x)
107 {
108   return x * (M_PI / 180.0);
109 }
110 float radians(float x)
111 {
112   return x * (M_PI / 180.0);
113 }
114 PERCOMP1(cos)
115 PERCOMP1(sin)
116 PERCOMP1(tan)
117 PERCOMP1(acos)
118 PERCOMP1(asin)
119 PERCOMP1(atan)
120 PERCOMP2(atan2)
121 PERCOMP1(cosh)
122 PERCOMP1(sinh)
123 PERCOMP1(tanh)
124 PERCOMP2F(pow)
125 PERCOMP1(exp)
126 PERCOMP1(exp2)
127 PERCOMP1(expm1)
128 PERCOMP1(log)
129 point log(point a, float b)
130 {
131   return log(a) / log(b);
132 }
133 vector log(vector a, float b)
134 {
135   return log(a) / log(b);
136 }
137 color log(color a, float b)
138 {
139   return log(a) / log(b);
140 }
141 float log(float a, float b)
142 {
143   return log(a) / log(b);
144 }
145 PERCOMP1(log2)
146 PERCOMP1(log10)
147 PERCOMP1(logb)
148 PERCOMP1(sqrt)
149 PERCOMP1(inversesqrt)
150 float hypot(float a, float b)
151 {
152   return sqrt(a * a + b * b);
153 }
154 float hypot(float a, float b, float c)
155 {
156   return sqrt(a * a + b * b + c * c);
157 }
158 PERCOMP1(abs)
159 int abs(int x) BUILTIN;
160 PERCOMP1(fabs)
161 int fabs(int x) BUILTIN;
162 PERCOMP1(sign)
163 PERCOMP1(floor)
164 PERCOMP1(ceil)
165 PERCOMP1(round)
166 PERCOMP1(trunc)
167 PERCOMP2(fmod)
168 PERCOMP2F(fmod)
169 int mod(int a, int b)
170 {
171   return a - b * (int)floor(a / b);
172 }
173 point mod(point a, point b)
174 {
175   return a - b * floor(a / b);
176 }
177 vector mod(vector a, vector b)
178 {
179   return a - b * floor(a / b);
180 }
181 normal mod(normal a, normal b)
182 {
183   return a - b * floor(a / b);
184 }
185 color mod(color a, color b)
186 {
187   return a - b * floor(a / b);
188 }
189 point mod(point a, float b)
190 {
191   return a - b * floor(a / b);
192 }
193 vector mod(vector a, float b)
194 {
195   return a - b * floor(a / b);
196 }
197 normal mod(normal a, float b)
198 {
199   return a - b * floor(a / b);
200 }
201 color mod(color a, float b)
202 {
203   return a - b * floor(a / b);
204 }
205 float mod(float a, float b)
206 {
207   return a - b * floor(a / b);
208 }
209 PERCOMP2(min)
210 int min(int a, int b) BUILTIN;
211 PERCOMP2(max)
212 int max(int a, int b) BUILTIN;
213 normal clamp(normal x, normal minval, normal maxval)
214 {
215   return max(min(x, maxval), minval);
216 }
217 vector clamp(vector x, vector minval, vector maxval)
218 {
219   return max(min(x, maxval), minval);
220 }
221 point clamp(point x, point minval, point maxval)
222 {
223   return max(min(x, maxval), minval);
224 }
225 color clamp(color x, color minval, color maxval)
226 {
227   return max(min(x, maxval), minval);
228 }
229 float clamp(float x, float minval, float maxval)
230 {
231   return max(min(x, maxval), minval);
232 }
233 int clamp(int x, int minval, int maxval)
234 {
235   return max(min(x, maxval), minval);
236 }
237 #if 0
238 normal mix (normal x, normal y, normal a) { return x*(1-a) + y*a; }
239 normal mix (normal x, normal y, float  a) { return x*(1-a) + y*a; }
240 vector mix (vector x, vector y, vector a) { return x*(1-a) + y*a; }
241 vector mix (vector x, vector y, float  a) { return x*(1-a) + y*a; }
242 point  mix (point  x, point  y, point  a) { return x*(1-a) + y*a; }
243 point  mix (point  x, point  y, float  a) { return x*(1-a) + y*a; }
244 color  mix (color  x, color  y, color  a) { return x*(1-a) + y*a; }
245 color  mix (color  x, color  y, float  a) { return x*(1-a) + y*a; }
246 float  mix (float  x, float  y, float  a) { return x*(1-a) + y*a; }
247 #else
248 normal mix(normal x, normal y, normal a) BUILTIN;
249 normal mix(normal x, normal y, float a) BUILTIN;
250 vector mix(vector x, vector y, vector a) BUILTIN;
251 vector mix(vector x, vector y, float a) BUILTIN;
252 point mix(point x, point y, point a) BUILTIN;
253 point mix(point x, point y, float a) BUILTIN;
254 color mix(color x, color y, color a) BUILTIN;
255 color mix(color x, color y, float a) BUILTIN;
256 float mix(float x, float y, float a) BUILTIN;
257 #endif
258 int isnan(float x) BUILTIN;
259 int isinf(float x) BUILTIN;
260 int isfinite(float x) BUILTIN;
261 float erf(float x) BUILTIN;
262 float erfc(float x) BUILTIN;
263
264 // Vector functions
265
266 vector cross(vector a, vector b) BUILTIN;
267 float dot(vector a, vector b) BUILTIN;
268 float length(vector v) BUILTIN;
269 float distance(point a, point b) BUILTIN;
270 float distance(point a, point b, point q)
271 {
272   vector d = b - a;
273   float dd = dot(d, d);
274   if (dd == 0.0)
275     return distance(q, a);
276   float t = dot(q - a, d) / dd;
277   return distance(q, a + clamp(t, 0.0, 1.0) * d);
278 }
279 normal normalize(normal v) BUILTIN;
280 vector normalize(vector v) BUILTIN;
281 vector faceforward(vector N, vector I, vector Nref) BUILTIN;
282 vector faceforward(vector N, vector I) BUILTIN;
283 vector reflect(vector I, vector N)
284 {
285   return I - 2 * dot(N, I) * N;
286 }
287 vector refract(vector I, vector N, float eta)
288 {
289   float IdotN = dot(I, N);
290   float k = 1 - eta * eta * (1 - IdotN * IdotN);
291   return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k)));
292 }
293 void fresnel(vector I,
294              normal N,
295              float eta,
296              output float Kr,
297              output float Kt,
298              output vector R,
299              output vector T)
300 {
301   float sqr(float x)
302   {
303     return x * x;
304   }
305   float c = dot(I, N);
306   if (c < 0)
307     c = -c;
308   R = reflect(I, N);
309   float g = 1.0 / sqr(eta) - 1.0 + c * c;
310   if (g >= 0.0) {
311     g = sqrt(g);
312     float beta = g - c;
313     float F = (c * (g + c) - 1.0) / (c * beta + 1.0);
314     F = 0.5 * (1.0 + sqr(F));
315     F *= sqr(beta / (g + c));
316     Kr = F;
317     Kt = (1.0 - Kr) * eta * eta;
318     // OPT: the following recomputes some of the above values, but it
319     // gives us the same result as if the shader-writer called refract()
320     T = refract(I, N, eta);
321   }
322   else {
323     // total internal reflection
324     Kr = 1.0;
325     Kt = 0.0;
326     T = vector(0, 0, 0);
327   }
328 }
329
330 void fresnel(vector I, normal N, float eta, output float Kr, output float Kt)
331 {
332   vector R, T;
333   fresnel(I, N, eta, Kr, Kt, R, T);
334 }
335
336 normal transform(matrix Mto, normal p) BUILTIN;
337 vector transform(matrix Mto, vector p) BUILTIN;
338 point transform(matrix Mto, point p) BUILTIN;
339 normal transform(string from, string to, normal p) BUILTIN;
340 vector transform(string from, string to, vector p) BUILTIN;
341 point transform(string from, string to, point p) BUILTIN;
342 normal transform(string to, normal p)
343 {
344   return transform("common", to, p);
345 }
346 vector transform(string to, vector p)
347 {
348   return transform("common", to, p);
349 }
350 point transform(string to, point p)
351 {
352   return transform("common", to, p);
353 }
354
355 float transformu(string tounits, float x) BUILTIN;
356 float transformu(string fromunits, string tounits, float x) BUILTIN;
357
358 point rotate(point p, float angle, point a, point b)
359 {
360   vector axis = normalize(b - a);
361   float cosang, sinang;
362   /* Older OSX has major issues with sincos() function,
363      * it's likely a big in OSL or LLVM. For until we've
364      * updated to new versions of this libraries we'll
365      * use a workaround to prevent possible crashes on all
366      * the platforms.
367      *
368      * Shouldn't be that bad because it's mainly used for
369      * anisotropic shader where angle is usually constant.
370      */
371 #if 0
372     sincos (angle, sinang, cosang);
373 #else
374   sinang = sin(angle);
375   cosang = cos(angle);
376 #endif
377   float cosang1 = 1.0 - cosang;
378   float x = axis[0], y = axis[1], z = axis[2];
379   matrix M = matrix(x * x + (1.0 - x * x) * cosang,
380                     x * y * cosang1 + z * sinang,
381                     x * z * cosang1 - y * sinang,
382                     0.0,
383                     x * y * cosang1 - z * sinang,
384                     y * y + (1.0 - y * y) * cosang,
385                     y * z * cosang1 + x * sinang,
386                     0.0,
387                     x * z * cosang1 + y * sinang,
388                     y * z * cosang1 - x * sinang,
389                     z * z + (1.0 - z * z) * cosang,
390                     0.0,
391                     0.0,
392                     0.0,
393                     0.0,
394                     1.0);
395   return transform(M, p - a) + a;
396 }
397
398 normal ensure_valid_reflection(normal Ng, vector I, normal N)
399 {
400   /* The implementation here mirrors the one in kernel_montecarlo.h,
401      * check there for an explanation of the algorithm. */
402
403   float sqr(float x)
404   {
405     return x * x;
406   }
407
408   vector R = 2 * dot(N, I) * N - I;
409
410   float threshold = min(0.9 * dot(Ng, I), 0.01);
411   if (dot(Ng, R) >= threshold) {
412     return N;
413   }
414
415   float NdotNg = dot(N, Ng);
416   vector X = normalize(N - NdotNg * Ng);
417
418   float Ix = dot(I, X), Iz = dot(I, Ng);
419   float Ix2 = sqr(Ix), Iz2 = sqr(Iz);
420   float a = Ix2 + Iz2;
421
422   float b = sqrt(Ix2 * (a - sqr(threshold)));
423   float c = Iz * threshold + a;
424
425   float fac = 0.5 / a;
426   float N1_z2 = fac * (b + c), N2_z2 = fac * (-b + c);
427   int valid1 = (N1_z2 > 1e-5) && (N1_z2 <= (1.0 + 1e-5));
428   int valid2 = (N2_z2 > 1e-5) && (N2_z2 <= (1.0 + 1e-5));
429
430   float N_new_x, N_new_z;
431   if (valid1 && valid2) {
432     float N1_x = sqrt(1.0 - N1_z2), N1_z = sqrt(N1_z2);
433     float N2_x = sqrt(1.0 - N2_z2), N2_z = sqrt(N2_z2);
434
435     float R1 = 2 * (N1_x * Ix + N1_z * Iz) * N1_z - Iz;
436     float R2 = 2 * (N2_x * Ix + N2_z * Iz) * N2_z - Iz;
437
438     valid1 = (R1 >= 1e-5);
439     valid2 = (R2 >= 1e-5);
440     if (valid1 && valid2) {
441       N_new_x = (R1 < R2) ? N1_x : N2_x;
442       N_new_z = (R1 < R2) ? N1_z : N2_z;
443     }
444     else {
445       N_new_x = (R1 > R2) ? N1_x : N2_x;
446       N_new_z = (R1 > R2) ? N1_z : N2_z;
447     }
448   }
449   else if (valid1 || valid2) {
450     float Nz2 = valid1 ? N1_z2 : N2_z2;
451     N_new_x = sqrt(1.0 - Nz2);
452     N_new_z = sqrt(Nz2);
453   }
454   else {
455     return Ng;
456   }
457
458   return N_new_x * X + N_new_z * Ng;
459 }
460
461 // Color functions
462
463 float luminance(color c) BUILTIN;
464 color blackbody(float temperatureK) BUILTIN;
465 color wavelength_color(float wavelength_nm) BUILTIN;
466
467 color transformc(string to, color x)
468 {
469   color rgb_to_hsv(color rgb)
470   {  // See Foley & van Dam
471     float r = rgb[0], g = rgb[1], b = rgb[2];
472     float mincomp = min(r, min(g, b));
473     float maxcomp = max(r, max(g, b));
474     float delta = maxcomp - mincomp;  // chroma
475     float h, s, v;
476     v = maxcomp;
477     if (maxcomp > 0)
478       s = delta / maxcomp;
479     else
480       s = 0;
481     if (s <= 0)
482       h = 0;
483     else {
484       if (r >= maxcomp)
485         h = (g - b) / delta;
486       else if (g >= maxcomp)
487         h = 2 + (b - r) / delta;
488       else
489         h = 4 + (r - g) / delta;
490       h /= 6;
491       if (h < 0)
492         h += 1;
493     }
494     return color(h, s, v);
495   }
496
497   color rgb_to_hsl(color rgb)
498   {  // See Foley & van Dam
499     // First convert rgb to hsv, then to hsl
500     float minval = min(rgb[0], min(rgb[1], rgb[2]));
501     color hsv = rgb_to_hsv(rgb);
502     float maxval = hsv[2];  // v == maxval
503     float h = hsv[0], s, l = (minval + maxval) / 2;
504     if (minval == maxval)
505       s = 0;  // special 'achromatic' case, hue is 0
506     else if (l <= 0.5)
507       s = (maxval - minval) / (maxval + minval);
508     else
509       s = (maxval - minval) / (2 - maxval - minval);
510     return color(h, s, l);
511   }
512
513   color r;
514   if (to == "rgb" || to == "RGB")
515     r = x;
516   else if (to == "hsv")
517     r = rgb_to_hsv(x);
518   else if (to == "hsl")
519     r = rgb_to_hsl(x);
520   else if (to == "YIQ")
521     r = color(dot(vector(0.299, 0.587, 0.114), (vector)x),
522               dot(vector(0.596, -0.275, -0.321), (vector)x),
523               dot(vector(0.212, -0.523, 0.311), (vector)x));
524   else if (to == "XYZ")
525     r = color(dot(vector(0.412453, 0.357580, 0.180423), (vector)x),
526               dot(vector(0.212671, 0.715160, 0.072169), (vector)x),
527               dot(vector(0.019334, 0.119193, 0.950227), (vector)x));
528   else {
529     error("Unknown color space \"%s\"", to);
530     r = x;
531   }
532   return r;
533 }
534
535 color transformc(string from, string to, color x)
536 {
537   color hsv_to_rgb(color c)
538   {  // Reference: Foley & van Dam
539     float h = c[0], s = c[1], v = c[2];
540     color r;
541     if (s < 0.0001) {
542       r = v;
543     }
544     else {
545       h = 6 * (h - floor(h));  // expand to [0..6)
546       int hi = (int)h;
547       float f = h - hi;
548       float p = v * (1 - s);
549       float q = v * (1 - s * f);
550       float t = v * (1 - s * (1 - f));
551       if (hi == 0)
552         r = color(v, t, p);
553       else if (hi == 1)
554         r = color(q, v, p);
555       else if (hi == 2)
556         r = color(p, v, t);
557       else if (hi == 3)
558         r = color(p, q, v);
559       else if (hi == 4)
560         r = color(t, p, v);
561       else
562         r = color(v, p, q);
563     }
564     return r;
565   }
566
567   color hsl_to_rgb(color c)
568   {
569     float h = c[0], s = c[1], l = c[2];
570     // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
571     float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
572     color r;
573     if (v <= 0) {
574       r = 0;
575     }
576     else {
577       float min = 2 * l - v;
578       s = (v - min) / v;
579       r = hsv_to_rgb(color(h, s, v));
580     }
581     return r;
582   }
583
584   color r;
585   if (from == "rgb" || from == "RGB")
586     r = x;
587   else if (from == "hsv")
588     r = hsv_to_rgb(x);
589   else if (from == "hsl")
590     r = hsl_to_rgb(x);
591   else if (from == "YIQ")
592     r = color(dot(vector(1, 0.9557, 0.6199), (vector)x),
593               dot(vector(1, -0.2716, -0.6469), (vector)x),
594               dot(vector(1, -1.1082, 1.7051), (vector)x));
595   else if (from == "XYZ")
596     r = color(dot(vector(3.240479, -1.537150, -0.498535), (vector)x),
597               dot(vector(-0.969256, 1.875991, 0.041556), (vector)x),
598               dot(vector(0.055648, -0.204043, 1.057311), (vector)x));
599   else {
600     error("Unknown color space \"%s\"", to);
601     r = x;
602   }
603   return transformc(to, r);
604 }
605
606 // Matrix functions
607
608 float determinant(matrix m) BUILTIN;
609 matrix transpose(matrix m) BUILTIN;
610
611 // Pattern generation
612
613 color step(color edge, color x) BUILTIN;
614 point step(point edge, point x) BUILTIN;
615 vector step(vector edge, vector x) BUILTIN;
616 normal step(normal edge, normal x) BUILTIN;
617 float step(float edge, float x) BUILTIN;
618 float smoothstep(float edge0, float edge1, float x) BUILTIN;
619
620 float linearstep(float edge0, float edge1, float x)
621 {
622   float result;
623   if (edge0 != edge1) {
624     float xclamped = clamp(x, edge0, edge1);
625     result = (xclamped - edge0) / (edge1 - edge0);
626   }
627   else {  // special case: edges coincide
628     result = step(edge0, x);
629   }
630   return result;
631 }
632
633 float smooth_linearstep(float edge0, float edge1, float x_, float eps_)
634 {
635   float result;
636   if (edge0 != edge1) {
637     float rampup(float x, float r)
638     {
639       return 0.5 / r * x * x;
640     }
641     float width_inv = 1.0 / (edge1 - edge0);
642     float eps = eps_ * width_inv;
643     float x = (x_ - edge0) * width_inv;
644     if (x <= -eps)
645       result = 0;
646     else if (x >= eps && x <= 1.0 - eps)
647       result = x;
648     else if (x >= 1.0 + eps)
649       result = 1;
650     else if (x < eps)
651       result = rampup(x + eps, 2.0 * eps);
652     else /* if (x < 1.0+eps) */
653       result = 1.0 - rampup(1.0 + eps - x, 2.0 * eps);
654   }
655   else {
656     result = step(edge0, x_);
657   }
658   return result;
659 }
660
661 float aastep(float edge, float s, float dedge, float ds)
662 {
663   // Box filtered AA step
664   float width = fabs(dedge) + fabs(ds);
665   float halfwidth = 0.5 * width;
666   float e1 = edge - halfwidth;
667   return (s <= e1) ? 0.0 : ((s >= (edge + halfwidth)) ? 1.0 : (s - e1) / width);
668 }
669 float aastep(float edge, float s, float ds)
670 {
671   return aastep(edge, s, filterwidth(edge), ds);
672 }
673 float aastep(float edge, float s)
674 {
675   return aastep(edge, s, filterwidth(edge), filterwidth(s));
676 }
677
678 // Derivatives and area operators
679
680 // Displacement functions
681
682 // String functions
683 int strlen(string s) BUILTIN;
684 int hash(string s) BUILTIN;
685 int getchar(string s, int index) BUILTIN;
686 int startswith(string s, string prefix) BUILTIN;
687 int endswith(string s, string suffix) BUILTIN;
688 string substr(string s, int start, int len) BUILTIN;
689 string substr(string s, int start)
690 {
691   return substr(s, start, strlen(s));
692 }
693 float stof(string str) BUILTIN;
694 int stoi(string str) BUILTIN;
695
696 // Define concat in terms of shorter concat
697 string concat(string a, string b, string c)
698 {
699   return concat(concat(a, b), c);
700 }
701 string concat(string a, string b, string c, string d)
702 {
703   return concat(concat(a, b, c), d);
704 }
705 string concat(string a, string b, string c, string d, string e)
706 {
707   return concat(concat(a, b, c, d), e);
708 }
709 string concat(string a, string b, string c, string d, string e, string f)
710 {
711   return concat(concat(a, b, c, d, e), f);
712 }
713
714 // Texture
715
716 // Closures
717
718 closure color diffuse(normal N) BUILTIN;
719 closure color oren_nayar(normal N, float sigma) BUILTIN;
720 closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
721 closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
722 closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
723 closure color glossy_toon(normal N, float size, float smooth) BUILTIN;
724 closure color translucent(normal N) BUILTIN;
725 closure color reflection(normal N) BUILTIN;
726 closure color refraction(normal N, float eta) BUILTIN;
727 closure color transparent() BUILTIN;
728 closure color microfacet_ggx(normal N, float ag) BUILTIN;
729 closure color microfacet_ggx_aniso(normal N, vector T, float ax, float ay) BUILTIN;
730 closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
731 closure color microfacet_multi_ggx(normal N, float ag, color C) BUILTIN;
732 closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN;
733 closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;
734 closure color microfacet_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
735 closure color microfacet_ggx_aniso_fresnel(
736     normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
737 closure color
738 microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
739 closure color microfacet_multi_ggx_aniso_fresnel(
740     normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN;
741 closure color
742 microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN;
743 closure color microfacet_beckmann(normal N, float ab) BUILTIN;
744 closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN;
745 closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
746 closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN;
747 closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
748 closure color emission() BUILTIN;
749 closure color background() BUILTIN;
750 closure color holdout() BUILTIN;
751 closure color ambient_occlusion() BUILTIN;
752 closure color principled_diffuse(normal N, float roughness) BUILTIN;
753 closure color principled_sheen(normal N) BUILTIN;
754 closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN;
755
756 // BSSRDF
757 closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;
758
759 // Hair
760 closure color
761 hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
762 closure color
763 hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
764 closure color principled_hair(normal N,
765                               color sigma,
766                               float roughnessu,
767                               float roughnessv,
768                               float coat,
769                               float alpha,
770                               float eta) BUILTIN;
771
772 // Volume
773 closure color henyey_greenstein(float g) BUILTIN;
774 closure color absorption() BUILTIN;
775
776 // OSL 1.5 Microfacet functions
777 closure color microfacet(
778     string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract)
779 {
780   /* GGX */
781   if (distribution == "ggx" || distribution == "default") {
782     if (!refract) {
783       if (xalpha == yalpha) {
784         /* Isotropic */
785         return microfacet_ggx(N, xalpha);
786       }
787       else {
788         /* Anisotropic */
789         return microfacet_ggx_aniso(N, U, xalpha, yalpha);
790       }
791     }
792     else {
793       return microfacet_ggx_refraction(N, xalpha, eta);
794     }
795   }
796   /* Beckmann */
797   else {
798     if (!refract) {
799       if (xalpha == yalpha) {
800         /* Isotropic */
801         return microfacet_beckmann(N, xalpha);
802       }
803       else {
804         /* Anisotropic */
805         return microfacet_beckmann_aniso(N, U, xalpha, yalpha);
806       }
807     }
808     else {
809       return microfacet_beckmann_refraction(N, xalpha, eta);
810     }
811   }
812 }
813
814 closure color microfacet(string distribution, normal N, float alpha, float eta, int refract)
815 {
816   return microfacet(distribution, N, vector(0), alpha, alpha, eta, refract);
817 }
818
819 // Renderer state
820 int backfacing() BUILTIN;
821 int raytype(string typename) BUILTIN;
822 // the individual 'isFOOray' functions are deprecated
823 int iscameraray()
824 {
825   return raytype("camera");
826 }
827 int isdiffuseray()
828 {
829   return raytype("diffuse");
830 }
831 int isglossyray()
832 {
833   return raytype("glossy");
834 }
835 int isshadowray()
836 {
837   return raytype("shadow");
838 }
839 int getmatrix(string fromspace, string tospace, output matrix M) BUILTIN;
840 int getmatrix(string fromspace, output matrix M)
841 {
842   return getmatrix(fromspace, "common", M);
843 }
844
845 // Miscellaneous
846
847 #undef BUILTIN
848 #undef BUILTIN_DERIV
849 #undef PERCOMP1
850 #undef PERCOMP2
851 #undef PERCOMP2F
852
853 #endif /* CCL_STDOSL_H */