#line 1 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 97 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 111 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 137 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 145 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 164 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 180 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 278 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 293 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 310 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 489 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 670 "C:\\cygwin64\\tmp\\OCL6424T10.cl" enum InterpolationType { INTERPOLATION_NONE = -1, INTERPOLATION_LINEAR = 0, INTERPOLATION_CLOSEST = 1, INTERPOLATION_CUBIC = 2, INTERPOLATION_SMART = 3, }; enum ExtensionType { EXTENSION_REPEAT = 0, EXTENSION_EXTEND = 1, EXTENSION_CLIP = 2, }; #line 704 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 718 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 728 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 738 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 820 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 1366 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 1450 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 1990 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2014 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2022 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2056 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2108 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float min4(float a, float b, float c, float d) { return min(min(a, b), min(c, d)); } float max4(float a, float b, float c, float d) { return max(max(a, b), max(c, d)); } #line 2132 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float saturate(float a) { return clamp(a, 0.0f, 1.0f); } int float_to_int(float f) { return (int)f; } int floor_to_int(float f) { return float_to_int(floor(((float)(f)))); } int ceil_to_int(float f) { return float_to_int(ceil(((float)(f)))); } float signf(float f) { return (f < 0.0f)? -1.0f: 1.0f; } float nonzerof(float f, float eps) { if(fabs(((float)(f))) < eps) return signf(f)*eps; else return f; } float smoothstepf(float f) { float ff = f*f; return (3.0f*ff - 2.0f*ff*f); } #line 2186 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2195 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2282 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2348 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2357 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2366 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2468 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float len(const float3 a) { return native_sqrt(((float)(dot(a, a)))); } float len_squared(const float3 a) { return dot(a, a); } #line 2501 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 normalize_len(const float3 a, float *t) { *t = len(a); return a/(*t); } float3 safe_normalize(const float3 a) { float t = len(a); return (t!=0)? a/t: a; } #line 2564 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 float2_to_float3(const float2 a) { return ((float3)(a . x, a . y, 0.0f)); } float3 float4_to_float3(const float4 a) { return ((float3)(a . x, a . y, a . z)); } float4 float3_to_float4(const float3 a) { return ((float4)(a . x, a . y, a . z, 1.0f)); } #line 2598 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 interp(float3 a, float3 b, float t) { return a + t*(b - a); } bool is_zero(const float3 a) { return (a.x == 0.0f && a.y == 0.0f && a.z == 0.0f); } float reduce_add(const float3 a) { return (a.x + a.y + a.z); } float average(const float3 a) { return reduce_add(a)*(1.0f/3.0f); } #line 2648 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2846 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2896 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2938 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 2947 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 3014 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 3083 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void make_orthonormals(const float3 N, float3 *a, float3 *b) { #line 3100 "C:\\cygwin64\\tmp\\OCL6424T10.cl" if(N.x != N.y || N.x != N.z) *a = ((float3)(N . z-N . y, N . x-N . z, N . y-N . x)); else *a = ((float3)(N . z-N . y, N . x+N . z, -N . y-N . x)); *a = normalize(*a); *b = cross(N, *a); } float3 safe_invert_color(float3 a) { float x, y, z; x = (a.x != 0.0f)? 1.0f/a.x: 0.0f; y = (a.y != 0.0f)? 1.0f/a.y: 0.0f; z = (a.z != 0.0f)? 1.0f/a.z: 0.0f; return ((float3)(x, y, z)); } float3 safe_divide_color(float3 a, float3 b) { float x, y, z; x = (b.x != 0.0f)? a.x/b.x: 0.0f; y = (b.y != 0.0f)? a.y/b.y: 0.0f; z = (b.z != 0.0f)? a.z/b.z: 0.0f; return ((float3)(x, y, z)); } float3 safe_divide_even_color(float3 a, float3 b) { float x, y, z; x = (b.x != 0.0f)? a.x/b.x: 0.0f; y = (b.y != 0.0f)? a.y/b.y: 0.0f; z = (b.z != 0.0f)? a.z/b.z: 0.0f; if(b.x == 0.0f) { if(b.y == 0.0f) { x = z; y = z; } else if(b.z == 0.0f) { x = y; z = y; } else x = 0.5f*(y + z); } else if(b.y == 0.0f) { if(b.z == 0.0f) { y = x; z = x; } else y = 0.5f*(x + z); } else if(b.z == 0.0f) { z = 0.5f*(x + y); } return ((float3)(x, y, z)); } float3 rotate_around_axis(float3 p, float3 axis, float angle) { float costheta = native_cos(((float)(angle))); float sintheta = native_sin(((float)(angle))); float3 r; r.x = ((costheta + (1 - costheta) * axis.x * axis.x) * p.x) + (((1 - costheta) * axis.x * axis.y - axis.z * sintheta) * p.y) + (((1 - costheta) * axis.x * axis.z + axis.y * sintheta) * p.z); r.y = (((1 - costheta) * axis.x * axis.y + axis.z * sintheta) * p.x) + ((costheta + (1 - costheta) * axis.y * axis.y) * p.y) + (((1 - costheta) * axis.y * axis.z - axis.x * sintheta) * p.z); r.z = (((1 - costheta) * axis.x * axis.z - axis.y * sintheta) * p.x) + (((1 - costheta) * axis.y * axis.z + axis.x * sintheta) * p.y) + ((costheta + (1 - costheta) * axis.z * axis.z) * p.z); return r; } float safe_sqrtf(float f) { return native_sqrt(((float)(max(f, 0.0f)))); } float safe_asinf(float a) { return asin(((float)(clamp(a, -1.0f, 1.0f)))); } float safe_acosf(float a) { return acos(((float)(clamp(a, -1.0f, 1.0f)))); } float compatible_powf(float x, float y) { if(y == 0.0f) return 1.0f; if(x < 0.0f) { if(fmod((float)(-y), (float)(2.0f)) == 0.0f) return pow(((float)(-x)), ((float)(y))); else return -pow(((float)(-x)), ((float)(y))); } else if(x == 0.0f) return 0.0f; return pow(((float)(x)), ((float)(y))); } float safe_powf(float a, float b) { if((a < 0.0f && b != float_to_int(b))) return 0.0f; return compatible_powf(a, b); } float safe_logf(float a, float b) { if((a < 0.0f || b < 0.0f)) return 0.0f; return native_log(((float)(a)))/native_log(((float)(b))); } float safe_divide(float a, float b) { return (b != 0.0f)? a/b: 0.0f; } float safe_modulo(float a, float b) { return (b != 0.0f)? fmod((float)(a), (float)(b)): 0.0f; } bool ray_sphere_intersect( float3 ray_P, float3 ray_D, float ray_t, float3 sphere_P, float sphere_radius, float3 *isect_P, float *isect_t) { float3 d = sphere_P - ray_P; float radiussq = sphere_radius*sphere_radius; float tsq = dot(d, d); if(tsq > radiussq) { float tp = dot(d, ray_D); if(tp < 0.0f) return 0; float dsq = tsq - tp*tp; if(dsq > radiussq) return 0; float t = tp - native_sqrt(((float)(radiussq - dsq))); if(t < ray_t) { *isect_t = t; *isect_P = ray_P + ray_D*t; return 1; } } return 0; } bool ray_aligned_disk_intersect( float3 ray_P, float3 ray_D, float ray_t, float3 disk_P, float disk_radius, float3 *isect_P, float *isect_t) { float disk_t; float3 disk_N = normalize_len(ray_P - disk_P, &disk_t); float div = dot(ray_D, disk_N); if((div == 0.0f)) return 0; float t = -disk_t/div; if(t < 0.0f || t > ray_t) return 0; float3 P = ray_P + ray_D*t; if(len_squared(P - disk_P) > disk_radius*disk_radius) return 0; *isect_P = P; *isect_t = t; return 1; } bool ray_triangle_intersect( float3 ray_P, float3 ray_D, float ray_t, float3 v0, float3 v1, float3 v2, float3 *isect_P, float *isect_t) { float3 e1 = v1 - v0; float3 e2 = v2 - v0; float3 s1 = cross(ray_D, e2); const float divisor = dot(s1, e1); if((divisor == 0.0f)) return 0; const float invdivisor = 1.0f/divisor; const float3 d = ray_P - v0; const float u = dot(d, s1)*invdivisor; if(u < 0.0f) return 0; const float3 s2 = cross(d, e1); const float v = dot(ray_D, s2)*invdivisor; if(v < 0.0f) return 0; const float b0 = 1.0f - u - v; if(b0 < 0.0f) return 0; const float t = dot(e2, s2)*invdivisor; if(t < 0.0f || t > ray_t) return 0; *isect_t = t; *isect_P = ray_P + ray_D*t; return 1; } bool ray_triangle_intersect_uv( float3 ray_P, float3 ray_D, float ray_t, float3 v0, float3 v1, float3 v2, float *isect_u, float *isect_v, float *isect_t) { float3 e1 = v1 - v0; float3 e2 = v2 - v0; float3 s1 = cross(ray_D, e2); const float divisor = dot(s1, e1); if((divisor == 0.0f)) return 0; const float invdivisor = 1.0f/divisor; const float3 d = ray_P - v0; const float u = dot(d, s1)*invdivisor; if(u < 0.0f) return 0; const float3 s2 = cross(d, e1); const float v = dot(ray_D, s2)*invdivisor; if(v < 0.0f) return 0; const float b0 = 1.0f - u - v; if(b0 < 0.0f) return 0; const float t = dot(e2, s2)*invdivisor; if(t < 0.0f || t > ray_t) return 0; *isect_u = u; *isect_v = v; *isect_t = t; return 1; } bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, float3 quad_P, float3 quad_u, float3 quad_v, float3 *isect_P, float *isect_t) { float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f; float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f; if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t)) return 1; else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t)) return 1; return 0; } float2 map_to_tube(const float3 co) { float len, u, v; len = native_sqrt(((float)(co . x * co . x + co . y * co . y))); if(len > 0.0f) { u = (1.0f - (atan2(((float)(co . x / len)), ((float)(co . y / len))) / 3.14159274101257f)) * 0.5f; v = (co.z + 1.0f) * 0.5f; } else { u = v = 0.0f; } return ((float2)(u, v)); } float2 map_to_sphere(const float3 co) { float l = len(co); float u, v; if(l > 0.0f) { if((co . x == 0.0f && co . y == 0.0f)) { u = 0.0f; } else { u = (1.0f - atan2(((float)(co . x)), ((float)(co . y))) / 3.14159274101257f) / 2.0f; } v = 1.0f - safe_acosf(co.z / l) / 3.14159274101257f; } else { u = v = 0.0f; } return ((float2)(u, v)); } int util_max_axis(float3 vec) { if(vec.x > vec.y) { if(vec.x > vec.z) return 0; else return 2; } else { if(vec.y > vec.z) return 1; else return 2; } } #line 4017 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uchar float_to_byte(float val) { return ((val <= 0.0f) ? 0 : ((val > (1.0f - 0.5f / 255.0f)) ? 255 : (uchar)((255.0f * val) + 0.5f))); } uchar4 color_float_to_byte(float3 c) { uchar r, g, b; r = float_to_byte(c.x); g = float_to_byte(c.y); b = float_to_byte(c.z); return ((uchar4)(r, g, b, 0)); } float3 color_byte_to_float(uchar4 c) { return ((float3)(c . x*(1.0f/255.0f), c . y*(1.0f/255.0f), c . z*(1.0f/255.0f))); } float color_srgb_to_scene_linear(float c) { if(c < 0.04045f) return (c < 0.0f)? 0.0f: c * (1.0f/12.92f); else return pow(((float)((c + 0.055f) * (1.0f / 1.055f))), ((float)(2.4f))); } float color_scene_linear_to_srgb(float c) { if(c < 0.0031308f) return (c < 0.0f)? 0.0f: c * 12.92f; else return 1.055f * pow(((float)(c)), ((float)(1.0f / 2.4f))) - 0.055f; } float3 rgb_to_hsv(float3 rgb) { float cmax, cmin, h, s, v, cdelta; float3 c; cmax = fmax(((float)(rgb . x)), ((float)(fmax(((float)(rgb . y)), ((float)(rgb . z)))))); cmin = min(rgb.x, min(rgb.y, rgb.z)); cdelta = cmax - cmin; v = cmax; if(cmax != 0.0f) { s = cdelta/cmax; } else { s = 0.0f; h = 0.0f; } if(s != 0.0f) { float3 cmax3 = ((float3)(cmax, cmax, cmax)); c = (cmax3 - rgb)/cdelta; if (rgb.x == cmax) h = c.z - c.y; else if(rgb.y == cmax) h = 2.0f + c.x - c.z; else h = 4.0f + c.y - c.x; h /= 6.0f; if(h < 0.0f) h += 1.0f; } else { h = 0.0f; } return ((float3)(h, s, v)); } float3 hsv_to_rgb(float3 hsv) { float i, f, p, q, t, h, s, v; float3 rgb; h = hsv.x; s = hsv.y; v = hsv.z; if(s != 0.0f) { if(h == 1.0f) h = 0.0f; h *= 6.0f; i = floor(((float)(h))); f = h - i; rgb = ((float3)(f, f, f)); p = v*(1.0f-s); q = v*(1.0f-(s*f)); t = v*(1.0f-(s*(1.0f-f))); if (i == 0.0f) rgb = ((float3)(v, t, p)); else if(i == 1.0f) rgb = ((float3)(q, v, p)); else if(i == 2.0f) rgb = ((float3)(p, v, t)); else if(i == 3.0f) rgb = ((float3)(p, q, v)); else if(i == 4.0f) rgb = ((float3)(t, p, v)); else rgb = ((float3)(v, p, q)); } else { rgb = ((float3)(v, v, v)); } return rgb; } float3 xyY_to_xyz(float x, float y, float Y) { float X, Z; if(y != 0.0f) X = (x / y) * Y; else X = 0.0f; if(y != 0.0f && Y != 0.0f) Z = (1.0f - x - y) / y * Y; else Z = 0.0f; return ((float3)(X, Y, Z)); } float3 xyz_to_rgb(float x, float y, float z) { return ((float3)(3.240479f * x + -1.537150f * y + -0.498535f * z, -0.969256f * x + 1.875991f * y + 0.041556f * z, 0.055648f * x + -0.204043f * y + 1.057311f * z)); } #line 4234 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float linear_rgb_to_gray(float3 c) { return c.x*0.2126f + c.y*0.7152f + c.z*0.0722f; } #line 6307 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float madd(const float a, const float b, const float c) { return a * b + c; } int fast_rint(float x) { return float_to_int(x + copysign(((float)(0.5f)), ((float)(x)))); } float fast_sinf(float x) { int q = fast_rint(x * 0.31830987334251f); float qf = q; x = madd(qf, -0.78515625f*4, x); x = madd(qf, -0.00024187564849853515625f*4, x); x = madd(qf, -3.7747668102383613586e-08f*4, x); x = madd(qf, -1.2816720341285448015e-12f*4, x); x = 1.57079637050629f - (1.57079637050629f - x); float s = x * x; if((q & 1) != 0) x = -x; float u = 2.6083159809786593541503e-06f; u = madd(u, s, -0.0001981069071916863322258f); u = madd(u, s, +0.00833307858556509017944336f); u = madd(u, s, -0.166666597127914428710938f); u = madd(s, u * x, x); if(fabs(((float)(u))) > 1.0f) { u = 0.0f; } return u; } float fast_cosf(float x) { int q = fast_rint(x * 0.31830987334251f); float qf = q; x = madd(qf, -0.78515625f*4, x); x = madd(qf, -0.00024187564849853515625f*4, x); x = madd(qf, -3.7747668102383613586e-08f*4, x); x = madd(qf, -1.2816720341285448015e-12f*4, x); x = 1.57079637050629f - (1.57079637050629f - x); float s = x * x; float u = -2.71811842367242206819355e-07f; u = madd(u, s, +2.47990446951007470488548e-05f); u = madd(u, s, -0.00138888787478208541870117f); u = madd(u, s, +0.0416666641831398010253906f); u = madd(u, s, -0.5f); u = madd(u, s, +1.0f); if((q & 1) != 0) { u = -u; } if(fabs(((float)(u))) > 1.0f) { u = 0.0f; } return u; } void fast_sincosf(float x, float* sine, float* cosine) { int q = fast_rint(x * 0.31830987334251f); float qf = q; x = madd(qf, -0.78515625f*4, x); x = madd(qf, -0.00024187564849853515625f*4, x); x = madd(qf, -3.7747668102383613586e-08f*4, x); x = madd(qf, -1.2816720341285448015e-12f*4, x); x = 1.57079637050629f - (1.57079637050629f - x); float s = x * x; if((q & 1) != 0) { x = -x; } float su = 2.6083159809786593541503e-06f; su = madd(su, s, -0.0001981069071916863322258f); su = madd(su, s, +0.00833307858556509017944336f); su = madd(su, s, -0.166666597127914428710938f); su = madd(s, su * x, x); float cu = -2.71811842367242206819355e-07f; cu = madd(cu, s, +2.47990446951007470488548e-05f); cu = madd(cu, s, -0.00138888787478208541870117f); cu = madd(cu, s, +0.0416666641831398010253906f); cu = madd(cu, s, -0.5f); cu = madd(cu, s, +1.0f); if((q & 1) != 0) { cu = -cu; } if(fabs(((float)(su))) > 1.0f) { su = 0.0f; } if(fabs(((float)(cu))) > 1.0f) { cu = 0.0f; } *sine = su; *cosine = cu; } float fast_tanf(float x) { int q = fast_rint(x * 2.0f * 0.31830987334251f); float qf = q; x = madd(qf, -0.78515625f*2, x); x = madd(qf, -0.00024187564849853515625f*2, x); x = madd(qf, -3.7747668102383613586e-08f*2, x); x = madd(qf, -1.2816720341285448015e-12f*2, x); if((q & 1) == 0) { x = 0.78539818525314f - (0.78539818525314f - x); } float s = x * x; float u = 0.00927245803177356719970703f; u = madd(u, s, 0.00331984995864331722259521f); u = madd(u, s, 0.0242998078465461730957031f); u = madd(u, s, 0.0534495301544666290283203f); u = madd(u, s, 0.133383005857467651367188f); u = madd(u, s, 0.333331853151321411132812f); u = madd(s, u * x, x); if((q & 1) != 0) { u = -1.0f / u; } return u; } float fast_sinpif(float x) { const float z = x - ((x + 25165824.0f) - 25165824.0f); const float y = z - z * fabs(((float)(z))); const float Q = 3.10396624f; const float P = 3.584135056f; return y * (Q + P * fabs(((float)(y)))); } float fast_cospif(float x) { return fast_sinpif(x+0.5f); } float fast_acosf(float x) { const float f = fabs(((float)(x))); const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f; const float a = native_sqrt(((float)(1.0f - m))) * (1.5707963267f + m * (-0.213300989f + m * (0.077980478f + m * -0.02164095f))); return x < 0 ? 3.14159274101257f - a : a; } float fast_asinf(float x) { const float f = fabs(((float)(x))); const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f; const float a = 1.57079637050629f - native_sqrt(((float)(1.0f - m))) * (1.5707963267f + m * (-0.213300989f + m * (0.077980478f + m * -0.02164095f))); return copysign(((float)(a)), ((float)(x))); } float fast_atanf(float x) { const float a = fabs(((float)(x))); const float k = a > 1.0f ? 1 / a : a; const float s = 1.0f - (1.0f - k); const float t = s * s; float r = s * madd(0.43157974f, t, 1.0f) / madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f); if(a > 1.0f) { r = 1.570796326794896557998982f - r; } return copysign(((float)(r)), ((float)(x))); } float fast_atan2f(float y, float x) { const float a = fabs(((float)(x))); const float b = fabs(((float)(y))); const float k = (b == 0) ? 0.0f : ((a == b) ? 1.0f : (b > a ? a / b : b / a)); const float s = 1.0f - (1.0f - k); const float t = s * s; float r = s * madd(0.43157974f, t, 1.0f) / madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f); if(b > a) { r = 1.570796326794896557998982f - r; } if(as_uint(x) & 0x80000000u) { r = 3.14159274101257f - r; } return copysign(((float)(r)), ((float)(y))); } float fast_log2f(float x) { x = clamp(x, 0x1.0p-126f, 0x1.fffffep127f); unsigned bits = as_uint(x); int exponent = (int)(bits >> 23) - 127; float f = as_float((bits & 0x007FFFFF) | 0x3f800000) - 1.0f; float f2 = f * f; float f4 = f2 * f2; float hi = madd(f, -0.00931049621349f, 0.05206469089414f); float lo = madd(f, 0.47868480909345f, -0.72116591947498f); hi = madd(f, hi, -0.13753123777116f); hi = madd(f, hi, 0.24187369696082f); hi = madd(f, hi, -0.34730547155299f); lo = madd(f, lo, 1.442689881667200f); return ((f4 * hi) + (f * lo)) + exponent; } float fast_logf(float x) { return fast_log2f(x) * 0.69314718246460f; } float fast_log10(float x) { return fast_log2f(x) * 0.69314718246460f / 2.30258512496948f; } float fast_logb(float x) { x = fabs(((float)(x))); x = clamp(x, 0x1.0p-126f, 0x1.fffffep127f); unsigned bits = as_uint(x); return (int)(bits >> 23) - 127; } float fast_exp2f(float x) { x = clamp(x, -126.0f, 126.0f); int m = (int)x; x -= m; x = 1.0f - (1.0f - x); float r = 1.33336498402e-3f; r = madd(x, r, 9.810352697968e-3f); r = madd(x, r, 5.551834031939e-2f); r = madd(x, r, 0.2401793301105f); r = madd(x, r, 0.693144857883f); r = madd(x, r, 1.0f); return as_float(as_uint(r) + ((unsigned)m << 23)); } float fast_expf(float x) { return fast_exp2f(x / 0.69314718246460f); } float fast_exp10(float x) { return fast_exp2f(x * 2.30258512496948f / 0.69314718246460f); } float fast_expm1f(float x) { if(fabs(((float)(x))) < 1e-5f) { x = 1.0f - (1.0f - x); return madd(0.5f, x * x, x); } else { return fast_expf(x) - 1.0f; } } float fast_sinhf(float x) { float a = fabs(((float)(x))); if(a > 1.0f) { float e = fast_expf(a); return copysign(((float)(0.5f * e - 0.5f / e)), ((float)(x))); } else { a = 1.0f - (1.0f - a); float a2 = a * a; float r = 2.03945513931e-4f; r = madd(r, a2, 8.32990277558e-3f); r = madd(r, a2, 0.1666673421859f); r = madd(r * a, a2, a); return copysign(((float)(r)), ((float)(x))); } } float fast_coshf(float x) { float e = fast_expf(fabs(((float)(x)))); return 0.5f * e + 0.5f / e; } float fast_tanhf(float x) { float e = fast_expf(2.0f * fabs(((float)(x)))); return copysign(((float)(1.0f - 2.0f / (1.0f + e))), ((float)(x))); } float fast_safe_powf(float x, float y) { if(y == 0) return 1.0f; if(x == 0) return 0.0f; float sign = 1.0f; if(x < 0.0f) { int ybits = as_int(y) & 0x7fffffff; if(ybits >= 0x4b800000) { } else if(ybits >= 0x3f800000) { int k = (ybits >> 23) - 127; int j = ybits >> (23 - k); if((j << (23 - k)) == ybits) { sign = as_float(0x3f800000 | (j << 31)); } else { return 0.0f; } } else { return 0.0f; } } return sign * fast_exp2f(y * fast_log2f(fabs(((float)(x))))); } float fast_erff(float x) { const float a1 = 0.0705230784f; const float a2 = 0.0422820123f; const float a3 = 0.0092705272f; const float a4 = 0.0001520143f; const float a5 = 0.0002765672f; const float a6 = 0.0000430638f; const float a = fabs(((float)(x))); const float b = 1.0f - (1.0f - a); const float r = madd(madd(madd(madd(madd(madd(a6, b, a5), b, a4), b, a3), b, a2), b, a1), b, 1.0f); const float s = r * r; const float t = s * s; const float u = t * t; const float v = u * u; return copysign(((float)(1.0f - 1.0f / v)), ((float)(x))); } float fast_erfcf(float x) { return 1.0f - fast_erff(x); } float fast_ierff(float x) { float a = fabs(((float)(x))); if(a > 0.99999994f) { a = 0.99999994f; } float w = -fast_logf((1.0f - a) * (1.0f + a)), p; if(w < 5.0f) { w = w - 2.5f; p = 2.81022636e-08f; p = madd(p, w, 3.43273939e-07f); p = madd(p, w, -3.5233877e-06f); p = madd(p, w, -4.39150654e-06f); p = madd(p, w, 0.00021858087f); p = madd(p, w, -0.00125372503f); p = madd(p, w, -0.00417768164f); p = madd(p, w, 0.246640727f); p = madd(p, w, 1.50140941f); } else { w = native_sqrt(((float)(w))) - 3.0f; p = -0.000200214257f; p = madd(p, w, 0.000100950558f); p = madd(p, w, 0.00134934322f); p = madd(p, w, -0.00367342844f); p = madd(p, w, 0.00573950773f); p = madd(p, w, -0.0076224613f); p = madd(p, w, 0.00943887047f); p = madd(p, w, 1.00167406f); p = madd(p, w, 2.83297682f); } return p * x; } #line 9009 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 9551 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef struct Transform { float4 x, y, z, w; } Transform; typedef struct MotionTransform { Transform pre; Transform mid; Transform post; } MotionTransform; typedef struct DecompMotionTransform { Transform mid; float4 pre_x, pre_y; float4 post_x, post_y; } DecompMotionTransform; typedef struct PerspectiveMotionTransform { Transform pre; Transform post; } PerspectiveMotionTransform; float3 transform_perspective(const Transform *t, const float3 a) { float4 b = ((float4)(a . x, a . y, a . z, 1.0f)); float3 c = ((float3)(dot(t->x, b), dot(t->y, b), dot(t->z, b))); float w = dot(t->w, b); return (w != 0.0f)? c/w: ((float3)(0.0f, 0.0f, 0.0f)); } float3 transform_point(const Transform *t, const float3 a) { float3 c = ((float3)(a . x*t->x . x + a . y*t->x . y + a . z*t->x . z + t->x . w, a . x*t->y . x + a . y*t->y . y + a . z*t->y . z + t->y . w, a . x*t->z . x + a . y*t->z . y + a . z*t->z . z + t->z . w)); return c; } float3 transform_direction(const Transform *t, const float3 a) { float3 c = ((float3)(a . x*t->x . x + a . y*t->x . y + a . z*t->x . z, a . x*t->y . x + a . y*t->y . y + a . z*t->y . z, a . x*t->z . x + a . y*t->z . y + a . z*t->z . z)); return c; } float3 transform_direction_transposed(const Transform *t, const float3 a) { float3 x = ((float3)(t->x . x, t->y . x, t->z . x)); float3 y = ((float3)(t->x . y, t->y . y, t->z . y)); float3 z = ((float3)(t->x . z, t->y . z, t->z . z)); return ((float3)(dot(x, a), dot(y, a), dot(z, a))); } Transform transform_transpose(const Transform a) { Transform t; t.x.x = a.x.x; t.x.y = a.y.x; t.x.z = a.z.x; t.x.w = a.w.x; t.y.x = a.x.y; t.y.y = a.y.y; t.y.z = a.z.y; t.y.w = a.w.y; t.z.x = a.x.z; t.z.y = a.y.z; t.z.z = a.z.z; t.z.w = a.w.z; t.w.x = a.x.w; t.w.y = a.y.w; t.w.z = a.z.w; t.w.w = a.w.w; return t; } Transform make_transform(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p) { Transform t; t.x.x = a; t.x.y = b; t.x.z = c; t.x.w = d; t.y.x = e; t.y.y = f; t.y.z = g; t.y.w = h; t.z.x = i; t.z.y = j; t.z.z = k; t.z.w = l; t.w.x = m; t.w.y = n; t.w.z = o; t.w.w = p; return t; } #line 9842 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float4 quat_interpolate(float4 q1, float4 q2, float t) { return normalize((1.0f - t)*q1 + t*q2); #line 9869 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } Transform transform_quick_inverse(Transform M) { Transform R; float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); det = (det != 0.0f)? 1.0f/det: 0.0f; float3 Rx = det*((float3)(M . z . z*M . y . y - M . z . y*M . y . z, M . z . y*M . x . z - M . z . z*M . x . y, M . y . z*M . x . y - M . y . y*M . x . z)); float3 Ry = det*((float3)(M . z . x*M . y . z - M . z . z*M . y . x, M . z . z*M . x . x - M . z . x*M . x . z, M . y . x*M . x . z - M . y . z*M . x . x)); float3 Rz = det*((float3)(M . z . y*M . y . x - M . z . x*M . y . y, M . z . x*M . x . y - M . z . y*M . x . x, M . y . y*M . x . x - M . y . x*M . x . y)); float3 T = -((float3)(M . x . w, M . y . w, M . z . w)); R.x = ((float4)(Rx . x, Rx . y, Rx . z, dot(Rx, T))); R.y = ((float4)(Ry . x, Ry . y, Ry . z, dot(Ry, T))); R.z = ((float4)(Rz . x, Rz . y, Rz . z, dot(Rz, T))); R.w = ((float4)(0.0f, 0.0f, 0.0f, 1.0f)); return R; } void transform_compose(Transform *tfm, const Transform *decomp) { float q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; q0 = 1.41421353816986f * decomp->x.w; q1 = 1.41421353816986f * decomp->x.x; q2 = 1.41421353816986f * decomp->x.y; q3 = 1.41421353816986f * decomp->x.z; qda = q0*q1; qdb = q0*q2; qdc = q0*q3; qaa = q1*q1; qab = q1*q2; qac = q1*q3; qbb = q2*q2; qbc = q2*q3; qcc = q3*q3; float3 rotation_x = ((float3)(1.0f-qbb-qcc, -qdc+qab, qdb+qac)); float3 rotation_y = ((float3)(qdc+qab, 1.0f-qaa-qcc, -qda+qbc)); float3 rotation_z = ((float3)(-qdb+qac, qda+qbc, 1.0f-qaa-qbb)); float3 scale_x = ((float3)(decomp->y . w, decomp->z . z, decomp->w . y)); float3 scale_y = ((float3)(decomp->z . x, decomp->z . w, decomp->w . z)); float3 scale_z = ((float3)(decomp->z . y, decomp->w . x, decomp->w . w)); tfm->x = ((float4)(dot(rotation_x, scale_x), dot(rotation_x, scale_y), dot(rotation_x, scale_z), decomp->y . x)); tfm->y = ((float4)(dot(rotation_y, scale_x), dot(rotation_y, scale_y), dot(rotation_y, scale_z), decomp->y . y)); tfm->z = ((float4)(dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y . z)); tfm->w = ((float4)(0.0f, 0.0f, 0.0f, 1.0f)); } void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t) { Transform decomp; #line 9953 "C:\\cygwin64\\tmp\\OCL6424T10.cl" if(t < 0.5f) { t *= 2.0f; decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t); decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y; } else { t = (t - 0.5f)*2.0f; decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t); decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y; } decomp.z = motion->mid.z; decomp.w = motion->mid.w; transform_compose(tfm, &decomp); } #line 9997 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 10013 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 transform_point_addrspace( __global const Transform *t, const float3 a) { Transform private_tfm = *t; return transform_point(&private_tfm, a); } float3 transform_direction_addrspace( __global const Transform *t, const float3 a) { Transform private_tfm = *t; return transform_direction(&private_tfm, a); } float3 transform_direction_transposed_addrspace( __global const Transform *t, const float3 a) { Transform private_tfm = *t; return transform_direction_transposed(&private_tfm, a); } #line 10028 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 18723 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef enum NodeType { NODE_END = 0, NODE_CLOSURE_BSDF, NODE_CLOSURE_EMISSION, NODE_CLOSURE_BACKGROUND, NODE_CLOSURE_SET_WEIGHT, NODE_CLOSURE_WEIGHT, NODE_MIX_CLOSURE, NODE_JUMP_IF_ZERO, NODE_JUMP_IF_ONE, NODE_TEX_IMAGE, NODE_TEX_IMAGE_BOX, NODE_TEX_SKY, NODE_GEOMETRY, NODE_GEOMETRY_DUPLI, NODE_LIGHT_PATH, NODE_VALUE_F, NODE_VALUE_V, NODE_MIX, NODE_ATTR, NODE_CONVERT, NODE_FRESNEL, NODE_WIREFRAME, NODE_WAVELENGTH, NODE_BLACKBODY, NODE_EMISSION_WEIGHT, NODE_TEX_GRADIENT, NODE_TEX_VORONOI, NODE_TEX_MUSGRAVE, NODE_TEX_WAVE, NODE_TEX_MAGIC, NODE_TEX_NOISE, NODE_SHADER_JUMP, NODE_SET_DISPLACEMENT, NODE_GEOMETRY_BUMP_DX, NODE_GEOMETRY_BUMP_DY, NODE_SET_BUMP, NODE_MATH, NODE_VECTOR_MATH, NODE_VECTOR_TRANSFORM, NODE_MAPPING, NODE_TEX_COORD, NODE_TEX_COORD_BUMP_DX, NODE_TEX_COORD_BUMP_DY, NODE_ATTR_BUMP_DX, NODE_ATTR_BUMP_DY, NODE_TEX_ENVIRONMENT, NODE_CLOSURE_HOLDOUT, NODE_LAYER_WEIGHT, NODE_CLOSURE_VOLUME, NODE_SEPARATE_VECTOR, NODE_COMBINE_VECTOR, NODE_SEPARATE_HSV, NODE_COMBINE_HSV, NODE_HSV, NODE_CAMERA, NODE_INVERT, NODE_NORMAL, NODE_GAMMA, NODE_TEX_CHECKER, NODE_BRIGHTCONTRAST, NODE_RGB_RAMP, NODE_RGB_CURVES, NODE_VECTOR_CURVES, NODE_MIN_MAX, NODE_LIGHT_FALLOFF, NODE_OBJECT_INFO, NODE_PARTICLE_INFO, NODE_TEX_BRICK, NODE_CLOSURE_SET_NORMAL, NODE_CLOSURE_AMBIENT_OCCLUSION, NODE_TANGENT, NODE_NORMAL_MAP, NODE_HAIR_INFO, NODE_UVMAP, NODE_TEX_VOXEL, } NodeType; typedef enum NodeAttributeType { NODE_ATTR_FLOAT = 0, NODE_ATTR_FLOAT3, NODE_ATTR_MATRIX } NodeAttributeType; typedef enum NodeGeometry { NODE_GEOM_P = 0, NODE_GEOM_N, NODE_GEOM_T, NODE_GEOM_I, NODE_GEOM_Ng, NODE_GEOM_uv } NodeGeometry; typedef enum NodeObjectInfo { NODE_INFO_OB_LOCATION, NODE_INFO_OB_INDEX, NODE_INFO_MAT_INDEX, NODE_INFO_OB_RANDOM } NodeObjectInfo; typedef enum NodeParticleInfo { NODE_INFO_PAR_INDEX, NODE_INFO_PAR_AGE, NODE_INFO_PAR_LIFETIME, NODE_INFO_PAR_LOCATION, NODE_INFO_PAR_ROTATION, NODE_INFO_PAR_SIZE, NODE_INFO_PAR_VELOCITY, NODE_INFO_PAR_ANGULAR_VELOCITY } NodeParticleInfo; typedef enum NodeHairInfo { NODE_INFO_CURVE_IS_STRAND, NODE_INFO_CURVE_INTERCEPT, NODE_INFO_CURVE_THICKNESS, NODE_INFO_CURVE_TANGENT_NORMAL } NodeHairInfo; typedef enum NodeLightPath { NODE_LP_camera = 0, NODE_LP_shadow, NODE_LP_diffuse, NODE_LP_glossy, NODE_LP_singular, NODE_LP_reflection, NODE_LP_transmission, NODE_LP_volume_scatter, NODE_LP_backfacing, NODE_LP_ray_length, NODE_LP_ray_depth, NODE_LP_ray_transparent } NodeLightPath; typedef enum NodeLightFalloff { NODE_LIGHT_FALLOFF_QUADRATIC, NODE_LIGHT_FALLOFF_LINEAR, NODE_LIGHT_FALLOFF_CONSTANT } NodeLightFalloff; typedef enum NodeTexCoord { NODE_TEXCO_NORMAL, NODE_TEXCO_OBJECT, NODE_TEXCO_CAMERA, NODE_TEXCO_WINDOW, NODE_TEXCO_REFLECTION, NODE_TEXCO_DUPLI_GENERATED, NODE_TEXCO_DUPLI_UV, NODE_TEXCO_VOLUME_GENERATED } NodeTexCoord; typedef enum NodeMix { NODE_MIX_BLEND = 0, NODE_MIX_ADD, NODE_MIX_MUL, NODE_MIX_SUB, NODE_MIX_SCREEN, NODE_MIX_DIV, NODE_MIX_DIFF, NODE_MIX_DARK, NODE_MIX_LIGHT, NODE_MIX_OVERLAY, NODE_MIX_DODGE, NODE_MIX_BURN, NODE_MIX_HUE, NODE_MIX_SAT, NODE_MIX_VAL, NODE_MIX_COLOR, NODE_MIX_SOFT, NODE_MIX_LINEAR, NODE_MIX_CLAMP } NodeMix; typedef enum NodeMath { NODE_MATH_ADD, NODE_MATH_SUBTRACT, NODE_MATH_MULTIPLY, NODE_MATH_DIVIDE, NODE_MATH_SINE, NODE_MATH_COSINE, NODE_MATH_TANGENT, NODE_MATH_ARCSINE, NODE_MATH_ARCCOSINE, NODE_MATH_ARCTANGENT, NODE_MATH_POWER, NODE_MATH_LOGARITHM, NODE_MATH_MINIMUM, NODE_MATH_MAXIMUM, NODE_MATH_ROUND, NODE_MATH_LESS_THAN, NODE_MATH_GREATER_THAN, NODE_MATH_MODULO, NODE_MATH_ABSOLUTE, NODE_MATH_CLAMP } NodeMath; typedef enum NodeVectorMath { NODE_VECTOR_MATH_ADD, NODE_VECTOR_MATH_SUBTRACT, NODE_VECTOR_MATH_AVERAGE, NODE_VECTOR_MATH_DOT_PRODUCT, NODE_VECTOR_MATH_CROSS_PRODUCT, NODE_VECTOR_MATH_NORMALIZE } NodeVectorMath; typedef enum NodeVectorTransformType { NODE_VECTOR_TRANSFORM_TYPE_VECTOR, NODE_VECTOR_TRANSFORM_TYPE_POINT, NODE_VECTOR_TRANSFORM_TYPE_NORMAL } NodeVectorTransformType; typedef enum NodeVectorTransformConvertSpace { NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA } NodeVectorTransformConvertSpace; typedef enum NodeConvert { NODE_CONVERT_FV, NODE_CONVERT_FI, NODE_CONVERT_CF, NODE_CONVERT_CI, NODE_CONVERT_VF, NODE_CONVERT_VI, NODE_CONVERT_IF, NODE_CONVERT_IV } NodeConvert; typedef enum NodeMusgraveType { NODE_MUSGRAVE_MULTIFRACTAL, NODE_MUSGRAVE_FBM, NODE_MUSGRAVE_HYBRID_MULTIFRACTAL, NODE_MUSGRAVE_RIDGED_MULTIFRACTAL, NODE_MUSGRAVE_HETERO_TERRAIN } NodeMusgraveType; typedef enum NodeWaveType { NODE_WAVE_BANDS, NODE_WAVE_RINGS } NodeWaveType; typedef enum NodeSkyType { NODE_SKY_OLD, NODE_SKY_NEW } NodeSkyType; typedef enum NodeGradientType { NODE_BLEND_LINEAR, NODE_BLEND_QUADRATIC, NODE_BLEND_EASING, NODE_BLEND_DIAGONAL, NODE_BLEND_RADIAL, NODE_BLEND_QUADRATIC_SPHERE, NODE_BLEND_SPHERICAL } NodeGradientType; typedef enum NodeVoronoiColoring { NODE_VORONOI_INTENSITY, NODE_VORONOI_CELLS } NodeVoronoiColoring; typedef enum NodeBlendWeightType { NODE_LAYER_WEIGHT_FRESNEL, NODE_LAYER_WEIGHT_FACING } NodeBlendWeightType; typedef enum NodeTangentDirectionType { NODE_TANGENT_RADIAL, NODE_TANGENT_UVMAP } NodeTangentDirectionType; typedef enum NodeTangentAxis { NODE_TANGENT_AXIS_X, NODE_TANGENT_AXIS_Y, NODE_TANGENT_AXIS_Z } NodeTangentAxis; typedef enum NodeNormalMapSpace { NODE_NORMAL_MAP_TANGENT, NODE_NORMAL_MAP_OBJECT, NODE_NORMAL_MAP_WORLD, NODE_NORMAL_MAP_BLENDER_OBJECT, NODE_NORMAL_MAP_BLENDER_WORLD, } NodeNormalMapSpace; typedef enum NodeImageProjection { NODE_IMAGE_PROJ_FLAT = 0, NODE_IMAGE_PROJ_BOX = 1, NODE_IMAGE_PROJ_SPHERE = 2, NODE_IMAGE_PROJ_TUBE = 3, } NodeImageProjection; typedef enum NodeBumpOffset { NODE_BUMP_OFFSET_CENTER, NODE_BUMP_OFFSET_DX, NODE_BUMP_OFFSET_DY, } NodeBumpOffset; typedef enum NodeTexVoxelSpace { NODE_TEX_VOXEL_SPACE_OBJECT = 0, NODE_TEX_VOXEL_SPACE_WORLD = 1, } NodeTexVoxelSpace; typedef enum ShaderType { SHADER_TYPE_SURFACE, SHADER_TYPE_VOLUME, SHADER_TYPE_DISPLACEMENT } ShaderType; typedef enum ClosureType { CLOSURE_BSDF_ID, CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, CLOSURE_BSDF_DIFFUSE_RAMP_ID, CLOSURE_BSDF_DIFFUSE_TOON_ID, CLOSURE_BSDF_GLOSSY_ID, CLOSURE_BSDF_REFLECTION_ID, CLOSURE_BSDF_MICROFACET_GGX_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ID, CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID, CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID, CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID, CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_PHONG_RAMP_ID, CLOSURE_BSDF_GLOSSY_TOON_ID, CLOSURE_BSDF_HAIR_REFLECTION_ID, CLOSURE_BSDF_TRANSMISSION_ID, CLOSURE_BSDF_TRANSLUCENT_ID, CLOSURE_BSDF_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, CLOSURE_BSDF_SHARP_GLASS_ID, CLOSURE_BSDF_HAIR_TRANSMISSION_ID, CLOSURE_BSDF_BSSRDF_ID, CLOSURE_BSDF_TRANSPARENT_ID, CLOSURE_BSSRDF_CUBIC_ID, CLOSURE_BSSRDF_GAUSSIAN_ID, CLOSURE_EMISSION_ID, CLOSURE_BACKGROUND_ID, CLOSURE_HOLDOUT_ID, CLOSURE_AMBIENT_OCCLUSION_ID, CLOSURE_VOLUME_ID, CLOSURE_VOLUME_ABSORPTION_ID, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, NBUILTIN_CLOSURES } ClosureType; #line 19164 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19195 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19229 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19244 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19256 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19268 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19284 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19293 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19308 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19316 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19328 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 19343 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef uint RNG; typedef enum ShaderEvalType { SHADER_EVAL_DISPLACE, SHADER_EVAL_BACKGROUND, SHADER_EVAL_BAKE, SHADER_EVAL_NORMAL, SHADER_EVAL_UV, SHADER_EVAL_DIFFUSE_COLOR, SHADER_EVAL_GLOSSY_COLOR, SHADER_EVAL_TRANSMISSION_COLOR, SHADER_EVAL_SUBSURFACE_COLOR, SHADER_EVAL_EMISSION, SHADER_EVAL_AO, SHADER_EVAL_COMBINED, SHADER_EVAL_SHADOW, SHADER_EVAL_DIFFUSE_DIRECT, SHADER_EVAL_GLOSSY_DIRECT, SHADER_EVAL_TRANSMISSION_DIRECT, SHADER_EVAL_SUBSURFACE_DIRECT, SHADER_EVAL_DIFFUSE_INDIRECT, SHADER_EVAL_GLOSSY_INDIRECT, SHADER_EVAL_TRANSMISSION_INDIRECT, SHADER_EVAL_SUBSURFACE_INDIRECT, SHADER_EVAL_ENVIRONMENT, } ShaderEvalType; enum PathTraceDimension { PRNG_FILTER_U = 0, PRNG_FILTER_V = 1, PRNG_LENS_U = 2, PRNG_LENS_V = 3, #line 19397 "C:\\cygwin64\\tmp\\OCL6424T10.cl" PRNG_BASE_NUM = 8, PRNG_BSDF_U = 0, PRNG_BSDF_V = 1, PRNG_BSDF = 2, PRNG_LIGHT = 3, PRNG_LIGHT_U = 4, PRNG_LIGHT_V = 5, PRNG_UNUSED_3 = 6, PRNG_TERMINATE = 7, #line 19414 "C:\\cygwin64\\tmp\\OCL6424T10.cl" PRNG_BOUNCE_NUM = 12, }; enum SamplingPattern { SAMPLING_PATTERN_SOBOL = 0, SAMPLING_PATTERN_CMJ = 1 }; enum PathRayFlag { PATH_RAY_CAMERA = 1, PATH_RAY_REFLECT = 2, PATH_RAY_TRANSMIT = 4, PATH_RAY_DIFFUSE = 8, PATH_RAY_GLOSSY = 16, PATH_RAY_SINGULAR = 32, PATH_RAY_TRANSPARENT = 64, PATH_RAY_SHADOW_OPAQUE = 128, PATH_RAY_SHADOW_TRANSPARENT = 256, PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT), PATH_RAY_CURVE = 512, PATH_RAY_VOLUME_SCATTER = 1024, PATH_RAY_ALL_VISIBILITY = (1|2|4|8|16|32|64|128|256|512|1024), PATH_RAY_MIS_SKIP = 2048, PATH_RAY_DIFFUSE_ANCESTOR = 4096, PATH_RAY_SINGLE_PASS_DONE = 8192, PATH_RAY_LAYER_SHIFT = (32-20) }; typedef enum ClosureLabel { LABEL_NONE = 0, LABEL_TRANSMIT = 1, LABEL_REFLECT = 2, LABEL_DIFFUSE = 4, LABEL_GLOSSY = 8, LABEL_SINGULAR = 16, LABEL_TRANSPARENT = 32, LABEL_VOLUME_SCATTER = 64, } ClosureLabel; typedef enum PassType { PASS_NONE = 0, PASS_COMBINED = (1 << 0), PASS_DEPTH = (1 << 1), PASS_NORMAL = (1 << 2), PASS_UV = (1 << 3), PASS_OBJECT_ID = (1 << 4), PASS_MATERIAL_ID = (1 << 5), PASS_DIFFUSE_COLOR = (1 << 6), PASS_GLOSSY_COLOR = (1 << 7), PASS_TRANSMISSION_COLOR = (1 << 8), PASS_DIFFUSE_INDIRECT = (1 << 9), PASS_GLOSSY_INDIRECT = (1 << 10), PASS_TRANSMISSION_INDIRECT = (1 << 11), PASS_DIFFUSE_DIRECT = (1 << 12), PASS_GLOSSY_DIRECT = (1 << 13), PASS_TRANSMISSION_DIRECT = (1 << 14), PASS_EMISSION = (1 << 15), PASS_BACKGROUND = (1 << 16), PASS_AO = (1 << 17), PASS_SHADOW = (1 << 18), PASS_MOTION = (1 << 19), PASS_MOTION_WEIGHT = (1 << 20), PASS_MIST = (1 << 21), PASS_SUBSURFACE_DIRECT = (1 << 22), PASS_SUBSURFACE_INDIRECT = (1 << 23), PASS_SUBSURFACE_COLOR = (1 << 24), PASS_LIGHT = (1 << 25), } PassType; typedef __global struct PathRadiance { int use_light_pass; float3 emission; float3 background; float3 ao; float3 indirect; float3 direct_throughput; float3 direct_emission; float3 color_diffuse; float3 color_glossy; float3 color_transmission; float3 color_subsurface; float3 color_scatter; float3 direct_diffuse; float3 direct_glossy; float3 direct_transmission; float3 direct_subsurface; float3 direct_scatter; float3 indirect_diffuse; float3 indirect_glossy; float3 indirect_transmission; float3 indirect_subsurface; float3 indirect_scatter; float3 path_diffuse; float3 path_glossy; float3 path_transmission; float3 path_subsurface; float3 path_scatter; float4 shadow; float mist; } PathRadiance; typedef struct BsdfEval { int use_light_pass; float3 diffuse; float3 glossy; float3 transmission; float3 transparent; float3 subsurface; float3 scatter; } BsdfEval; #line 19565 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef enum ShaderFlag { SHADER_SMOOTH_NORMAL = (1 << 31), SHADER_CAST_SHADOW = (1 << 30), SHADER_AREA_LIGHT = (1 << 29), SHADER_USE_MIS = (1 << 28), SHADER_EXCLUDE_DIFFUSE = (1 << 27), SHADER_EXCLUDE_GLOSSY = (1 << 26), SHADER_EXCLUDE_TRANSMIT = (1 << 25), SHADER_EXCLUDE_CAMERA = (1 << 24), SHADER_EXCLUDE_SCATTER = (1 << 23), SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT|SHADER_EXCLUDE_CAMERA|SHADER_EXCLUDE_SCATTER), SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY) } ShaderFlag; typedef enum LightType { LIGHT_POINT, LIGHT_DISTANT, LIGHT_BACKGROUND, LIGHT_AREA, LIGHT_SPOT, LIGHT_TRIANGLE } LightType; enum CameraType { CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC, CAMERA_PANORAMA }; enum PanoramaType { PANORAMA_EQUIRECTANGULAR, PANORAMA_MIRRORBALL, PANORAMA_FISHEYE_EQUIDISTANT, PANORAMA_FISHEYE_EQUISOLID }; typedef struct differential3 { float3 dx; float3 dy; } differential3; typedef struct differential { float dx; float dy; } differential; typedef struct Ray { #line 19641 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float t; float time; float3 P; float3 D; differential3 dP; differential3 dD; } Ray; typedef __global struct Intersection { float t, u, v; int prim; int object; int type; } Intersection; typedef enum PrimitiveType { PRIMITIVE_NONE = 0, PRIMITIVE_TRIANGLE = 1, PRIMITIVE_MOTION_TRIANGLE = 2, PRIMITIVE_CURVE = 4, PRIMITIVE_MOTION_CURVE = 8, PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE), PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE), PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE), PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE), PRIMITIVE_NUM_TOTAL = 4, } PrimitiveType; typedef enum AttributeElement { ATTR_ELEMENT_NONE, ATTR_ELEMENT_OBJECT, ATTR_ELEMENT_MESH, ATTR_ELEMENT_FACE, ATTR_ELEMENT_VERTEX, ATTR_ELEMENT_VERTEX_MOTION, ATTR_ELEMENT_CORNER, ATTR_ELEMENT_CORNER_BYTE, ATTR_ELEMENT_CURVE, ATTR_ELEMENT_CURVE_KEY, ATTR_ELEMENT_CURVE_KEY_MOTION, ATTR_ELEMENT_VOXEL } AttributeElement; typedef enum AttributeStandard { ATTR_STD_NONE = 0, ATTR_STD_VERTEX_NORMAL, ATTR_STD_FACE_NORMAL, ATTR_STD_UV, ATTR_STD_UV_TANGENT, ATTR_STD_UV_TANGENT_SIGN, ATTR_STD_GENERATED, ATTR_STD_GENERATED_TRANSFORM, ATTR_STD_POSITION_UNDEFORMED, ATTR_STD_POSITION_UNDISPLACED, ATTR_STD_MOTION_VERTEX_POSITION, ATTR_STD_MOTION_VERTEX_NORMAL, ATTR_STD_PARTICLE, ATTR_STD_CURVE_INTERCEPT, ATTR_STD_PTEX_FACE_ID, ATTR_STD_PTEX_UV, ATTR_STD_VOLUME_DENSITY, ATTR_STD_VOLUME_COLOR, ATTR_STD_VOLUME_FLAME, ATTR_STD_VOLUME_HEAT, ATTR_STD_VOLUME_VELOCITY, ATTR_STD_POINTINESS, ATTR_STD_NUM, ATTR_STD_NOT_FOUND = ~0 } AttributeStandard; #line 19749 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef __global struct ShaderClosure { float3 weight; float3 N; float3 T; ClosureType type; float sample_weight; float data0; float data1; float data2; int pad1, pad2, pad3; } ShaderClosure; typedef enum ShaderContext { SHADER_CONTEXT_MAIN = 0, SHADER_CONTEXT_INDIRECT = 1, SHADER_CONTEXT_EMISSION = 2, SHADER_CONTEXT_SHADOW = 3, SHADER_CONTEXT_SSS = 4, SHADER_CONTEXT_VOLUME = 5, SHADER_CONTEXT_NUM = 6 } ShaderContext; enum ShaderDataFlag { SD_BACKFACING = (1 << 0), SD_EMISSION = (1 << 1), SD_BSDF = (1 << 2), SD_BSDF_HAS_EVAL = (1 << 3), SD_BSSRDF = (1 << 4), SD_HOLDOUT = (1 << 5), SD_ABSORPTION = (1 << 6), SD_SCATTER = (1 << 7), SD_AO = (1 << 8), SD_TRANSPARENT = (1 << 9), SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF| SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO), SD_USE_MIS = (1 << 10), SD_HAS_TRANSPARENT_SHADOW = (1 << 11), SD_HAS_VOLUME = (1 << 12), SD_HAS_ONLY_VOLUME = (1 << 13), SD_HETEROGENEOUS_VOLUME = (1 << 14), SD_HAS_BSSRDF_BUMP = (1 << 15), SD_VOLUME_EQUIANGULAR = (1 << 16), SD_VOLUME_MIS = (1 << 17), SD_VOLUME_CUBIC = (1 << 18), SD_HAS_BUMP = (1 << 19), SD_SHADER_FLAGS = (SD_USE_MIS|SD_HAS_TRANSPARENT_SHADOW|SD_HAS_VOLUME| SD_HAS_ONLY_VOLUME|SD_HETEROGENEOUS_VOLUME| SD_HAS_BSSRDF_BUMP|SD_VOLUME_EQUIANGULAR|SD_VOLUME_MIS| SD_VOLUME_CUBIC|SD_HAS_BUMP), SD_HOLDOUT_MASK = (1 << 20), SD_OBJECT_MOTION = (1 << 21), SD_TRANSFORM_APPLIED = (1 << 22), SD_NEGATIVE_SCALE_APPLIED = (1 << 23), SD_OBJECT_HAS_VOLUME = (1 << 24), SD_OBJECT_INTERSECTS_VOLUME = (1 << 25), SD_OBJECT_HAS_VERTEX_MOTION = (1 << 26), SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED| SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME| SD_OBJECT_INTERSECTS_VOLUME) }; struct KernelGlobals; #line 19852 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef __global struct ShaderData { #line 19878 "C:\\cygwin64\\tmp\\OCL6424T10.cl" __global float3 *P; __global float3 *N; __global float3 *Ng; __global float3 *I; __global int *shader; __global int *flag; __global int *prim; __global int *type; __global float *u; __global float *v; __global int *object; __global float *time; __global float *ray_length; __global int *ray_depth; __global int *transparent_depth; __global differential3 *dP; __global differential3 *dI; __global differential *du; __global differential *dv; __global float3 *dPdu; __global float3 *dPdv; #line 19939 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ShaderClosure *closure; __global int *num_closure; __global float *randb_closure; __global float3 *ray_P; __global differential3 *ray_dP; } ShaderData; #line 19968 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef struct PathState { int flag; int rng_offset; int sample; int num_samples; int bounce; int diffuse_bounce; int glossy_bounce; int transmission_bounce; int transparent_bounce; float min_ray_pdf; float ray_pdf; float ray_t; } PathState; typedef struct KernelCamera { int type; int panorama_type; float fisheye_fov; float fisheye_lens; float4 equirectangular_range; Transform cameratoworld; Transform rastertocamera; float4 dx; float4 dy; float aperturesize; float blades; float bladesrotation; float focaldistance; float shuttertime; int have_motion, have_perspective_motion; float nearclip; float cliplength; float sensorwidth; float sensorheight; float width, height; int resolution; float inv_aperture_ratio; int is_inside_volume; Transform screentoworld; Transform rastertoworld; Transform worldtoscreen; Transform worldtoraster; Transform worldtondc; Transform worldtocamera; MotionTransform motion; PerspectiveMotionTransform perspective_motion; } KernelCamera; typedef struct KernelFilm { float exposure; int pass_flag; int pass_stride; int use_light_pass; int pass_combined; int pass_depth; int pass_normal; int pass_motion; int pass_motion_weight; int pass_uv; int pass_object_id; int pass_material_id; int pass_diffuse_color; int pass_glossy_color; int pass_transmission_color; int pass_subsurface_color; int pass_diffuse_indirect; int pass_glossy_indirect; int pass_transmission_indirect; int pass_subsurface_indirect; int pass_diffuse_direct; int pass_glossy_direct; int pass_transmission_direct; int pass_subsurface_direct; int pass_emission; int pass_background; int pass_ao; float pass_alpha_threshold; int pass_shadow; float pass_shadow_scale; int filter_table_offset; int pass_pad2; int pass_mist; float mist_start; float mist_inv_depth; float mist_falloff; #line 20122 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } KernelFilm; typedef struct KernelBackground { int surface_shader; int volume_shader; int transparent; int pad; float ao_factor; float ao_distance; float ao_pad1, ao_pad2; } KernelBackground; typedef struct KernelIntegrator { int use_direct_light; int use_ambient_occlusion; int num_distribution; int num_all_lights; float pdf_triangles; float pdf_lights; float inv_pdf_lights; int pdf_background_res; float portal_pdf; int num_portals; int portal_offset; int min_bounce; int max_bounce; int max_diffuse_bounce; int max_glossy_bounce; int max_transmission_bounce; int max_volume_bounce; int transparent_min_bounce; int transparent_max_bounce; int transparent_shadows; int caustics_reflective; int caustics_refractive; float filter_glossy; int seed; int layer_flag; float sample_clamp_direct; float sample_clamp_indirect; int branched; int diffuse_samples; int glossy_samples; int transmission_samples; int ao_samples; int mesh_light_samples; int subsurface_samples; int sample_all_lights_direct; int sample_all_lights_indirect; int use_lamp_mis; int sampling_pattern; int aa_samples; int use_volumes; int volume_max_steps; float volume_step_size; int volume_samples; int pad; } KernelIntegrator; typedef struct KernelBVH { int root; int attributes_map_stride; int have_motion; int have_curves; int have_instancing; int use_qbvh; int pad1, pad2; } KernelBVH; typedef enum CurveFlag { CURVE_KN_BACKFACING = 1, CURVE_KN_ENCLOSEFILTER = 2, CURVE_KN_INTERPOLATE = 4, CURVE_KN_ACCURATE = 8, CURVE_KN_INTERSECTCORRECTION = 16, CURVE_KN_TRUETANGENTGNORMAL = 32, CURVE_KN_RIBBONS = 64, } CurveFlag; typedef struct KernelCurves { int curveflags; int subdivisions; float minimum_width; float maximum_width; } KernelCurves; typedef struct KernelTables { int beckmann_offset; int pad1, pad2, pad3; } KernelTables; typedef struct KernelData { KernelCamera cam; KernelFilm film; KernelBackground background; KernelIntegrator integrator; KernelBVH bvh; KernelCurves curve; KernelTables tables; } KernelData; #line 20263 "C:\\cygwin64\\tmp\\OCL6424T10.cl" enum QueueNumber { QUEUE_ACTIVE_AND_REGENERATED_RAYS = 0, QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS = 1, QUEUE_SHADOW_RAY_CAST_AO_RAYS = 2, QUEUE_SHADOW_RAY_CAST_DL_RAYS = 3, }; enum RayState { RAY_ACTIVE = 0, RAY_INACTIVE = 1, RAY_UPDATE_BUFFER = 2, RAY_HIT_BACKGROUND = 3, RAY_TO_REGENERATE = 4, RAY_REGENERATED = 5, RAY_SKIP_DL = 6, RAY_SHADOW_RAY_CAST_AO = 16, RAY_SHADOW_RAY_CAST_DL = 32 }; #line 20621 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 20882 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef __global struct KernelGlobals { __constant KernelData *data; __global float4 *__bvh_nodes; __global float4 *__bvh_leaf_nodes; __global float4 *__tri_woop; __global uint *__prim_type; __global uint *__prim_visibility; __global uint *__prim_index; __global uint *__prim_object; __global uint *__object_node; __global float4 *__objects; __global float4 *__objects_vector; __global uint *__tri_shader; __global float4 *__tri_vnormal; __global float4 *__tri_vindex; __global float4 *__tri_verts; __global float4 *__curves; __global float4 *__curve_keys; __global uint4 *__attributes_map; __global float *__attributes_float; __global float4 *__attributes_float3; __global uchar4 *__attributes_uchar4; __global float4 *__light_distribution; __global float4 *__light_data; __global float2 *__light_background_marginal_cdf; __global float2 *__light_background_conditional_cdf; __global float4 *__particles; __global uint4 *__svm_nodes; __global uint *__shader_flag; __global uint *__object_flag; __global float *__lookup_table; __global uint *__sobol_directions; __global uchar4 *__tex_image_packed; __global uint4 *__tex_image_packed_info; } KernelGlobals; float lookup_table_read(KernelGlobals *kg, float x, int offset, int size) { x = saturate(x)*(size-1); int index = min(float_to_int(x), size-1); int nindex = min(index+1, size-1); float t = x - index; float data0 = kg->__lookup_table[index + offset]; if(t == 0.0f) return data0; float data1 = kg->__lookup_table[nindex + offset]; return (1.0f - t)*data0 + t*data1; } float lookup_table_read_2D(KernelGlobals *kg, float x, float y, int offset, int xsize, int ysize) { y = saturate(y)*(ysize-1); int index = min(float_to_int(y), ysize-1); int nindex = min(index+1, ysize-1); float t = y - index; float data0 = lookup_table_read(kg, x, offset + xsize*index, xsize); if(t == 0.0f) return data0; float data1 = lookup_table_read(kg, x, offset + xsize*nindex, xsize); return (1.0f - t)*data0 + t*data1; } #line 21213 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void atomic_add_float(volatile __global float *source, const float operand) { union { unsigned int int_value; float float_value; } new_value; union { unsigned int int_value; float float_value; } prev_value; do { prev_value.float_value = *source; new_value.float_value = prev_value.float_value + operand; } while(atomic_cmpxchg((volatile __global unsigned int *)source, prev_value.int_value, new_value.int_value) != prev_value.int_value); } bool cmj_is_pow2(int i) { return (i & (i - 1)) == 0; } int cmj_fast_mod_pow2(int a, int b) { return (a & (b - 1)); } int cmj_fast_div_pow2(int a, int b) { ; ; #line 21316 "C:\\cygwin64\\tmp\\OCL6424T10.cl" return a/b; } uint cmj_w_mask(uint w) { ; #line 21334 "C:\\cygwin64\\tmp\\OCL6424T10.cl" w |= w >> 1; w |= w >> 2; w |= w >> 4; w |= w >> 8; w |= w >> 16; return w; } uint cmj_permute(uint i, uint l, uint p) { uint w = l - 1; if((l & w) == 0) { i ^= p; i *= 0xe170893d; i ^= p >> 16; i ^= (i & w) >> 4; i ^= p >> 8; i *= 0x0929eb3f; i ^= p >> 23; i ^= (i & w) >> 1; i *= 1 | p >> 27; i *= 0x6935fa69; i ^= (i & w) >> 11; i *= 0x74dcb303; i ^= (i & w) >> 2; i *= 0x9e501cc3; i ^= (i & w) >> 2; i *= 0xc860a3df; i &= w; i ^= i >> 5; return (i + p) & w; } else { w = cmj_w_mask(w); do { i ^= p; i *= 0xe170893d; i ^= p >> 16; i ^= (i & w) >> 4; i ^= p >> 8; i *= 0x0929eb3f; i ^= p >> 23; i ^= (i & w) >> 1; i *= 1 | p >> 27; i *= 0x6935fa69; i ^= (i & w) >> 11; i *= 0x74dcb303; i ^= (i & w) >> 2; i *= 0x9e501cc3; i ^= (i & w) >> 2; i *= 0xc860a3df; i &= w; i ^= i >> 5; } while(i >= l); return (i + p) % l; } } uint cmj_hash(uint i, uint p) { i ^= p; i ^= i >> 17; i ^= i >> 10; i *= 0xb36534e5; i ^= i >> 12; i ^= i >> 21; i *= 0x93fc4795; i ^= 0xdf6e307f; i ^= i >> 17; i *= 1 | p >> 18; return i; } float cmj_randfloat(uint i, uint p) { return cmj_hash(i, p) * (1.0f / 4294967808.0f); } #line 21471 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uint van_der_corput(uint bits) { bits = (bits << 16) | (bits >> 16); bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8); bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4); bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2); bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1); return bits; } uint sobol(uint i) { uint r = 0; for(uint v = 1U << 31; i; i >>= 1, v ^= v >> 1) if(i & 1) r ^= v; return r; } uint sobol_inverse(uint i) { const uint msb = 1U << 31; uint r = 0; for(uint v = 1; i; i <<= 1, v ^= v << 1) if(i & msb) r ^= v; return r; } uint sobol_dimension(KernelGlobals *kg, int index, int dimension) { uint result = 0; uint i = index; for(uint j = 0; i; i >>= 1, j++) if(i & 1) result ^= kg->__sobol_directions[32*dimension + j]; return result; } uint sobol_lookup(const uint m, const uint frame, const uint ex, const uint ey, uint *x, uint *y) { const uint shift = frame << (m << 1); const uint sobol_shift = sobol(shift); const uint lower = van_der_corput(ex << (32 - m)); const uint sobol_lower = sobol(lower); const uint mask = ~-(1 << m) << (32 - m); const uint delta = ((ey << (32 - m)) ^ sobol_lower ^ sobol_shift) & mask; const uint sobol_result = delta | (delta >> m); const uint upper = sobol_inverse(sobol_result); const uint index = shift | upper | lower; *x = van_der_corput(index); *y = sobol_shift ^ sobol_result ^ sobol_lower; return index; } float path_rng_1D(KernelGlobals *kg, __global RNG *rng, int sample, int num_samples, int dimension) { #line 21568 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uint result = sobol_dimension(kg, sample + 64, dimension); float r = (float)result * (1.0f/(float)0xFFFFFFFF); float shift; if(dimension & 1) shift = (*rng >> 16) * (1.0f/(float)0xFFFF); else shift = (*rng & 0xFFFF) * (1.0f/(float)0xFFFF); return r + shift - floor(((float)(r + shift))); } void path_rng_2D(KernelGlobals *kg, __global RNG *rng, int sample, int num_samples, int dimension, float *fx, float *fy) { #line 21603 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); } } void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, __global RNG *rng, int x, int y, float *fx, float *fy) { #line 21631 "C:\\cygwin64\\tmp\\OCL6424T10.cl" *rng = *rng_state; *rng ^= (*kg->data).integrator.seed; if(sample == 0) { *fx = 0.5f; *fy = 0.5f; } else { path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); } } void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng) { } #line 21690 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uint lcg_step_uint(uint *rng) { *rng = (1103515245*(*rng) + 12345); return *rng; } float lcg_step_float(uint *rng) { *rng = (1103515245*(*rng) + 12345); return (float)*rng * (1.0f/(float)0xFFFFFFFF); } uint lcg_init(uint seed) { uint rng = seed; lcg_step_uint(&rng); return rng; } float path_state_rng_1D(KernelGlobals *kg, __global RNG *rng, const __global PathState *state, int dimension) { return path_rng_1D(kg, rng, state->sample, state->num_samples, state->rng_offset + dimension); } float path_state_rng_1D_for_decision(KernelGlobals *kg, __global RNG *rng, const __global PathState *state, int dimension) { int rng_offset = state->rng_offset + state->transparent_bounce*PRNG_BOUNCE_NUM; return path_rng_1D(kg, rng, state->sample, state->num_samples, rng_offset + dimension); } void path_state_rng_2D(KernelGlobals *kg, __global RNG *rng, const __global PathState *state, int dimension, float *fx, float *fy) { path_rng_2D(kg, rng, state->sample, state->num_samples, state->rng_offset + dimension, fx, fy); } float path_branched_rng_1D(KernelGlobals *kg, __global RNG *rng, const PathState *state, int branch, int num_branches, int dimension) { return path_rng_1D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, state->rng_offset + dimension); } float path_branched_rng_1D_for_decision(KernelGlobals *kg, __global RNG *rng, const PathState *state, int branch, int num_branches, int dimension) { int rng_offset = state->rng_offset + state->transparent_bounce*PRNG_BOUNCE_NUM; return path_rng_1D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, rng_offset + dimension); } void path_branched_rng_2D(KernelGlobals *kg, __global RNG *rng, const PathState *state, int branch, int num_branches, int dimension, float *fx, float *fy) { path_rng_2D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, state->rng_offset + dimension, fx, fy); } void path_state_branch(PathState *state, int branch, int num_branches) { state->rng_offset += PRNG_BOUNCE_NUM; state->sample = state->sample*num_branches + branch; state->num_samples = state->num_samples*num_branches; } uint lcg_state_init(RNG *rng, const PathState *state, uint scramble) { return lcg_init(*rng + state->rng_offset + state->sample*scramble); } float2 direction_to_spherical(float3 dir) { float theta = safe_acosf(dir.z); float phi = atan2(((float)(dir . x)), ((float)(dir . y))); return ((float2)(theta, phi)); } float3 spherical_to_direction(float theta, float phi) { return ((float3)(native_sin(((float)(theta)))*native_cos(((float)(phi))), native_sin(((float)(theta)))*native_sin(((float)(phi))), native_cos(((float)(theta))))); } float2 direction_to_equirectangular_range(float3 dir, float4 range) { float u = (atan2(((float)(dir . y)), ((float)(dir . x))) - range.y) / range.x; float v = (acos(((float)(dir . z / len(dir)))) - range.w) / range.z; return ((float2)(u, v)); } float3 equirectangular_range_to_direction(float u, float v, float4 range) { float phi = range.x*u + range.y; float theta = range.z*v + range.w; return ((float3)(native_sin(((float)(theta)))*native_cos(((float)(phi))), native_sin(((float)(theta)))*native_sin(((float)(phi))), native_cos(((float)(theta))))); } float2 direction_to_equirectangular(float3 dir) { return direction_to_equirectangular_range(dir, ((float4)(-((float)6.283185307179586476925286766559005768), 3.14159274101257f, -3.14159274101257f, 3.14159274101257f))); } float3 equirectangular_to_direction(float u, float v) { return equirectangular_range_to_direction(u, v, ((float4)(-((float)6.283185307179586476925286766559005768), 3.14159274101257f, -3.14159274101257f, 3.14159274101257f))); } float2 direction_to_fisheye(float3 dir, float fov) { float r = atan2(((float)(native_sqrt(((float)(dir . y*dir . y + dir . z*dir . z))))), ((float)(dir . x))) / fov; float phi = atan2(((float)(dir . z)), ((float)(dir . y))); float u = r * native_cos(((float)(phi))) + 0.5f; float v = r * native_sin(((float)(phi))) + 0.5f; return ((float2)(u, v)); } float3 fisheye_to_direction(float u, float v, float fov) { u = (u - 0.5f) * 2.0f; v = (v - 0.5f) * 2.0f; float r = native_sqrt(((float)(u*u + v*v))); if(r > 1.0f) return ((float3)(0.0f, 0.0f, 0.0f)); float phi = safe_acosf((r != 0.0f)? u/r: 0.0f); float theta = r * fov * 0.5f; if(v < 0.0f) phi = -phi; return ((float3)(native_cos(((float)(theta))), -native_cos(((float)(phi)))*native_sin(((float)(theta))), native_sin(((float)(phi)))*native_sin(((float)(theta))))); } float2 direction_to_fisheye_equisolid(float3 dir, float lens, float width, float height) { float theta = safe_acosf(dir.x); float r = 2.0f * lens * native_sin(((float)(theta * 0.5f))); float phi = atan2(((float)(dir . z)), ((float)(dir . y))); float u = r * native_cos(((float)(phi))) / width + 0.5f; float v = r * native_sin(((float)(phi))) / height + 0.5f; return ((float2)(u, v)); } float3 fisheye_equisolid_to_direction(float u, float v, float lens, float fov, float width, float height) { u = (u - 0.5f) * width; v = (v - 0.5f) * height; float rmax = 2.0f * lens * native_sin(((float)(fov * 0.25f))); float r = native_sqrt(((float)(u*u + v*v))); if(r > rmax) return ((float3)(0.0f, 0.0f, 0.0f)); float phi = safe_acosf((r != 0.0f)? u/r: 0.0f); float theta = 2.0f * asin(((float)(r/(2.0f * lens)))); if(v < 0.0f) phi = -phi; return ((float3)(native_cos(((float)(theta))), -native_cos(((float)(phi)))*native_sin(((float)(theta))), native_sin(((float)(phi)))*native_sin(((float)(theta))))); } float3 mirrorball_to_direction(float u, float v) { float3 dir; dir.x = 2.0f*u - 1.0f; dir.z = 2.0f*v - 1.0f; if(dir.x*dir.x + dir.z*dir.z > 1.0f) return ((float3)(0.0f, 0.0f, 0.0f)); dir.y = -native_sqrt(((float)(max(1.0f - dir . x*dir . x - dir . z*dir . z, 0.0f)))); float3 I = ((float3)(0.0f, -1.0f, 0.0f)); return 2.0f*dot(dir, I)*dir - I; } float2 direction_to_mirrorball(float3 dir) { dir.y -= 1.0f; float div = 2.0f*native_sqrt(((float)(max(-0.5f*dir . y, 0.0f)))); if(div > 0.0f) dir /= div; float u = 0.5f*(dir.x + 1.0f); float v = 0.5f*(dir.z + 1.0f); return ((float2)(u, v)); } float3 panorama_to_direction(KernelGlobals *kg, float u, float v) { switch((*kg->data).cam.panorama_type) { case PANORAMA_EQUIRECTANGULAR: return equirectangular_range_to_direction(u, v, (*kg->data).cam.equirectangular_range); case PANORAMA_MIRRORBALL: return mirrorball_to_direction(u, v); case PANORAMA_FISHEYE_EQUIDISTANT: return fisheye_to_direction(u, v, (*kg->data).cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: default: return fisheye_equisolid_to_direction(u, v, (*kg->data).cam.fisheye_lens, (*kg->data).cam.fisheye_fov, (*kg->data).cam.sensorwidth, (*kg->data).cam.sensorheight); } } float2 direction_to_panorama(KernelGlobals *kg, float3 dir) { switch((*kg->data).cam.panorama_type) { case PANORAMA_EQUIRECTANGULAR: return direction_to_equirectangular_range(dir, (*kg->data).cam.equirectangular_range); case PANORAMA_MIRRORBALL: return direction_to_mirrorball(dir); case PANORAMA_FISHEYE_EQUIDISTANT: return direction_to_fisheye(dir, (*kg->data).cam.fisheye_fov); case PANORAMA_FISHEYE_EQUISOLID: default: return direction_to_fisheye_equisolid(dir, (*kg->data).cam.fisheye_lens, (*kg->data).cam.sensorwidth, (*kg->data).cam.sensorheight); } } void to_unit_disk(float *x, float *y) { float phi = ((float)6.283185307179586476925286766559005768) * (*x); float r = native_sqrt(((float)(*y))); *x = r * native_cos(((float)(phi))); *y = r * native_sin(((float)(phi))); } void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b) { *b = normalize(cross(N, T)); *a = cross(*b, N); } void sample_cos_hemisphere(const float3 N, float randu, float randv, float3 *omega_in, float *pdf) { to_unit_disk(&randu, &randv); float costheta = native_sqrt(((float)(max(1.0f - randu * randu - randv * randv, 0.0f)))); float3 T, B; make_orthonormals(N, &T, &B); *omega_in = randu * T + randv * B + costheta * N; *pdf = costheta *0.31830987334251f; } void sample_uniform_hemisphere(const float3 N, float randu, float randv, float3 *omega_in, float *pdf) { float z = randu; float r = native_sqrt(((float)(max(0.0f, 1.0f - z*z)))); float phi = ((float)6.283185307179586476925286766559005768) * randv; float x = r * native_cos(((float)(phi))); float y = r * native_sin(((float)(phi))); float3 T, B; make_orthonormals (N, &T, &B); *omega_in = x * T + y * B + z * N; *pdf = 0.5f * 0.31830987334251f; } void sample_uniform_cone(const float3 N, float angle, float randu, float randv, float3 *omega_in, float *pdf) { float z = native_cos(((float)(angle*randu))); float r = native_sqrt(((float)(max(0.0f, 1.0f - z*z)))); float phi = ((float)6.283185307179586476925286766559005768) * randv; float x = r * native_cos(((float)(phi))); float y = r * native_sin(((float)(phi))); float3 T, B; make_orthonormals (N, &T, &B); *omega_in = x * T + y * B + z * N; *pdf = 0.5f * 0.31830987334251f / (1.0f - native_cos(((float)(angle)))); } float3 sample_uniform_sphere(float u1, float u2) { float z = 1.0f - 2.0f*u1; float r = native_sqrt(((float)(fmax(((float)(0.0f)), ((float)(1.0f - z*z)))))); float phi = ((float)6.283185307179586476925286766559005768)*u2; float x = r*native_cos(((float)(phi))); float y = r*native_sin(((float)(phi))); return ((float3)(x, y, z)); } float balance_heuristic(float a, float b) { return (a)/(a + b); } float balance_heuristic_3(float a, float b, float c) { return (a)/(a + b + c); } float power_heuristic(float a, float b) { return (a*a)/(a*a + b*b); } float power_heuristic_3(float a, float b, float c) { return (a*a)/(a*a + b*b + c*c); } float max_heuristic(float a, float b) { return (a > b)? 1.0f: 0.0f; } float2 concentric_sample_disk(float u1, float u2) { float phi, r; float a = 2.0f*u1 - 1.0f; float b = 2.0f*u2 - 1.0f; if(a == 0.0f && b == 0.0f) { return ((float2)(0.0f, 0.0f)); } else if(a*a > b*b) { r = a; phi = 0.78539818525314f * (b/a); } else { r = b; phi = 1.57079637050629f - 0.78539818525314f * (a/b); } return ((float2)(r*native_cos(((float)(phi))), r*native_sin(((float)(phi))))); } float2 regular_polygon_sample(float corners, float rotation, float u, float v) { float corner = floor(((float)(u*corners))); u = u*corners - corner; u = native_sqrt(((float)(u))); v = v*u; u = 1.0f - u; float angle = 3.14159274101257f/corners; float2 p = ((float2)((u + v)*native_cos(((float)(angle))), (u - v)*native_sin(((float)(angle))))); rotation += corner*2.0f*angle; float cr = native_cos(((float)(rotation))); float sr = native_sin(((float)(rotation))); return ((float2)(cr*p . x - sr*p . y, sr*p . x + cr*p . y)); } void differential_transfer(__global differential3 *dP_, const differential3 dP, float3 D, const differential3 dD, float3 Ng, float t) { float3 tmp = D/dot(D, Ng); float3 tmpx = dP.dx + t*dD.dx; float3 tmpy = dP.dy + t*dD.dy; dP_->dx = tmpx - dot(tmpx, Ng)*tmp; dP_->dy = tmpy - dot(tmpy, Ng)*tmp; } void differential_incoming(__global differential3 *dI, const differential3 dD) { dI->dx = -dD.dx; dI->dy = -dD.dy; } void differential_dudv(__global differential *du, __global differential *dv, float3 dPdu, float3 dPdv, differential3 dP, float3 Ng) { float xn = fabs(((float)(Ng . x))); float yn = fabs(((float)(Ng . y))); float zn = fabs(((float)(Ng . z))); if(zn < xn || zn < yn) { if(yn < xn || yn < zn) { dPdu.x = dPdu.y; dPdv.x = dPdv.y; dP.dx.x = dP.dx.y; dP.dy.x = dP.dy.y; } dPdu.y = dPdu.z; dPdv.y = dPdv.z; dP.dx.y = dP.dx.z; dP.dy.y = dP.dy.z; } float det = (dPdu.x*dPdv.y - dPdv.x*dPdu.y); if(det != 0.0f) det = 1.0f/det; du->dx = (dP.dx.x*dPdv.y - dP.dx.y*dPdv.x)*det; dv->dx = (dP.dx.y*dPdu.x - dP.dx.x*dPdu.y)*det; du->dy = (dP.dy.x*dPdv.y - dP.dy.y*dPdv.x)*det; dv->dy = (dP.dy.y*dPdu.x - dP.dy.x*dPdu.y)*det; } differential differential_zero() { differential d; d.dx = 0.0f; d.dy = 0.0f; return d; } differential3 differential3_zero() { differential3 d; d.dx = ((float3)(0.0f, 0.0f, 0.0f)); d.dy = ((float3)(0.0f, 0.0f, 0.0f)); return d; } float2 camera_sample_aperture(KernelGlobals *kg, float u, float v) { float blades = (*kg->data).cam.blades; float2 bokeh; if(blades == 0.0f) { bokeh = concentric_sample_disk(u, v); } else { float rotation = (*kg->data).cam.bladesrotation; bokeh = regular_polygon_sample(blades, rotation, u, v); } bokeh.x *= (*kg->data).cam.inv_aperture_ratio; return bokeh; } void camera_sample_perspective(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, __global Ray *ray) { Transform rastertocamera = (*kg->data).cam.rastertocamera; float3 raster = ((float3)(raster_x, raster_y, 0.0f)); float3 Pcamera = transform_perspective(&rastertocamera, raster); #line 22382 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ray->P = ((float3)(0.0f, 0.0f, 0.0f)); ray->D = Pcamera; float aperturesize = (*kg->data).cam.aperturesize; if(aperturesize > 0.0f) { float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize; float ft = (*kg->data).cam.focaldistance/ray->D.z; float3 Pfocus = ray->D*ft; ray->P = ((float3)(lensuv . x, lensuv . y, 0.0f)); ray->D = normalize(Pfocus - ray->P); } Transform cameratoworld = (*kg->data).cam.cameratoworld; #line 22419 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ray->P = transform_point(&cameratoworld, ray->P); ray->D = transform_direction(&cameratoworld, ray->D); ray->D = normalize(ray->D); float3 Ddiff = transform_direction(&cameratoworld, Pcamera); ray->dP = differential3_zero(); ray->dD.dx = normalize(Ddiff + float4_to_float3((*kg->data).cam.dx)) - normalize(Ddiff); ray->dD.dy = normalize(Ddiff + float4_to_float3((*kg->data).cam.dy)) - normalize(Ddiff); float3 Pclip = normalize(Pcamera); float z_inv = 1.0f / Pclip.z; ray->P += (*kg->data).cam.nearclip*ray->D * z_inv; ray->t = (*kg->data).cam.cliplength * z_inv; } void camera_sample_orthographic(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, __global Ray *ray) { Transform rastertocamera = (*kg->data).cam.rastertocamera; float3 Pcamera = transform_perspective(&rastertocamera, ((float3)(raster_x, raster_y, 0.0f))); ray->D = ((float3)(0.0f, 0.0f, 1.0f)); float aperturesize = (*kg->data).cam.aperturesize; if(aperturesize > 0.0f) { float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize; float3 Pfocus = ray->D * (*kg->data).cam.focaldistance; float3 lensuvw = ((float3)(lensuv . x, lensuv . y, 0.0f)); ray->P = Pcamera + lensuvw; ray->D = normalize(Pfocus - lensuvw); } else { ray->P = Pcamera; } Transform cameratoworld = (*kg->data).cam.cameratoworld; #line 22489 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ray->P = transform_point(&cameratoworld, ray->P); ray->D = transform_direction(&cameratoworld, ray->D); ray->D = normalize(ray->D); ray->dP.dx = float4_to_float3((*kg->data).cam.dx); ray->dP.dy = float4_to_float3((*kg->data).cam.dy); ray->dD = differential3_zero(); ray->t = (*kg->data).cam.cliplength; } void camera_sample_panorama(KernelGlobals *kg, float raster_x, float raster_y, float lens_u, float lens_v, __global Ray *ray) { Transform rastertocamera = (*kg->data).cam.rastertocamera; float3 Pcamera = transform_perspective(&rastertocamera, ((float3)(raster_x, raster_y, 0.0f))); ray->P = ((float3)(0.0f, 0.0f, 0.0f)); ray->t = (*kg->data).cam.cliplength; ray->D = panorama_to_direction(kg, Pcamera.x, Pcamera.y); if(is_zero(ray->D)) { ray->t = 0.0f; return; } float aperturesize = (*kg->data).cam.aperturesize; if(aperturesize > 0.0f) { float2 lensuv = camera_sample_aperture(kg, lens_u, lens_v)*aperturesize; float3 D = normalize(ray->D); float3 Pfocus = D * (*kg->data).cam.focaldistance; float3 U, V; U = normalize(((float3)(1.0f, 0.0f, 0.0f)) - D.x * D); V = normalize(cross(D, U)); ray->P = U * lensuv.x + V * lensuv.y; ray->D = normalize(Pfocus - ray->P); } Transform cameratoworld = (*kg->data).cam.cameratoworld; #line 22573 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ray->P = transform_point(&cameratoworld, ray->P); ray->D = transform_direction(&cameratoworld, ray->D); ray->D = normalize(ray->D); ray->dP = differential3_zero(); Pcamera = transform_perspective(&rastertocamera, ((float3)(raster_x, raster_y, 0.0f))); float3 Ddiff = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))); Pcamera = transform_perspective(&rastertocamera, ((float3)(raster_x + 1.0f, raster_y, 0.0f))); ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; Pcamera = transform_perspective(&rastertocamera, ((float3)(raster_x, raster_y + 1.0f, 0.0f))); ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; } void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v, float lens_u, float lens_v, float time, __global Ray *ray) { int filter_table_offset = (*kg->data).film.filter_table_offset; float raster_x = x + lookup_table_read(kg, filter_u, filter_table_offset, 256); float raster_y = y + lookup_table_read(kg, filter_v, filter_table_offset, 256); #line 22610 "C:\\cygwin64\\tmp\\OCL6424T10.cl" if((*kg->data).cam.type == CAMERA_PERSPECTIVE) camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray); else if((*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) camera_sample_orthographic(kg, raster_x, raster_y, lens_u, lens_v, ray); else camera_sample_panorama(kg, raster_x, raster_y, lens_u, lens_v, ray); } float3 camera_position(KernelGlobals *kg) { Transform cameratoworld = (*kg->data).cam.cameratoworld; return ((float3)(cameratoworld . x . w, cameratoworld . y . w, cameratoworld . z . w)); } float camera_distance(KernelGlobals *kg, float3 P) { Transform cameratoworld = (*kg->data).cam.cameratoworld; float3 camP = ((float3)(cameratoworld . x . w, cameratoworld . y . w, cameratoworld . z . w)); if((*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) { float3 camD = ((float3)(cameratoworld . x . z, cameratoworld . y . z, cameratoworld . z . z)); return fabs(((float)(dot((P - camP), camD)))); } else return len(P - camP); } float3 camera_direction_from_point(KernelGlobals *kg, float3 P) { Transform cameratoworld = (*kg->data).cam.cameratoworld; if((*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) { float3 camD = ((float3)(cameratoworld . x . z, cameratoworld . y . z, cameratoworld . z . z)); return -camD; } else { float3 camP = ((float3)(cameratoworld . x . w, cameratoworld . y . w, cameratoworld . z . w)); return normalize(camP - P); } } float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P) { if((*kg->data).cam.type != CAMERA_PANORAMA) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0) && (*kg->data).cam.type == CAMERA_PERSPECTIVE) P += camera_position(kg); Transform tfm = (*kg->data).cam.worldtondc; return transform_perspective(&tfm, P); } else { Transform tfm = (*kg->data).cam.worldtocamera; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) P = normalize(transform_point(&tfm, P)); else P = normalize(transform_direction(&tfm, P)); float2 uv = direction_to_panorama(kg, P); return ((float3)(uv . x, uv . y, 0.0f)); } } #line 22713 "C:\\cygwin64\\tmp\\OCL6424T10.cl" int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0)) return (int)ATTR_STD_NOT_FOUND; uint attr_offset = (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*(*kg->data).bvh.attributes_map_stride; uint4 attr_map = kg->__attributes_map[attr_offset]; while(attr_map.x != id) { if((attr_map . x == ATTR_STD_NONE)) { return ATTR_STD_NOT_FOUND; } attr_offset += 2; attr_map = kg->__attributes_map[attr_offset]; } *elem = (AttributeElement)attr_map.y; if((sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0) && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH) return ATTR_STD_NOT_FOUND; return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset) { Transform tfm; tfm.x = kg->__attributes_float3[offset + 0]; tfm.y = kg->__attributes_float3[offset + 1]; tfm.z = kg->__attributes_float3[offset + 2]; tfm.w = kg->__attributes_float3[offset + 3]; return tfm; } enum ObjectTransform { OBJECT_TRANSFORM = 0, OBJECT_TRANSFORM_MOTION_PRE = 0, OBJECT_INVERSE_TRANSFORM = 4, OBJECT_TRANSFORM_MOTION_POST = 4, OBJECT_PROPERTIES = 8, OBJECT_DUPLI = 9 }; enum ObjectVectorTransform { OBJECT_VECTOR_MOTION_PRE = 0, OBJECT_VECTOR_MOTION_POST = 3 }; Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) { int offset = object*11 + (int)type; Transform tfm; tfm.x = kg->__objects[offset + 0]; tfm.y = kg->__objects[offset + 1]; tfm.z = kg->__objects[offset + 2]; tfm.w = ((float4)(0.0f, 0.0f, 0.0f, 1.0f)); return tfm; } Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type) { int offset = object*6 + (int)type; Transform tfm; tfm.x = kg->__objects_vector[offset + 0]; tfm.y = kg->__objects_vector[offset + 1]; tfm.z = kg->__objects_vector[offset + 2]; tfm.w = ((float4)(0.0f, 0.0f, 0.0f, 1.0f)); return tfm; } #line 22920 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void object_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_TRANSFORM); *P = transform_point(&tfm, *P); } void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, *P); } void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); } void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_INVERSE_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); } void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_TRANSFORM); *D = transform_direction(&tfm, *D); } void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D) { Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_INVERSE_TRANSFORM); *D = transform_direction(&tfm, *D); } float3 object_location(KernelGlobals *kg, const ShaderData *sd) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0)) return ((float3)(0.0f, 0.0f, 0.0f)); Transform tfm = object_fetch_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_TRANSFORM); return ((float3)(tfm . x . w, tfm . y . w, tfm . z . w)); } float object_surface_area(KernelGlobals *kg, int object) { int offset = object*11 + OBJECT_PROPERTIES; float4 f = kg->__objects[offset]; return f.x; } float object_pass_id(KernelGlobals *kg, int object) { if(object == (~0)) return 0.0f; int offset = object*11 + OBJECT_PROPERTIES; float4 f = kg->__objects[offset]; return f.y; } float object_random_number(KernelGlobals *kg, int object) { if(object == (~0)) return 0.0f; int offset = object*11 + OBJECT_PROPERTIES; float4 f = kg->__objects[offset]; return f.z; } int object_particle_id(KernelGlobals *kg, int object) { if(object == (~0)) return 0; int offset = object*11 + OBJECT_PROPERTIES; float4 f = kg->__objects[offset]; return as_uint(f . w); } float3 object_dupli_generated(KernelGlobals *kg, int object) { if(object == (~0)) return ((float3)(0.0f, 0.0f, 0.0f)); int offset = object*11 + OBJECT_DUPLI; float4 f = kg->__objects[offset]; return ((float3)(f . x, f . y, f . z)); } float3 object_dupli_uv(KernelGlobals *kg, int object) { if(object == (~0)) return ((float3)(0.0f, 0.0f, 0.0f)); int offset = object*11 + OBJECT_DUPLI; float4 f = kg->__objects[offset + 1]; return ((float3)(f . x, f . y, 0.0f)); } void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys) { int offset = object*11 + OBJECT_DUPLI; if(numkeys) { float4 f = kg->__objects[offset]; *numkeys = as_int(f . w); } float4 f = kg->__objects[offset + 1]; if(numsteps) *numsteps = as_int(f . z); if(numverts) *numverts = as_int(f . w); } int shader_pass_id(KernelGlobals *kg, const ShaderData *sd) { return kg->__shader_flag[((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_MASK)*2 + 1]; } float particle_index(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 0]; return f.x; } float particle_age(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 0]; return f.y; } float particle_lifetime(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 0]; return f.z; } float particle_size(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 0]; return f.w; } float4 particle_rotation(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 1]; return f; } float3 particle_location(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f = kg->__particles[offset + 2]; return ((float3)(f . x, f . y, f . z)); } float3 particle_velocity(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f2 = kg->__particles[offset + 2]; float4 f3 = kg->__particles[offset + 3]; return ((float3)(f2 . w, f3 . x, f3 . y)); } float3 particle_angular_velocity(KernelGlobals *kg, int particle) { int offset = particle*5; float4 f3 = kg->__particles[offset + 3]; float4 f4 = kg->__particles[offset + 4]; return ((float3)(f3 . z, f3 . w, f4 . x)); } float3 bvh_clamp_direction(float3 dir) { float ooeps = 8.271806E-25f; return ((float3)((fabs(((float)(dir . x))) > ooeps)? dir . x: copysign(((float)(ooeps)), ((float)(dir . x))), (fabs(((float)(dir . y))) > ooeps)? dir . y: copysign(((float)(ooeps)), ((float)(dir . y))), (fabs(((float)(dir . z))) > ooeps)? dir . z: copysign(((float)(ooeps)), ((float)(dir . z))))); } float3 bvh_inverse_direction(float3 dir) { return 1.0f / dir; } void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, __global float *t) { Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, ray->P); float len; *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); if(*t != 0x1.fffffep127f) *t *= len; } #line 23225 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, __global float *t) { if(*t != 0x1.fffffep127f) { Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); *t *= len(transform_direction(&tfm, 1.0f/(*idir))); } *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); } void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac) { Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); *t_fac = len(transform_direction(&tfm, 1.0f/(*idir))); *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); } #line 23322 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void object_dir_transform_addrspace(KernelGlobals *kg, const ShaderData *sd, __global float3 *D) { float3 private_D = *D; object_dir_transform(kg, sd, &private_D); *D = private_D; } void object_normal_transform_addrspace(KernelGlobals *kg, const ShaderData *sd, __global float3 *N) { float3 private_N = *N; object_normal_transform(kg, sd, &private_N); *N = private_N; } #line 23355 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 triangle_normal(KernelGlobals *kg, ShaderData *sd) { float4 tri_vindex = kg->__tri_vindex[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; float3 v0 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . x)]); float3 v1 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . y)]); float3 v2 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . z)]); if((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_NEGATIVE_SCALE_APPLIED) return normalize(cross(v2 - v0, v1 - v0)); else return normalize(cross(v1 - v0, v2 - v0)); } void triangle_point_normal(KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader) { float4 tri_vindex = kg->__tri_vindex[prim]; float3 v0 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . x)]); float3 v1 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . y)]); float3 v2 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . z)]); float t = 1.0f - u - v; *P = (u*v0 + v*v1 + t*v2); int object_flag = kg->__object_flag[object >= 0 ? object : ~object]; if(object_flag & SD_NEGATIVE_SCALE_APPLIED) *Ng = normalize(cross(v2 - v0, v1 - v0)); else *Ng = normalize(cross(v1 - v0, v2 - v0)); *shader = kg->__tri_shader[prim]; } void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3]) { float4 tri_vindex = kg->__tri_vindex[prim]; P[0] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . x)]); P[1] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . y)]); P[2] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . z)]); } float3 triangle_smooth_normal(KernelGlobals *kg, int prim, float u, float v) { float4 tri_vindex = kg->__tri_vindex[prim]; float3 n0 = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . x)]); float3 n1 = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . y)]); float3 n2 = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . z)]); return normalize((1.0f - u - v)*n2 + u*n0 + v*n1); } void triangle_dPdudv(KernelGlobals *kg, int prim, __global float3 *dPdu, __global float3 *dPdv) { float4 tri_vindex = kg->__tri_vindex[prim]; float3 p0 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . x)]); float3 p1 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . y)]); float3 p2 = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . z)]); *dPdu = (p0 - p2); *dPdv = (p1 - p2); } float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) { if(elem == ATTR_ELEMENT_FACE) { if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; return kg->__attributes_float[offset + (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; } else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { float4 tri_vindex = kg->__tri_vindex[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; float f0 = kg->__attributes_float[offset + as_int(tri_vindex . x)]; float f1 = kg->__attributes_float[offset + as_int(tri_vindex . y)]; float f2 = kg->__attributes_float[offset + as_int(tri_vindex . z)]; if(dx) *dx = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx)*f2; if(dy) *dy = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy)*f2; return (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f0 + (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f1 + (1.0f - (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*f2; } else if(elem == ATTR_ELEMENT_CORNER) { int tri = offset + (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*3; float f0 = kg->__attributes_float[tri + 0]; float f1 = kg->__attributes_float[tri + 1]; float f2 = kg->__attributes_float[tri + 2]; if(dx) *dx = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx)*f2; if(dy) *dy = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy)*f2; return (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f0 + (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f1 + (1.0f - (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*f2; } else { if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; return 0.0f; } } float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) { if(elem == ATTR_ELEMENT_FACE) { if(dx) *dx = ((float3)(0.0f, 0.0f, 0.0f)); if(dy) *dy = ((float3)(0.0f, 0.0f, 0.0f)); return float4_to_float3(kg->__attributes_float3[offset + (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); } else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { float4 tri_vindex = kg->__tri_vindex[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; float3 f0 = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . x)]); float3 f1 = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . y)]); float3 f2 = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . z)]); if(dx) *dx = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx)*f2; if(dy) *dy = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy)*f2; return (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f0 + (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f1 + (1.0f - (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*f2; } else if(elem == ATTR_ELEMENT_CORNER || elem == ATTR_ELEMENT_CORNER_BYTE) { int tri = offset + (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*3; float3 f0, f1, f2; if(elem == ATTR_ELEMENT_CORNER) { f0 = float4_to_float3(kg->__attributes_float3[tri + 0]); f1 = float4_to_float3(kg->__attributes_float3[tri + 1]); f2 = float4_to_float3(kg->__attributes_float3[tri + 2]); } else { f0 = color_byte_to_float(kg->__attributes_uchar4[tri + 0]); f1 = color_byte_to_float(kg->__attributes_uchar4[tri + 1]); f2 = color_byte_to_float(kg->__attributes_uchar4[tri + 2]); } if(dx) *dx = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx)*f2; if(dy) *dy = (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f0 + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy*f1 - ((sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy)*f2; return (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f0 + (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*f1 + (1.0f - (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*f2; } else { if(dx) *dx = ((float3)(0.0f, 0.0f, 0.0f)); if(dy) *dy = ((float3)(0.0f, 0.0f, 0.0f)); return ((float3)(0.0f, 0.0f, 0.0f)); } } #line 23605 "C:\\cygwin64\\tmp\\OCL6424T10.cl" typedef struct IsectPrecalc { int kx, ky, kz; float Sx, Sy, Sz; } IsectPrecalc; #line 23636 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void triangle_intersect_precalc(float3 dir, IsectPrecalc *isect_precalc) { int kz = util_max_axis(((float3)(fabs(((float)(dir . x))), fabs(((float)(dir . y))), fabs(((float)(dir . z)))))); int kx = kz + 1; if(kx == 3) kx = 0; int ky = kx + 1; if(ky == 3) ky = 0; if(((kz == 0) ? ((dir). x) : ( (kz == 1) ? ((dir). y) : ((dir). z) )) < 0.0f) { int tmp = kx; kx = ky; ky = tmp; } float inv_dir_z = 1.0f / ((kz == 0) ? ((dir). x) : ( (kz == 1) ? ((dir). y) : ((dir). z) )); isect_precalc->Sx = ((kx == 0) ? ((dir). x) : ( (kx == 1) ? ((dir). y) : ((dir). z) )) * inv_dir_z; isect_precalc->Sy = ((ky == 0) ? ((dir). x) : ( (ky == 1) ? ((dir). y) : ((dir). z) )) * inv_dir_z; isect_precalc->Sz = inv_dir_z; isect_precalc->kx = kx; isect_precalc->ky = ky; isect_precalc->kz = kz; } float xor_signmask(float x, int y) { return as_float(as_int(x) ^ y); } bool triangle_intersect(KernelGlobals *kg, const IsectPrecalc *isect_precalc, Intersection *isect, float3 P, uint visibility, int object, int triAddr) { const int kx = isect_precalc->kx; const int ky = isect_precalc->ky; const int kz = isect_precalc->kz; const float Sx = isect_precalc->Sx; const float Sy = isect_precalc->Sy; const float Sz = isect_precalc->Sz; const float4 tri_a = kg->__tri_woop[triAddr*3+0], tri_b = kg->__tri_woop[triAddr*3+1], tri_c = kg->__tri_woop[triAddr*3+2]; const float3 A = ((float3)(tri_a . x - P . x, tri_a . y - P . y, tri_a . z - P . z)); const float3 B = ((float3)(tri_b . x - P . x, tri_b . y - P . y, tri_b . z - P . z)); const float3 C = ((float3)(tri_c . x - P . x, tri_c . y - P . y, tri_c . z - P . z)); const float A_kx = ((kx == 0) ? ((A). x) : ( (kx == 1) ? ((A). y) : ((A). z) )), A_ky = ((ky == 0) ? ((A). x) : ( (ky == 1) ? ((A). y) : ((A). z) )), A_kz = ((kz == 0) ? ((A). x) : ( (kz == 1) ? ((A). y) : ((A). z) )); const float B_kx = ((kx == 0) ? ((B). x) : ( (kx == 1) ? ((B). y) : ((B). z) )), B_ky = ((ky == 0) ? ((B). x) : ( (ky == 1) ? ((B). y) : ((B). z) )), B_kz = ((kz == 0) ? ((B). x) : ( (kz == 1) ? ((B). y) : ((B). z) )); const float C_kx = ((kx == 0) ? ((C). x) : ( (kx == 1) ? ((C). y) : ((C). z) )), C_ky = ((ky == 0) ? ((C). x) : ( (ky == 1) ? ((C). y) : ((C). z) )), C_kz = ((kz == 0) ? ((C). x) : ( (kz == 1) ? ((C). y) : ((C). z) )); const float Ax = A_kx - Sx * A_kz; const float Ay = A_ky - Sy * A_kz; const float Bx = B_kx - Sx * B_kz; const float By = B_ky - Sy * B_kz; const float Cx = C_kx - Sx * C_kz; const float Cy = C_ky - Sy * C_kz; float U = Cx * By - Cy * Bx; float V = Ax * Cy - Ay * Cx; float W = Bx * Ay - By * Ax; if((U < 0.0f || V < 0.0f || W < 0.0f) && (U > 0.0f || V > 0.0f || W > 0.0f)) { return 0; } float det = U + V + W; if((det == 0.0f)) { return 0; } const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; const int sign_det = (as_int(det) & 0x80000000); const float sign_T = xor_signmask(T, sign_det); if((sign_T < 0.0f) || (sign_T > isect->t * xor_signmask(det, sign_det))) { return 0; } if(kg->__prim_visibility[triAddr] & visibility) { float4 a = tri_b - tri_a, b = tri_c - tri_a; if(len_squared(((float3)(a . y*b . z - a . z*b . y, a . z*b . x - a . x*b . z, a . x*b . y - a . y*b . x))) == 0.0f) { return 0; } const float inv_det = 1.0f / det; isect->prim = triAddr; isect->object = object; isect->type = PRIMITIVE_TRIANGLE; isect->u = U * inv_det; isect->v = V * inv_det; isect->t = T * inv_det; return 1; } return 0; } #line 23873 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { float3 P = ray->P; float3 D = ray->D; float t = isect->t; if(isect->object != (~0)) { if((t == 0.0f)) { return P; } Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); P = transform_point(&tfm, P); D = transform_direction(&tfm, D*t); D = normalize_len(D, &t); } P = P + D*t; const float4 tri_a = kg->__tri_woop[isect->prim*3+0], tri_b = kg->__tri_woop[isect->prim*3+1], tri_c = kg->__tri_woop[isect->prim*3+2]; float3 edge1 = ((float3)(tri_a . x - tri_c . x, tri_a . y - tri_c . y, tri_a . z - tri_c . z)); float3 edge2 = ((float3)(tri_b . x - tri_c . x, tri_b . y - tri_c . y, tri_b . z - tri_c . z)); float3 tvec = ((float3)(P . x - tri_c . x, P . y - tri_c . y, P . z - tri_c . z)); float3 qvec = cross(tvec, edge1); float3 pvec = cross(D, edge2); float rt = dot(edge2, qvec) / dot(edge1, pvec); P = P + D*rt; if(isect->object != (~0)) { Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); P = transform_point(&tfm, P); } return P; } float3 triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { float3 P = ray->P; float3 D = ray->D; float t = isect->t; if(isect->object != (~0)) { Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); P = transform_point(&tfm, P); D = transform_direction(&tfm, D); D = normalize(D); } P = P + D*t; const float4 tri_a = kg->__tri_woop[isect->prim*3+0], tri_b = kg->__tri_woop[isect->prim*3+1], tri_c = kg->__tri_woop[isect->prim*3+2]; float3 edge1 = ((float3)(tri_a . x - tri_c . x, tri_a . y - tri_c . y, tri_a . z - tri_c . z)); float3 edge2 = ((float3)(tri_b . x - tri_c . x, tri_b . y - tri_c . y, tri_b . z - tri_c . z)); float3 tvec = ((float3)(P . x - tri_c . x, P . y - tri_c . y, P . z - tri_c . z)); float3 qvec = cross(tvec, edge1); float3 pvec = cross(D, edge2); float rt = dot(edge2, qvec) / dot(edge1, pvec); P = P + D*rt; if(isect->object != (~0)) { Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); P = transform_point(&tfm, P); } return P; } int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem) { uint attr_offset = object*(*kg->data).bvh.attributes_map_stride; uint4 attr_map = kg->__attributes_map[attr_offset]; while(attr_map.x != id) { attr_offset += 2; attr_map = kg->__attributes_map[attr_offset]; } *elem = (AttributeElement)attr_map.y; return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } void motion_triangle_verts_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3]) { if(step == numsteps) { verts[0] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . x)]); verts[1] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . y)]); verts[2] = float4_to_float3(kg->__tri_verts[as_int(tri_vindex . z)]); } else { if(step > numsteps) step--; offset += step*numverts; verts[0] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . x)]); verts[1] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . y)]); verts[2] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . z)]); } } void motion_triangle_normals_for_step(KernelGlobals *kg, float3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3]) { if(step == numsteps) { normals[0] = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . x)]); normals[1] = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . y)]); normals[2] = float4_to_float3(kg->__tri_vnormal[as_int(tri_vindex . z)]); } else { if(step > numsteps) step--; offset += step*numverts; normals[0] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . x)]); normals[1] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . y)]); normals[2] = float4_to_float3(kg->__attributes_float3[offset + as_int(tri_vindex . z)]); } } void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3]) { int numsteps, numverts; object_motion_info(kg, object, &numsteps, &numverts, 0); int maxstep = numsteps*2; int step = min((int)(time*maxstep), maxstep-1); float t = time*maxstep - step; AttributeElement elem; int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); ; float3 next_verts[3]; float3 tri_vindex = float4_to_float3(kg->__tri_vindex[prim]); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts); verts[0] = (1.0f - t)*verts[0] + t*next_verts[0]; verts[1] = (1.0f - t)*verts[1] + t*next_verts[1]; verts[2] = (1.0f - t)*verts[2] + t*next_verts[2]; } float3 motion_triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, float3 verts[3]) { float3 P = ray->P; float3 D = ray->D; float t = isect->t; if(isect->object != (~0)) { if((t == 0.0f)) { return P; } Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); P = transform_point(&tfm, P); D = transform_direction(&tfm, D*t); D = normalize_len(D, &t); } P = P + D*t; const float3 e1 = verts[0] - verts[2]; const float3 e2 = verts[1] - verts[2]; const float3 s1 = cross(D, e2); const float invdivisor = 1.0f/dot(s1, e1); const float3 d = P - verts[2]; const float3 s2 = cross(d, e1); float rt = dot(e2, s2)*invdivisor; P = P + D*rt; if(isect->object != (~0)) { Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); P = transform_point(&tfm, P); } return P; } #line 24234 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void motion_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface) { (sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__tri_shader[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; int numsteps, numverts; object_motion_info(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &numsteps, &numverts, 0); int maxstep = numsteps*2; int step = min((int)((sd->time[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*maxstep), maxstep-1); float t = (sd->time[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*maxstep - step; AttributeElement elem; int offset = find_attribute_motion(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), ATTR_STD_MOTION_VERTEX_POSITION, &elem); ; float3 verts[3], next_verts[3]; float3 tri_vindex = float4_to_float3(kg->__tri_vindex[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts); verts[0] = (1.0f - t)*verts[0] + t*next_verts[0]; verts[1] = (1.0f - t)*verts[1] + t*next_verts[1]; verts[2] = (1.0f - t)*verts[2] + t*next_verts[2]; (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = motion_triangle_refine(kg, sd, isect, ray, verts); float3 Ng; if((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_NEGATIVE_SCALE_APPLIED) Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0])); else Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0])); (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (verts[0] - verts[2]); (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (verts[1] - verts[2]); if((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_SMOOTH_NORMAL) { AttributeElement elem; int offset = find_attribute_motion(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), ATTR_STD_MOTION_VERTEX_NORMAL, &elem); ; float3 normals[3], next_normals[3]; motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals); motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_normals); normals[0] = (1.0f - t)*normals[0] + t*next_normals[0]; normals[1] = (1.0f - t)*normals[1] + t*next_normals[1]; normals[2] = (1.0f - t)*normals[2] + t*next_normals[2]; float u = (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float v = (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float w = 1.0f - u - v; (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (u*normals[0] + v*normals[1] + w*normals[2]); } } bool motion_triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 dir, float time, uint visibility, int object, int triAddr) { int prim = kg->__prim_index[triAddr]; int fobject = (object == (~0))? kg->__prim_object[triAddr]: object; float3 verts[3]; motion_triangle_vertices(kg, fobject, prim, time, verts); float t, u, v; if(ray_triangle_intersect_uv(P, dir, isect->t, verts[2], verts[0], verts[1], &u, &v, &t)) { if(kg->__prim_visibility[triAddr] & visibility) { isect->t = t; isect->u = u; isect->v = v; isect->prim = triAddr; isect->object = object; isect->type = PRIMITIVE_MOTION_TRIANGLE; return 1; } } return 0; } #line 24407 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 24563 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 25595 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 25689 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) { if((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_ALL_TRIANGLE) { return triangle_attribute_float(kg, sd, elem, offset, dx, dy); } #line 25735 "C:\\cygwin64\\tmp\\OCL6424T10.cl" else { if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; return 0.0f; } } float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) { if((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_ALL_TRIANGLE) { return triangle_attribute_float3(kg, sd, elem, offset, dx, dy); } #line 25757 "C:\\cygwin64\\tmp\\OCL6424T10.cl" else { if(dx) *dx = ((float3)(0.0f, 0.0f, 0.0f)); if(dy) *dy = ((float3)(0.0f, 0.0f, 0.0f)); return ((float3)(0.0f, 0.0f, 0.0f)); } } float3 primitive_uv(KernelGlobals *kg, ShaderData *sd) { AttributeElement elem_uv; int offset_uv = find_attribute(kg, sd, ATTR_STD_UV, &elem_uv); if(offset_uv == ATTR_STD_NOT_FOUND) return ((float3)(0.0f, 0.0f, 0.0f)); float3 uv = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, 0, 0); uv.z = 1.0f; return uv; } bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id) { AttributeElement elem_face_id, elem_uv; int offset_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID, &elem_face_id); int offset_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV, &elem_uv); if(offset_face_id == ATTR_STD_NOT_FOUND || offset_uv == ATTR_STD_NOT_FOUND) return 0; float3 uv3 = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, 0, 0); float face_id_f = primitive_attribute_float(kg, sd, elem_face_id, offset_face_id, 0, 0); *uv = ((float2)(uv3 . x, uv3 . y)); *face_id = (int)face_id_f; return 1; } float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd) { #line 25812 "C:\\cygwin64\\tmp\\OCL6424T10.cl" AttributeElement attr_elem; int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED, &attr_elem); if(attr_offset != ATTR_STD_NOT_FOUND) { float3 data = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, 0, 0); data = ((float3)(-(data . y - 0.5f), (data . x - 0.5f), 0.0f)); object_normal_transform(kg, sd, &data); return cross((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), normalize(cross(data, (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])))); } else { return normalize((sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } } float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd) { float3 center; #line 25850 "C:\\cygwin64\\tmp\\OCL6424T10.cl" center = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float3 motion_pre = center, motion_post = center; AttributeElement elem; int offset = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION, &elem); if(offset != ATTR_STD_NOT_FOUND) { int numverts, numkeys; object_motion_info(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), 0, &numverts, &numkeys); int offset_next = ((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_ALL_TRIANGLE)? offset + numverts: offset + numkeys; motion_pre = primitive_attribute_float3(kg, sd, elem, offset, 0, 0); motion_post = primitive_attribute_float3(kg, sd, elem, offset_next, 0, 0); #line 25875 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } Transform tfm; tfm = object_fetch_vector_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_VECTOR_MOTION_PRE); motion_pre = transform_point(&tfm, motion_pre); tfm = object_fetch_vector_transform(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), OBJECT_VECTOR_MOTION_POST); motion_post = transform_point(&tfm, motion_post); float3 motion_center; if((*kg->data).cam.type != CAMERA_PANORAMA) { tfm = (*kg->data).cam.worldtoraster; motion_center = transform_perspective(&tfm, center); tfm = (*kg->data).cam.motion.pre; motion_pre = transform_perspective(&tfm, motion_pre); tfm = (*kg->data).cam.motion.post; motion_post = transform_perspective(&tfm, motion_post); } else { tfm = (*kg->data).cam.worldtocamera; motion_center = normalize(transform_point(&tfm, center)); motion_center = float2_to_float3(direction_to_panorama(kg, motion_center)); motion_center.x *= (*kg->data).cam.width; motion_center.y *= (*kg->data).cam.height; tfm = (*kg->data).cam.motion.pre; motion_pre = normalize(transform_point(&tfm, motion_pre)); motion_pre = float2_to_float3(direction_to_panorama(kg, motion_pre)); motion_pre.x *= (*kg->data).cam.width; motion_pre.y *= (*kg->data).cam.height; tfm = (*kg->data).cam.motion.post; motion_post = normalize(transform_point(&tfm, motion_post)); motion_post = float2_to_float3(direction_to_panorama(kg, motion_post)); motion_post.x *= (*kg->data).cam.width; motion_post.y *= (*kg->data).cam.height; } motion_pre = motion_pre - motion_center; motion_post = motion_center - motion_post; return ((float4)(motion_pre . x, motion_pre . y, motion_post . x, motion_post . y)); } #line 26135 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 26590 "C:\\cygwin64\\tmp\\OCL6424T10.cl" bool BVH_bvh_intersect(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility ) { int traversalStack[192]; traversalStack[0] = 0x76543210; int stackPtr = 0; int nodeAddr = (*kg->data).bvh.root; float3 P = ray->P; float3 dir = bvh_clamp_direction(ray->D); float3 idir = bvh_inverse_direction(dir); int object = (~0); isect->t = ray->t; isect->u = 0.0f; isect->v = 0.0f; isect->prim = (~0); isect->object = (~0); #line 26665 "C:\\cygwin64\\tmp\\OCL6424T10.cl" IsectPrecalc isect_precalc; triangle_intersect_precalc(dir, &isect_precalc); do { do { while(nodeAddr >= 0 && nodeAddr != 0x76543210) { bool traverseChild0, traverseChild1; int nodeAddrChild1; float t = isect->t; float4 node0 = kg->__bvh_nodes[nodeAddr*4+0]; float4 node1 = kg->__bvh_nodes[nodeAddr*4+1]; float4 node2 = kg->__bvh_nodes[nodeAddr*4+2]; float4 cnodes = kg->__bvh_nodes[nodeAddr*4+3]; float c0lox = (node0.x - P.x) * idir.x; float c0hix = (node0.z - P.x) * idir.x; float c0loy = (node1.x - P.y) * idir.y; float c0hiy = (node1.z - P.y) * idir.y; float c0loz = (node2.x - P.z) * idir.z; float c0hiz = (node2.z - P.z) * idir.z; float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f); float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t); float c1lox = (node0.y - P.x) * idir.x; float c1hix = (node0.w - P.x) * idir.x; float c1loy = (node1.y - P.y) * idir.y; float c1hiy = (node1.w - P.y) * idir.y; float c1loz = (node2.y - P.z) * idir.z; float c1hiz = (node2.w - P.z) * idir.z; float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f); float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t); #line 26720 "C:\\cygwin64\\tmp\\OCL6424T10.cl" traverseChild0 = (c0max >= c0min) && (as_uint(cnodes . z) & visibility); traverseChild1 = (c1max >= c1min) && (as_uint(cnodes . w) & visibility); #line 26778 "C:\\cygwin64\\tmp\\OCL6424T10.cl" nodeAddr = as_int(cnodes . x); nodeAddrChild1 = as_int(cnodes . y); if(traverseChild0 && traverseChild1) { bool closestChild1 = (c1min < c0min); if(closestChild1) { int tmp = nodeAddr; nodeAddr = nodeAddrChild1; nodeAddrChild1 = tmp; } ++stackPtr; ; traversalStack[stackPtr] = nodeAddrChild1; } else { if(traverseChild1) { nodeAddr = nodeAddrChild1; } else if(!traverseChild0) { nodeAddr = traversalStack[stackPtr]; --stackPtr; } } } if(nodeAddr < 0) { float4 leaf = kg->__bvh_leaf_nodes[(-nodeAddr-1)*1]; int primAddr = as_int(leaf . x); const int primAddr2 = as_int(leaf . y); const uint type = as_int(leaf . w); nodeAddr = traversalStack[stackPtr]; --stackPtr; switch(type & PRIMITIVE_ALL) { case PRIMITIVE_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { ; if(triangle_intersect(kg, &isect_precalc, isect, P, visibility, object, primAddr)) { if(visibility == PATH_RAY_SHADOW_OPAQUE) return 1; } } break; } #line 26904 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } } #line 26940 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } while(nodeAddr != 0x76543210); #line 26969 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } while(nodeAddr != 0x76543210); return (isect->prim != (~0)); } bool bvh_intersect(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility ) { #line 27000 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { ; return BVH_bvh_intersect(kg, ray, isect, visibility ); } } #line 27473 "C:\\cygwin64\\tmp\\OCL6424T10.cl" bool BVH_bvh_intersect_instancing(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility ) { int traversalStack[192]; traversalStack[0] = 0x76543210; int stackPtr = 0; int nodeAddr = (*kg->data).bvh.root; float3 P = ray->P; float3 dir = bvh_clamp_direction(ray->D); float3 idir = bvh_inverse_direction(dir); int object = (~0); isect->t = ray->t; isect->u = 0.0f; isect->v = 0.0f; isect->prim = (~0); isect->object = (~0); #line 27548 "C:\\cygwin64\\tmp\\OCL6424T10.cl" IsectPrecalc isect_precalc; triangle_intersect_precalc(dir, &isect_precalc); do { do { while(nodeAddr >= 0 && nodeAddr != 0x76543210) { bool traverseChild0, traverseChild1; int nodeAddrChild1; float t = isect->t; float4 node0 = kg->__bvh_nodes[nodeAddr*4+0]; float4 node1 = kg->__bvh_nodes[nodeAddr*4+1]; float4 node2 = kg->__bvh_nodes[nodeAddr*4+2]; float4 cnodes = kg->__bvh_nodes[nodeAddr*4+3]; float c0lox = (node0.x - P.x) * idir.x; float c0hix = (node0.z - P.x) * idir.x; float c0loy = (node1.x - P.y) * idir.y; float c0hiy = (node1.z - P.y) * idir.y; float c0loz = (node2.x - P.z) * idir.z; float c0hiz = (node2.z - P.z) * idir.z; float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f); float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t); float c1lox = (node0.y - P.x) * idir.x; float c1hix = (node0.w - P.x) * idir.x; float c1loy = (node1.y - P.y) * idir.y; float c1hiy = (node1.w - P.y) * idir.y; float c1loz = (node2.y - P.z) * idir.z; float c1hiz = (node2.w - P.z) * idir.z; float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f); float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t); #line 27603 "C:\\cygwin64\\tmp\\OCL6424T10.cl" traverseChild0 = (c0max >= c0min) && (as_uint(cnodes . z) & visibility); traverseChild1 = (c1max >= c1min) && (as_uint(cnodes . w) & visibility); #line 27661 "C:\\cygwin64\\tmp\\OCL6424T10.cl" nodeAddr = as_int(cnodes . x); nodeAddrChild1 = as_int(cnodes . y); if(traverseChild0 && traverseChild1) { bool closestChild1 = (c1min < c0min); if(closestChild1) { int tmp = nodeAddr; nodeAddr = nodeAddrChild1; nodeAddrChild1 = tmp; } ++stackPtr; ; traversalStack[stackPtr] = nodeAddrChild1; } else { if(traverseChild1) { nodeAddr = nodeAddrChild1; } else if(!traverseChild0) { nodeAddr = traversalStack[stackPtr]; --stackPtr; } } } if(nodeAddr < 0) { float4 leaf = kg->__bvh_leaf_nodes[(-nodeAddr-1)*1]; int primAddr = as_int(leaf . x); if(primAddr >= 0) { const int primAddr2 = as_int(leaf . y); const uint type = as_int(leaf . w); nodeAddr = traversalStack[stackPtr]; --stackPtr; switch(type & PRIMITIVE_ALL) { case PRIMITIVE_TRIANGLE: { for(; primAddr < primAddr2; primAddr++) { ; if(triangle_intersect(kg, &isect_precalc, isect, P, visibility, object, primAddr)) { if(visibility == PATH_RAY_SHADOW_OPAQUE) return 1; } } break; } #line 27787 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } } else { object = kg->__prim_object[-primAddr-1]; bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); triangle_intersect_precalc(dir, &isect_precalc); #line 27810 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ++stackPtr; ; traversalStack[stackPtr] = 0x76543210; nodeAddr = kg->__object_node[object]; } } } while(nodeAddr != 0x76543210); if(stackPtr >= 0) { ; bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); triangle_intersect_precalc(dir, &isect_precalc); #line 27846 "C:\\cygwin64\\tmp\\OCL6424T10.cl" object = (~0); nodeAddr = traversalStack[stackPtr]; --stackPtr; } } while(nodeAddr != 0x76543210); return (isect->prim != (~0)); } bool bvh_intersect_instancing(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility ) { #line 27883 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { ; return BVH_bvh_intersect_instancing(kg, ray, isect, visibility ); } } #line 28787 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 29671 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 30555 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 31231 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 31905 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 32579 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 33253 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 33927 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 34648 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 35367 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 36086 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 36805 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 37524 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 38351 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 39176 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 40001 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 40826 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 41651 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 42563 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 43473 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 44383 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 45293 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 46203 "C:\\cygwin64\\tmp\\OCL6424T10.cl" bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax) { #line 46222 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 46237 "C:\\cygwin64\\tmp\\OCL6424T10.cl" return bvh_intersect_instancing(kg, ray, isect, visibility); } #line 46285 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 46313 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 46354 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 46385 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 ray_offset(float3 P, float3 Ng) { const float epsilon_f = 1e-5f; const float epsilon_test = 1.0f; const int epsilon_i = 32; float3 res; if(fabs(((float)(P . x))) < epsilon_test) { res.x = P.x + Ng.x*epsilon_f; } else { uint ix = as_uint(P . x); ix += ((ix ^ as_uint(Ng . x)) >> 31)? -epsilon_i: epsilon_i; res.x = as_float(ix); } if(fabs(((float)(P . y))) < epsilon_test) { res.y = P.y + Ng.y*epsilon_f; } else { uint iy = as_uint(P . y); iy += ((iy ^ as_uint(Ng . y)) >> 31)? -epsilon_i: epsilon_i; res.y = as_float(iy); } if(fabs(((float)(P . z))) < epsilon_test) { res.z = P.z + Ng.z*epsilon_f; } else { uint iz = as_uint(P . z); iz += ((iz ^ as_uint(Ng . z)) >> 31)? -epsilon_i: epsilon_i; res.z = as_float(iz); } return res; } #line 46455 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass) { eval->use_light_pass = use_light_pass; if(eval->use_light_pass) { eval->diffuse = ((float3)(0.0f, 0.0f, 0.0f)); eval->glossy = ((float3)(0.0f, 0.0f, 0.0f)); eval->transmission = ((float3)(0.0f, 0.0f, 0.0f)); eval->transparent = ((float3)(0.0f, 0.0f, 0.0f)); eval->subsurface = ((float3)(0.0f, 0.0f, 0.0f)); eval->scatter = ((float3)(0.0f, 0.0f, 0.0f)); if(type == CLOSURE_BSDF_TRANSPARENT_ID) eval->transparent = value; else if((type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)) eval->diffuse = value; else if((type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)) eval->glossy = value; else if((type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)) eval->transmission = value; else if((type == CLOSURE_BSDF_BSSRDF_ID)) eval->subsurface = value; else if((type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)) eval->scatter = value; } else eval->diffuse = value; } void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value) { if(eval->use_light_pass) { if((type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)) eval->diffuse += value; else if((type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)) eval->glossy += value; else if((type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)) eval->transmission += value; else if((type == CLOSURE_BSDF_BSSRDF_ID)) eval->subsurface += value; else if((type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)) eval->scatter += value; } else eval->diffuse += value; } bool bsdf_eval_is_zero(BsdfEval *eval) { if(eval->use_light_pass) { return is_zero(eval->diffuse) && is_zero(eval->glossy) && is_zero(eval->transmission) && is_zero(eval->transparent) && is_zero(eval->subsurface) && is_zero(eval->scatter); } else return is_zero(eval->diffuse); } void bsdf_eval_mul(BsdfEval *eval, float3 value) { if(eval->use_light_pass) { eval->diffuse *= value; eval->glossy *= value; eval->transmission *= value; eval->subsurface *= value; eval->scatter *= value; } else eval->diffuse *= value; } void path_radiance_init(PathRadiance *L, int use_light_pass) { L->use_light_pass = use_light_pass; if(use_light_pass) { L->indirect = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_throughput = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_emission = ((float3)(0.0f, 0.0f, 0.0f)); L->color_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->color_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->color_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->color_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->color_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->path_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->path_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->path_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->path_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->path_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->emission = ((float3)(0.0f, 0.0f, 0.0f)); L->background = ((float3)(0.0f, 0.0f, 0.0f)); L->ao = ((float3)(0.0f, 0.0f, 0.0f)); L->shadow = ((float4)(0.0f, 0.0f, 0.0f, 0.0f)); L->mist = 0.0f; } else L->emission = ((float3)(0.0f, 0.0f, 0.0f)); } void path_radiance_bsdf_bounce(PathRadiance *L, __global float3 *throughput, BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label) { float inverse_pdf = 1.0f/bsdf_pdf; if(L->use_light_pass) { if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) { float3 value = *throughput*inverse_pdf; L->path_diffuse = bsdf_eval->diffuse*value; L->path_glossy = bsdf_eval->glossy*value; L->path_transmission = bsdf_eval->transmission*value; L->path_subsurface = bsdf_eval->subsurface*value; L->path_scatter = bsdf_eval->scatter*value; *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter; L->direct_throughput = *throughput; } else { float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent + bsdf_eval->subsurface + bsdf_eval->scatter) * inverse_pdf; *throughput *= sum; } } else *throughput *= bsdf_eval->diffuse*inverse_pdf; } void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce) { if(L->use_light_pass) { if(bounce == 0) L->emission += throughput*value; else if(bounce == 1) L->direct_emission += throughput*value; else L->indirect += throughput*value; } else L->emission += throughput*value; } void path_radiance_accum_ao(PathRadiance *L, float3 throughput, float3 alpha, float3 bsdf, float3 ao, int bounce) { if(L->use_light_pass) { if(bounce == 0) { L->direct_diffuse += throughput*bsdf*ao; L->ao += alpha*throughput*ao; } else { L->indirect += throughput*bsdf*ao; } } else L->emission += throughput*bsdf*ao; } void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, float shadow_fac, int bounce, bool is_lamp) { if(L->use_light_pass) { if(bounce == 0) { L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow; L->direct_glossy += throughput*bsdf_eval->glossy*shadow; L->direct_transmission += throughput*bsdf_eval->transmission*shadow; L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow; L->direct_scatter += throughput*bsdf_eval->scatter*shadow; if(is_lamp) { L->shadow.x += shadow.x*shadow_fac; L->shadow.y += shadow.y*shadow_fac; L->shadow.z += shadow.z*shadow_fac; } } else { float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->subsurface + bsdf_eval->scatter; L->indirect += throughput*sum*shadow; } } else L->emission += throughput*bsdf_eval->diffuse*shadow; } void path_radiance_accum_background(PathRadiance *L, float3 throughput, float3 value, int bounce) { if(L->use_light_pass) { if(bounce == 0) L->background += throughput*value; else if(bounce == 1) L->direct_emission += throughput*value; else L->indirect += throughput*value; } else L->emission += throughput*value; } void path_radiance_sum_indirect(PathRadiance *L) { if(L->use_light_pass) { L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); L->direct_diffuse += L->path_diffuse*L->direct_emission; L->direct_glossy += L->path_glossy*L->direct_emission; L->direct_transmission += L->path_transmission*L->direct_emission; L->direct_subsurface += L->path_subsurface*L->direct_emission; L->direct_scatter += L->path_scatter*L->direct_emission; L->indirect = safe_divide_color(L->indirect, L->direct_throughput); L->indirect_diffuse += L->path_diffuse*L->indirect; L->indirect_glossy += L->path_glossy*L->indirect; L->indirect_transmission += L->path_transmission*L->indirect; L->indirect_subsurface += L->path_subsurface*L->indirect; L->indirect_scatter += L->path_scatter*L->indirect; } } void path_radiance_reset_indirect(PathRadiance *L) { if(L->use_light_pass) { L->path_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->path_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->path_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->path_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->path_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_emission = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect = ((float3)(0.0f, 0.0f, 0.0f)); } } float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L) { float3 L_sum; float3 L_direct, L_indirect; float clamp_direct = (*kg->data).integrator.sample_clamp_direct; float clamp_indirect = (*kg->data).integrator.sample_clamp_indirect; if(L->use_light_pass) { path_radiance_sum_indirect(L); L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission; L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter; if(!(*kg->data).background.transparent) L_direct += L->background; L_sum = L_direct + L_indirect; float sum = fabs(((float)((L_sum). x))) + fabs(((float)((L_sum). y))) + fabs(((float)((L_sum). z))); if(!isfinite(sum)) { L_sum = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->direct_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_diffuse = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_glossy = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_transmission = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_subsurface = ((float3)(0.0f, 0.0f, 0.0f)); L->indirect_scatter = ((float3)(0.0f, 0.0f, 0.0f)); L->emission = ((float3)(0.0f, 0.0f, 0.0f)); } else if(sum > clamp_direct || sum > clamp_indirect) { float scale; float sum_direct = fabs(((float)(L_direct . x))) + fabs(((float)(L_direct . y))) + fabs(((float)(L_direct . z))); if(sum_direct > clamp_direct) { scale = clamp_direct/sum_direct; L_direct *= scale; L->direct_diffuse *= scale; L->direct_glossy *= scale; L->direct_transmission *= scale; L->direct_subsurface *= scale; L->direct_scatter *= scale; L->emission *= scale; L->background *= scale; } float sum_indirect = fabs(((float)(L_indirect . x))) + fabs(((float)(L_indirect . y))) + fabs(((float)(L_indirect . z))); if(sum_indirect > clamp_indirect) { scale = clamp_indirect/sum_indirect; L_indirect *= scale; L->indirect_diffuse *= scale; L->indirect_glossy *= scale; L->indirect_transmission *= scale; L->indirect_subsurface *= scale; L->indirect_scatter *= scale; } L_sum = L_direct + L_indirect; } return L_sum; } else L_sum = L->emission; float sum = fabs(((float)((L_sum). x))) + fabs(((float)((L_sum). y))) + fabs(((float)((L_sum). z))); if(!isfinite(sum)) L_sum = ((float3)(0.0f, 0.0f, 0.0f)); return L_sum; } void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples) { float fac = 1.0f/num_samples; L->direct_diffuse += L_sample->direct_diffuse*fac; L->direct_glossy += L_sample->direct_glossy*fac; L->direct_transmission += L_sample->direct_transmission*fac; L->direct_subsurface += L_sample->direct_subsurface*fac; L->direct_scatter += L_sample->direct_scatter*fac; L->indirect_diffuse += L_sample->indirect_diffuse*fac; L->indirect_glossy += L_sample->indirect_glossy*fac; L->indirect_transmission += L_sample->indirect_transmission*fac; L->indirect_subsurface += L_sample->indirect_subsurface*fac; L->indirect_scatter += L_sample->indirect_scatter*fac; L->emission += L_sample->emission*fac; L->background += L_sample->background*fac; L->ao += L_sample->ao*fac; L->shadow += L_sample->shadow*fac; L->mist += L_sample->mist*fac; } float fresnel_dielectric( float eta, const float3 N, const float3 I, float3 *R, float3 *T, const float3 dIdx, const float3 dIdy, float3 *dRdx, float3 *dRdy, float3 *dTdx, float3 *dTdy, bool *is_inside) { float cos = dot(N, I), neta; float3 Nn; if(cos > 0) { neta = 1 / eta; Nn = N; *is_inside = 0; } else { cos = -cos; neta = eta; Nn = -N; *is_inside = 1; } *R = (2 * cos)* Nn - I; *dRdx = (2 * dot(Nn, dIdx)) * Nn - dIdx; *dRdy = (2 * dot(Nn, dIdy)) * Nn - dIdy; float arg = 1 -(neta * neta *(1 -(cos * cos))); if(arg < 0) { *T = ((float3)(0.0f, 0.0f, 0.0f)); *dTdx = ((float3)(0.0f, 0.0f, 0.0f)); *dTdy = ((float3)(0.0f, 0.0f, 0.0f)); return 1; } else { float dnp = native_sqrt(((float)(arg))); float nK = (neta * cos)- dnp; *T = -(neta * I)+(nK * Nn); *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; float cosTheta1 = cos; float cosTheta2 = -dot(Nn, *T); float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); return 0.5f * (pPara * pPara + pPerp * pPerp); } } float fresnel_dielectric_cos(float cosi, float eta) { float c = fabs(((float)(cosi))); float g = eta * eta - 1 + c * c; if(g > 0) { g = native_sqrt(((float)(g))); float A = (g - c)/(g + c); float B = (c *(g + c)- 1)/(c *(g - c)+ 1); return 0.5f * A * A *(1 + B * B); } return 1.0f; } #line 47087 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float smooth_step(float edge0, float edge1, float x) { float result; if(x < edge0) result = 0.0f; else if(x >= edge1) result = 1.0f; else { float t = (x - edge0)/(edge1 - edge0); result = (3.0f-2.0f*t)*(t*t); } return result; } int bsdf_ashikhmin_velvet_setup(ShaderClosure *sc) { float sigma = fmax(((float)(sc->data0)), ((float)(0.01f))); sc->data0 = 1.0f/(sigma * sigma); sc->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invsigma2 = sc->data0; float3 N = sc->N; float cosNO = dot(N, I); float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float3 H = normalize(omega_in + I); float cosNH = dot(N, H); float cosHO = fabs(((float)(dot(I, H)))); if(!(fabs(((float)(cosNH))) < 1.0f-1e-5f && cosHO > 1e-5f)) return ((float3)(0.0f, 0.0f, 0.0f)); float cosNHdivHO = cosNH / cosHO; cosNHdivHO = fmax(((float)(cosNHdivHO)), ((float)(1e-5f))); float fac1 = 2 * fabs(((float)(cosNHdivHO * cosNO))); float fac2 = 2 * fabs(((float)(cosNHdivHO * cosNI))); float sinNH2 = 1 - cosNH * cosNH; float sinNH4 = sinNH2 * sinNH2; float cotangent2 = (cosNH * cosNH) / sinNH2; float D = native_exp(((float)(-cotangent2 * m_invsigma2))) * m_invsigma2 * 0.31830987334251f / sinNH4; float G = min(1.0f, min(fac1, fac2)); float out = 0.25f * (D * G) / cosNO; *pdf = 0.5f * 0.31830987334251f; return ((float3)(out, out, out)); } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_invsigma2 = sc->data0; float3 N = sc->N; sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0) { float3 H = normalize(*omega_in + I); float cosNI = dot(N, *omega_in); float cosNO = dot(N, I); float cosNH = dot(N, H); float cosHO = fabs(((float)(dot(I, H)))); if(fabs(((float)(cosNO))) > 1e-5f && fabs(((float)(cosNH))) < 1.0f-1e-5f && cosHO > 1e-5f) { float cosNHdivHO = cosNH / cosHO; cosNHdivHO = fmax(((float)(cosNHdivHO)), ((float)(1e-5f))); float fac1 = 2 * fabs(((float)(cosNHdivHO * cosNO))); float fac2 = 2 * fabs(((float)(cosNHdivHO * cosNI))); float sinNH2 = 1 - cosNH * cosNH; float sinNH4 = sinNH2 * sinNH2; float cotangent2 = (cosNH * cosNH) / sinNH2; float D = native_exp(((float)(-cotangent2 * m_invsigma2))) * m_invsigma2 * 0.31830987334251f / sinNH4; float G = min(1.0f, min(fac1, fac2)); float power = 0.25f * (D * G) / cosNO; *eval = ((float3)(power, power, power)); *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; } else *pdf = 0.0f; } else *pdf = 0.0f; return LABEL_REFLECT|LABEL_DIFFUSE; } int bsdf_diffuse_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float3 N = sc->N; float cos_pi = fmax(((float)(dot(N, omega_in))), ((float)(0.0f))) * 0.31830987334251f; *pdf = cos_pi; return ((float3)(cos_pi, cos_pi, cos_pi)); } float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float3 N = sc->N; sample_cos_hemisphere(N, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0.0f) { *eval = ((float3)(*pdf, *pdf, *pdf)); *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; } else *pdf = 0.0f; return LABEL_REFLECT|LABEL_DIFFUSE; } int bsdf_translucent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSLUCENT_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float3 N = sc->N; float cos_pi = fmax(((float)(-dot(N, omega_in))), ((float)(0.0f))) * 0.31830987334251f; *pdf = cos_pi; return ((float3)(cos_pi, cos_pi, cos_pi)); } int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float3 N = sc->N; sample_cos_hemisphere (-N, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) < 0) { *eval = ((float3)(*pdf, *pdf, *pdf)); *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); } else { *pdf = 0; } return LABEL_TRANSMIT|LABEL_DIFFUSE; } float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l) { float nl = max(dot(n, l), 0.0f); float nv = max(dot(n, v), 0.0f); float t = dot(l, v) - nl * nv; if(t > 0.0f) t /= max(nl, nv) + 0x1.0p-126f; float is = nl * (sc->data0 + sc->data1 * t); return ((float3)(is, is, is)); } int bsdf_oren_nayar_setup(ShaderClosure *sc) { float sigma = sc->data0; sc->type = CLOSURE_BSDF_OREN_NAYAR_ID; sigma = saturate(sigma); float div = 1.0f / (3.14159274101257f + ((3.0f * 3.14159274101257f - 4.0f) / 6.0f) * sigma); sc->data0 = 1.0f * div; sc->data1 = sigma * div; return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { if(dot(sc->N, omega_in) > 0.0f) { *pdf = 0.5f * 0.31830987334251f; return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in); } else { *pdf = 0.0f; return ((float3)(0.0f, 0.0f, 0.0f)); } } float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0.0f) { *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in); *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx; *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy; } else { *pdf = 0.0f; *eval = ((float3)(0.0f, 0.0f, 0.0f)); } return LABEL_REFLECT|LABEL_DIFFUSE; } float3 bsdf_phong_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos) { int MAXCOLORS = 8; float npos = pos * (float)(MAXCOLORS - 1); int ipos = float_to_int(npos); if(ipos < 0) return colors[0]; if(ipos >= (MAXCOLORS - 1)) return colors[MAXCOLORS - 1]; float offset = npos - (float)ipos; return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset; } int bsdf_phong_ramp_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_PHONG_RAMP_ID; sc->data0 = max(sc->data0, 0.0f); sc->data1 = 0.0f; return SD_BSDF|SD_BSDF_HAS_EVAL; } void bsdf_phong_ramp_blur(ShaderClosure *sc, float roughness) { } float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) { float m_exponent = sc->data0; float cosNI = dot(sc->N, omega_in); float cosNO = dot(sc->N, I); if(cosNI > 0 && cosNO > 0) { float3 R = (2 * cosNO) * sc->N - I; float cosRI = dot(R, omega_in); if(cosRI > 0) { float cosp = pow(((float)(cosRI)), ((float)(m_exponent))); float common = 0.5f * 0.31830987334251f * cosp; float out = cosNI * (m_exponent + 2) * common; *pdf = (m_exponent + 1) * common; return bsdf_phong_ramp_get_color(sc, colors, cosp) * out; } } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_phong_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors[8], float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float cosNO = dot(sc->N, I); float m_exponent = sc->data0; if(cosNO > 0) { float3 R = (2 * cosNO) * sc->N - I; *domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx; *domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy; float3 T, B; make_orthonormals (R, &T, &B); float phi = ((float)6.283185307179586476925286766559005768) * randu; float cosTheta = pow(((float)(randv)), ((float)(1 / (m_exponent + 1)))); float sinTheta2 = 1 - cosTheta * cosTheta; float sinTheta = sinTheta2 > 0 ? native_sqrt(((float)(sinTheta2))) : 0; *omega_in = (native_cos(((float)(phi))) * sinTheta) * T + (native_sin(((float)(phi))) * sinTheta) * B + ( cosTheta) * R; if(dot(Ng, *omega_in) > 0.0f) { float cosNI = dot(sc->N, *omega_in); if(cosNI > 0) { float cosp = pow(((float)(cosTheta)), ((float)(m_exponent))); float common = 0.5f * 0.31830987334251f * cosp; *pdf = (m_exponent + 1) * common; float out = cosNI * (m_exponent + 2) * common; *eval = bsdf_phong_ramp_get_color(sc, colors, cosp) * out; } } } return LABEL_REFLECT|LABEL_GLOSSY; } float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos) { int MAXCOLORS = 8; float npos = pos * (float)(MAXCOLORS - 1); int ipos = float_to_int(npos); if(ipos < 0) return colors[0]; if(ipos >= (MAXCOLORS - 1)) return colors[MAXCOLORS - 1]; float offset = npos - (float)ipos; return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset; } int bsdf_diffuse_ramp_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID; sc->data0 = 0.0f; sc->data1 = 0.0f; return SD_BSDF|SD_BSDF_HAS_EVAL; } void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness) { } float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) { float3 N = sc->N; float cos_pi = fmax(((float)(dot(N, omega_in))), ((float)(0.0f))); *pdf = cos_pi * 0.31830987334251f; return bsdf_diffuse_ramp_get_color(sc, colors, cos_pi) * 0.31830987334251f; } float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_diffuse_ramp_sample(const ShaderClosure *sc, const float3 colors[8], float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float3 N = sc->N; sample_cos_hemisphere(N, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0.0f) { *eval = bsdf_diffuse_ramp_get_color(sc, colors, *pdf * 3.14159274101257f) * 0.31830987334251f; *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; } else *pdf = 0.0f; return LABEL_REFLECT|LABEL_DIFFUSE; } void microfacet_beckmann_sample_slopes( KernelGlobals *kg, const float cos_theta_i, const float sin_theta_i, float randu, float randv, float *slope_x, float *slope_y, float *G1i) { if(cos_theta_i >= 0.99999f) { const float r = native_sqrt(((float)(-native_log(((float)(randu)))))); const float phi = ((float)6.283185307179586476925286766559005768) * randv; *slope_x = r * native_cos(((float)(phi))); *slope_y = r * native_sin(((float)(phi))); *G1i = 1.0f; return; } const float tan_theta_i = sin_theta_i/cos_theta_i; const float inv_a = tan_theta_i; const float cot_theta_i = 1.0f/tan_theta_i; const float erf_a = fast_erff(cot_theta_i); const float exp_a2 = native_exp(((float)(-cot_theta_i*cot_theta_i))); const float SQRT_PI_INV = 0.56418958354f; const float Lambda = 0.5f*(erf_a - 1.0f) + (0.5f*SQRT_PI_INV)*(exp_a2*inv_a); const float G1 = 1.0f/(1.0f + Lambda); *G1i = G1; float K = tan_theta_i * SQRT_PI_INV; float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); float y_exact = randu * (1.0f + erf_a + K * exp_a2); float b = K > 0 ? (0.5f - native_sqrt(((float)(K * (K - y_approx + 1.0f) + 0.25f)))) / K : y_approx - 1.0f; float inv_erf = fast_ierff(b); float value = 1.0f + b + K * native_exp(((float)(-inv_erf * inv_erf))) - y_exact; if(fabs(((float)(value))) > 1e-6f) { b -= value / (1.0f - inv_erf * tan_theta_i); inv_erf = fast_ierff(b); value = 1.0f + b + K * native_exp(((float)(-inv_erf * inv_erf))) - y_exact; b -= value / (1.0f - inv_erf * tan_theta_i); *slope_x = fast_ierff(b); } else { *slope_x = inv_erf; } *slope_y = fast_ierff(2.0f*randv - 1.0f); #line 47851 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } void microfacet_ggx_sample_slopes( const float cos_theta_i, const float sin_theta_i, float randu, float randv, float *slope_x, float *slope_y, float *G1i) { if(cos_theta_i >= 0.99999f) { const float r = native_sqrt(((float)(randu/(1.0f - randu)))); const float phi = ((float)6.283185307179586476925286766559005768) * randv; *slope_x = r * native_cos(((float)(phi))); *slope_y = r * native_sin(((float)(phi))); *G1i = 1.0f; return; } const float tan_theta_i = sin_theta_i/cos_theta_i; const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i*tan_theta_i)); *G1i = 1.0f/G1_inv; const float A = 2.0f*randu*G1_inv - 1.0f; const float AA = A*A; const float tmp = 1.0f/(AA - 1.0f); const float B = tan_theta_i; const float BB = B*B; const float D = safe_sqrtf(BB*(tmp*tmp) - (AA - BB)*tmp); const float slope_x_1 = B*tmp - D; const float slope_x_2 = B*tmp + D; *slope_x = (A < 0.0f || slope_x_2*tan_theta_i > 1.0f)? slope_x_1: slope_x_2; float S; if(randv > 0.5f) { S = 1.0f; randv = 2.0f*(randv - 0.5f); } else { S = -1.0f; randv = 2.0f*(0.5f - randv); } const float z = (randv*(randv*(randv*0.27385f - 0.73369f) + 0.46341f)) / (randv*(randv*(randv*0.093073f + 0.309420f) - 1.000000f) + 0.597999f); *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x)*(*slope_x)); } float3 microfacet_sample_stretched( KernelGlobals *kg, const float3 omega_i, const float alpha_x, const float alpha_y, const float randu, const float randv, bool beckmann, float *G1i) { float3 omega_i_ = ((float3)(alpha_x * omega_i . x, alpha_y * omega_i . y, omega_i . z)); omega_i_ = normalize(omega_i_); float costheta_ = 1.0f; float sintheta_ = 0.0f; float cosphi_ = 1.0f; float sinphi_ = 0.0f; if(omega_i_.z < 0.99999f) { costheta_ = omega_i_.z; sintheta_ = safe_sqrtf(1.0f - costheta_*costheta_); float invlen = 1.0f/sintheta_; cosphi_ = omega_i_.x * invlen; sinphi_ = omega_i_.y * invlen; } float slope_x, slope_y; if(beckmann) { microfacet_beckmann_sample_slopes(kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); } else { microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); } float tmp = cosphi_*slope_x - sinphi_*slope_y; slope_y = sinphi_*slope_x + cosphi_*slope_y; slope_x = tmp; slope_x = alpha_x * slope_x; slope_y = alpha_y * slope_y; return normalize(((float3)(-slope_x, -slope_y, 1.0f))); } int bsdf_microfacet_ggx_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = sc->data0; sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = saturate(sc->data1); sc->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = sc->data0; sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) { sc->data0 = fmax(((float)(roughness)), ((float)(sc->data0))); sc->data1 = fmax(((float)(roughness)), ((float)(sc->data1))); } float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; float3 N = sc->N; if(m_refractive || fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) return ((float3)(0.0f, 0.0f, 0.0f)); float cosNO = dot(N, I); float cosNI = dot(N, omega_in); if(cosNI > 0 && cosNO > 0) { float3 m = normalize(omega_in + I); float alpha2 = alpha_x * alpha_y; float D, G1o, G1i; if(alpha_x == alpha_y) { float cosThetaM = dot(N, m); float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; D = alpha2 / (3.14159274101257f * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); } else { float3 X, Y, Z = N; make_orthonormals_tangent(Z, sc->T, &X, &Y); float3 local_m = ((float3)(dot(X, m), dot(Y, m), dot(Z, m))); float slope_x = -local_m.x/(local_m.z*alpha_x); float slope_y = -local_m.y/(local_m.z*alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = 1 / ((slope_len * slope_len) * 3.14159274101257f * alpha2 * cosThetaM4); float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); float cosPhiO = dot(I, X); float sinPhiO = dot(I, Y); float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); float cosPhiI = dot(omega_in, X); float sinPhiI = dot(omega_in, Y); float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); } float G = G1o * G1i; float common = D * 0.25f / cosNO; float out = G * common; *pdf = G1o * common; return ((float3)(out, out, out)); } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; float m_eta = sc->data2; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; float3 N = sc->N; if(!m_refractive || fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) return ((float3)(0.0f, 0.0f, 0.0f)); float cosNO = dot(N, I); float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return ((float3)(0.0f, 0.0f, 0.0f)); float3 ht = -(m_eta * omega_in + I); float3 Ht = normalize(ht); float cosHO = dot(Ht, I); float cosHI = dot(Ht, omega_in); float D, G1o, G1i; float alpha2 = alpha_x * alpha_y; float cosThetaM = dot(N, Ht); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = alpha2 / (3.14159274101257f * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); float G = G1o * G1i; float Ht2 = dot(ht, ht); float common = D * (m_eta * m_eta) / (cosNO * Ht2); float out = G * fabs(((float)(cosHI * cosHO))) * common; *pdf = G1o * fabs(((float)(cosHO * cosHI))) * common; return ((float3)(out, out, out)); } int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; float3 N = sc->N; float cosNO = dot(N, I); if(cosNO > 0) { float3 X, Y, Z = N; if(alpha_x == alpha_y) make_orthonormals(Z, &X, &Y); else make_orthonormals_tangent(Z, sc->T, &X, &Y); float3 local_I = ((float3)(dot(X, I), dot(Y, I), cosNO)); float3 local_m; float G1o; local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_y, randu, randv, 0, &G1o); float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z; float cosThetaM = local_m.z; if(!m_refractive) { float cosMO = dot(m, I); if(cosMO > 0) { *omega_in = 2 * cosMO * m - I; if(dot(Ng, *omega_in) > 0) { if(fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } else { float alpha2 = alpha_x * alpha_y; float D, G1i; if(alpha_x == alpha_y) { float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; D = alpha2 / (3.14159274101257f * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); float cosNI = dot(N, *omega_in); G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); } else { float3 local_m = ((float3)(dot(X, m), dot(Y, m), dot(Z, m))); float slope_x = -local_m.x/(local_m.z*alpha_x); float slope_y = -local_m.y/(local_m.z*alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = 1 / ((slope_len * slope_len) * 3.14159274101257f * alpha2 * cosThetaM4); float cosNI = dot(N, *omega_in); float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); float cosPhiI = dot(*omega_in, X); float sinPhiI = dot(*omega_in, Y); float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); } float common = (G1o * D) * 0.25f / cosNO; float out = G1i * common; *pdf = common; *eval = ((float3)(out, out, out)); } *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; } } } else { float3 R, T; float3 dRdx, dRdy, dTdx, dTdy; float m_eta = sc->data2, fresnel; bool inside; fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, &inside); if(!inside && fresnel != 1.0f) { *omega_in = T; *domega_in_dx = dTdx; *domega_in_dy = dTdy; if(fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f || fabs(((float)(m_eta - 1.0f))) < 1e-4f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } else { float alpha2 = alpha_x * alpha_y; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; float D = alpha2 / (3.14159274101257f * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); float cosNI = dot(N, *omega_in); float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); float cosHI = dot(m, *omega_in); float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2); float out = G1i * fabs(((float)(cosHI * cosHO))) * common; *pdf = cosHO * fabs(((float)(cosHI))) * common; *eval = ((float3)(out, out, out)); } } } } return (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY; } int bsdf_microfacet_beckmann_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = sc->data0; sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = saturate(sc->data1); sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc) { sc->data0 = saturate(sc->data0); sc->data1 = sc->data0; sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) { sc->data0 = fmax(((float)(roughness)), ((float)(sc->data0))); sc->data1 = fmax(((float)(roughness)), ((float)(sc->data1))); } float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; float3 N = sc->N; if(m_refractive || fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) return ((float3)(0.0f, 0.0f, 0.0f)); float cosNO = dot(N, I); float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float3 m = normalize(omega_in + I); float alpha2 = alpha_x * alpha_y; float D, G1o, G1i; if(alpha_x == alpha_y) { float cosThetaM = dot(N, m); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = native_exp(((float)(-tanThetaM2 / alpha2))) / (3.14159274101257f * alpha2 * cosThetaM4); float ao = 1 / (alpha_x * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (alpha_x * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; } else { float3 X, Y, Z = N; make_orthonormals_tangent(Z, sc->T, &X, &Y); float3 local_m = ((float3)(dot(X, m), dot(Y, m), dot(Z, m))); float slope_x = -local_m.x/(local_m.z*alpha_x); float slope_y = -local_m.y/(local_m.z*alpha_y); float cosThetaM = local_m.z; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = native_exp(((float)(-slope_x*slope_x - slope_y*slope_y))) / (3.14159274101257f * alpha2 * cosThetaM4); float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); float cosPhiO = dot(I, X); float sinPhiO = dot(I, Y); float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); float cosPhiI = dot(omega_in, X); float sinPhiI = dot(omega_in, Y); float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; float ao = 1 / (safe_sqrtf(alphaO2 * tanThetaO2)); float ai = 1 / (safe_sqrtf(alphaI2 * tanThetaI2)); G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; } float G = G1o * G1i; float common = D * 0.25f / cosNO; float out = G * common; *pdf = G1o * common; return ((float3)(out, out, out)); } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; float m_eta = sc->data2; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; float3 N = sc->N; if(!m_refractive || fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) return ((float3)(0.0f, 0.0f, 0.0f)); float cosNO = dot(N, I); float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return ((float3)(0.0f, 0.0f, 0.0f)); float3 ht = -(m_eta * omega_in + I); float3 Ht = normalize(ht); float cosHO = dot(Ht, I); float cosHI = dot(Ht, omega_in); float alpha2 = alpha_x * alpha_y; float cosThetaM = min(dot(N, Ht), 1.0f); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; float D = native_exp(((float)(-tanThetaM2 / alpha2))) / (3.14159274101257f * alpha2 * cosThetaM4); float ao = 1 / (alpha_x * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (alpha_x * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; float G = G1o * G1i; float Ht2 = dot(ht, ht); float common = D * (m_eta * m_eta) / (cosNO * Ht2); float out = G * fabs(((float)(cosHI * cosHO))) * common; *pdf = G1o * fabs(((float)(cosHO * cosHI))) * common; return ((float3)(out, out, out)); } int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float alpha_x = sc->data0; float alpha_y = sc->data1; bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; float3 N = sc->N; float cosNO = dot(N, I); if(cosNO > 0) { float3 X, Y, Z = N; if(alpha_x == alpha_y) make_orthonormals(Z, &X, &Y); else make_orthonormals_tangent(Z, sc->T, &X, &Y); float3 local_I = ((float3)(dot(X, I), dot(Y, I), cosNO)); float3 local_m; float G1o; local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, 1, &G1o); float3 m = X*local_m.x + Y*local_m.y + Z*local_m.z; float cosThetaM = local_m.z; if(!m_refractive) { float cosMO = dot(m, I); if(cosMO > 0) { *omega_in = 2 * cosMO * m - I; if(dot(Ng, *omega_in) > 0) { if(fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } else { float alpha2 = alpha_x * alpha_y; float D, G1i; if(alpha_x == alpha_y) { float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; D = native_exp(((float)(-tanThetaM2 / alpha2))) / (3.14159274101257f * alpha2 * cosThetaM4); float cosNI = dot(N, *omega_in); float ai = 1 / (alpha_x * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; } else { float3 local_m = ((float3)(dot(X, m), dot(Y, m), dot(Z, m))); float slope_x = -local_m.x/(local_m.z*alpha_x); float slope_y = -local_m.y/(local_m.z*alpha_y); float cosThetaM = local_m.z; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; D = native_exp(((float)(-slope_x*slope_x - slope_y*slope_y))) / (3.14159274101257f * alpha2 * cosThetaM4); float cosNI = dot(N, *omega_in); float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); float cosPhiI = dot(*omega_in, X); float sinPhiI = dot(*omega_in, Y); float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; float ai = 1 / (safe_sqrtf(alphaI2 * tanThetaI2)); G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; } float G = G1o * G1i; float common = D * 0.25f / cosNO; float out = G * common; *pdf = G1o * common; *eval = ((float3)(out, out, out)); } *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; } } } else { float3 R, T; float3 dRdx, dRdy, dTdx, dTdy; float m_eta = sc->data2, fresnel; bool inside; fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, &inside); if(!inside && fresnel != 1.0f) { *omega_in = T; *domega_in_dx = dTdx; *domega_in_dy = dTdy; if(fmax(((float)(alpha_x)), ((float)(alpha_y))) <= 1e-4f || fabs(((float)(m_eta - 1.0f))) < 1e-4f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } else { float alpha2 = alpha_x * alpha_y; float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; float D = native_exp(((float)(-tanThetaM2 / alpha2))) / (3.14159274101257f * alpha2 * cosThetaM4); float cosNI = dot(N, *omega_in); float ai = 1 / (alpha_x * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; float G = G1o * G1i; float cosHI = dot(m, *omega_in); float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float common = D * (m_eta * m_eta) / (cosNO * Ht2); float out = G * fabs(((float)(cosHI * cosHO))) * common; *pdf = G1o * cosHO * fabs(((float)(cosHI))) * common; *eval = ((float3)(out, out, out)); } } } } return (m_refractive) ? LABEL_TRANSMIT|LABEL_GLOSSY : LABEL_REFLECT|LABEL_GLOSSY; } int bsdf_reflection_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_REFLECTION_ID; return SD_BSDF; } float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float3 N = sc->N; float cosNO = dot(N, I); if(cosNO > 0) { *omega_in = (2 * cosNO) * N - I; if(dot(Ng, *omega_in) > 0) { *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } } return LABEL_REFLECT|LABEL_SINGULAR; } int bsdf_refraction_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_REFRACTION_ID; return SD_BSDF; } float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_eta = sc->data0; float3 N = sc->N; float3 R, T; float3 dRdx, dRdy, dTdx, dTdy; bool inside; float fresnel; fresnel = fresnel_dielectric(m_eta, N, I, &R, &T, dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, &inside); if(!inside && fresnel != 1.0f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); *omega_in = T; *domega_in_dx = dTdx; *domega_in_dy = dTdy; } return LABEL_TRANSMIT|LABEL_SINGULAR; } int bsdf_transparent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSPARENT_ID; return SD_BSDF|SD_TRANSPARENT; } float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { *omega_in = -I; *domega_in_dx = -dIdx; *domega_in_dy = -dIdy; *pdf = 1; *eval = ((float3)(1, 1, 1)); return LABEL_TRANSMIT|LABEL_TRANSPARENT; } int bsdf_ashikhmin_shirley_setup(ShaderClosure *sc) { sc->data0 = clamp(sc->data0, 1e-4f, 1.0f); sc->data1 = sc->data0; sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_ashikhmin_shirley_aniso_setup(ShaderClosure *sc) { sc->data0 = clamp(sc->data0, 1e-4f, 1.0f); sc->data1 = clamp(sc->data1, 1e-4f, 1.0f); sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness) { sc->data0 = fmax(((float)(roughness)), ((float)(sc->data0))); sc->data1 = fmax(((float)(roughness)), ((float)(sc->data1))); } float bsdf_ashikhmin_shirley_roughness_to_exponent(float roughness) { return 2.0f / (roughness*roughness) - 2.0f; } float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float3 N = sc->N; float NdotI = dot(N, I); float NdotO = dot(N, omega_in); float out = 0.0f; if(fmax(((float)(sc->data0)), ((float)(sc->data1))) <= 1e-4f) return ((float3)(0.0f, 0.0f, 0.0f)); if(NdotI > 0.0f && NdotO > 0.0f) { NdotI = fmax(((float)(NdotI)), ((float)(1e-6f))); NdotO = fmax(((float)(NdotO)), ((float)(1e-6f))); float3 H = normalize(omega_in + I); float HdotI = fmax(((float)(fabs(((float)(dot(H, I)))))), ((float)(1e-6f))); float HdotN = fmax(((float)(dot(H, N))), ((float)(1e-6f))); float pump = 1.0f / fmax(((float)(1e-6f)), ((float)((HdotI*fmax(((float)(NdotO)), ((float)(NdotI))))))); float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0); float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1); if(n_x == n_y) { float e = n_x; float lobe = pow(((float)(HdotN)), ((float)(e))); float norm = (n_x + 1.0f) / (8.0f * 3.14159274101257f); out = NdotO * norm * lobe * pump; *pdf = norm * lobe / HdotI; } else { float3 X, Y; make_orthonormals_tangent(N, sc->T, &X, &Y); float HdotX = dot(H, X); float HdotY = dot(H, Y); float e = (n_x * HdotX*HdotX + n_y * HdotY*HdotY) / (1.0f - HdotN*HdotN); float lobe = pow(((float)(HdotN)), ((float)(e))); float norm = native_sqrt(((float)((n_x + 1.0f)*(n_y + 1.0f)))) / (8.0f * 3.14159274101257f); out = NdotO * norm * lobe * pump; *pdf = norm * lobe / HdotI; } } return ((float3)(out, out, out)); } float3 bsdf_ashikhmin_shirley_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, float n_y, float randu, float randv, float *phi, float *cos_theta) { *phi = atan(((float)(native_sqrt(((float)((n_x + 1.0f) / (n_y + 1.0f)))) * native_tan(((float)(1.57079637050629f * randu)))))); float cos_phi = native_cos(((float)(*phi))); float sin_phi = native_sin(((float)(*phi))); *cos_theta = pow(((float)(randv)), ((float)(1.0f / (n_x * cos_phi*cos_phi + n_y * sin_phi*sin_phi + 1.0f)))); } int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float3 N = sc->N; float NdotI = dot(N, I); if(NdotI > 0.0f) { float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0); float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1); float3 X, Y; if(n_x == n_y) make_orthonormals(N, &X, &Y); else make_orthonormals_tangent(N, sc->T, &X, &Y); float phi; float cos_theta; if(n_x == n_y) { phi = ((float)6.283185307179586476925286766559005768) * randu; cos_theta = pow(((float)(randv)), ((float)(1.0f / (n_x + 1.0f)))); } else { if(randu < 0.25f) { float remapped_randu = 4.0f * randu; bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta); } else if(randu < 0.5f) { float remapped_randu = 4.0f * (.5f - randu); bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta); phi = 3.14159274101257f - phi; } else if(randu < 0.75f) { float remapped_randu = 4.0f * (randu - 0.5f); bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta); phi = 3.14159274101257f + phi; } else { float remapped_randu = 4.0f * (1.0f - randu); bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta); phi = 2.0f * 3.14159274101257f - phi; } } float sin_theta = native_sqrt(((float)(fmax(((float)(0.0f)), ((float)(1.0f - cos_theta*cos_theta)))))); float cos_phi = native_cos(((float)(phi))); float sin_phi = native_sin(((float)(phi))); float3 h = ((float3)(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta)); float3 H = h.x*X + h.y*Y + h.z*N; float HdotI = dot(H, I); if(HdotI < 0.0f) H = -H; *omega_in = -I + (2.0f * HdotI) * H; if(fmax(((float)(sc->data0)), ((float)(sc->data1))) <= 1e-4f) { *pdf = 1e6f; *eval = ((float3)(1e6f, 1e6f, 1e6f)); } else { *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf); } *domega_in_dx = (2.0f * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2.0f * dot(N, dIdy)) * N - dIdy; } return LABEL_REFLECT|LABEL_GLOSSY; } int bsdf_diffuse_toon_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_TOON_ID; sc->data0 = saturate(sc->data0); sc->data1 = saturate(sc->data1); return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle) { float is; if(angle < max_angle) is = 1.0f; else if(angle < (max_angle + smooth) && smooth != 0.0f) is = (1.0f - (angle - max_angle)/smooth); else is = 0.0f; return ((float3)(is, is, is)); } float bsdf_toon_get_sample_angle(float max_angle, float smooth) { return fmin(((float)(max_angle + smooth)), ((float)(1.57079637050629f))); } float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float max_angle = sc->data0*1.57079637050629f; float smooth = sc->data1*1.57079637050629f; float angle = safe_acosf(fmax(((float)(dot(sc->N, omega_in))), ((float)(0.0f)))); float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle); if(eval.x > 0.0f) { float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); *pdf = 0.5f * 0.31830987334251f / (1.0f - native_cos(((float)(sample_angle)))); return *pdf * eval; } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_diffuse_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float max_angle = sc->data0*1.57079637050629f; float smooth = sc->data1*1.57079637050629f; float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); float angle = sample_angle*randu; if(sample_angle > 0.0f) { sample_uniform_cone(sc->N, sample_angle, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0.0f) { *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle); *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx; *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy; } else *pdf = 0.0f; } return LABEL_REFLECT | LABEL_DIFFUSE; } int bsdf_glossy_toon_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_GLOSSY_TOON_ID; sc->data0 = saturate(sc->data0); sc->data1 = saturate(sc->data1); return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_glossy_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float max_angle = sc->data0*1.57079637050629f; float smooth = sc->data1*1.57079637050629f; float cosNI = dot(sc->N, omega_in); float cosNO = dot(sc->N, I); if(cosNI > 0 && cosNO > 0) { float3 R = (2 * cosNO) * sc->N - I; float cosRI = dot(R, omega_in); float angle = safe_acosf(fmax(((float)(cosRI)), ((float)(0.0f)))); float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle); float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); *pdf = 0.5f * 0.31830987334251f / (1.0f - native_cos(((float)(sample_angle)))); return *pdf * eval; } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_glossy_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } int bsdf_glossy_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float max_angle = sc->data0*1.57079637050629f; float smooth = sc->data1*1.57079637050629f; float cosNO = dot(sc->N, I); if(cosNO > 0) { float3 R = (2 * cosNO) * sc->N - I; float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); float angle = sample_angle*randu; sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf); if(dot(Ng, *omega_in) > 0.0f) { float cosNI = dot(sc->N, *omega_in); if(cosNI > 0) { *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle); *domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx; *domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy; } else *pdf = 0.0f; } else *pdf = 0.0f; } return LABEL_GLOSSY | LABEL_REFLECT; } int bsdf_hair_reflection_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_HAIR_REFLECTION_ID; sc->data0 = clamp(sc->data0, 0.001f, 1.0f); sc->data1 = clamp(sc->data1, 0.001f, 1.0f); return SD_BSDF|SD_BSDF_HAS_EVAL; } int bsdf_hair_transmission_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID; sc->data0 = clamp(sc->data0, 0.001f, 1.0f); sc->data1 = clamp(sc->data1, 0.001f, 1.0f); return SD_BSDF|SD_BSDF_HAS_EVAL; } float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float offset = sc->data2; float3 Tg = sc->T; float roughness1 = sc->data0; float roughness2 = sc->data1; float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float theta_r = 1.57079637050629f - fast_acosf(Iz); float omega_in_z = dot(Tg, omega_in); float3 omega_in_y = normalize(omega_in - Tg * omega_in_z); float theta_i = 1.57079637050629f - fast_acosf(omega_in_z); float cosphi_i = dot(omega_in_y, locy); if(1.57079637050629f - fabs(((float)(theta_i))) < 0.001f || cosphi_i < 0.0f) { *pdf = 0.0f; return ((float3)(*pdf, *pdf, *pdf)); } float roughness1_inv = 1.0f / roughness1; float roughness2_inv = 1.0f / roughness2; float phi_i = fast_acosf(cosphi_i) * roughness2_inv; phi_i = fabs(((float)(phi_i))) < 3.14159274101257f ? phi_i : 3.14159274101257f; float costheta_i = fast_cosf(theta_i); float a_R = fast_atan2f(((1.57079637050629f + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f); float b_R = fast_atan2f(((-1.57079637050629f + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f); float theta_h = (theta_i + theta_r) * 0.5f; float t = theta_h - offset; float phi_pdf = fast_cosf(phi_i * 0.5f) * 0.25f * roughness2_inv; float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)* costheta_i); *pdf = phi_pdf * theta_pdf; return ((float3)(*pdf, *pdf, *pdf)); } float3 bsdf_hair_transmission_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_hair_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return ((float3)(0.0f, 0.0f, 0.0f)); } float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float offset = sc->data2; float3 Tg = sc->T; float roughness1 = sc->data0; float roughness2 = sc->data1; float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float theta_r = 1.57079637050629f - fast_acosf(Iz); float omega_in_z = dot(Tg, omega_in); float3 omega_in_y = normalize(omega_in - Tg * omega_in_z); float theta_i = 1.57079637050629f - fast_acosf(omega_in_z); float phi_i = fast_acosf(dot(omega_in_y, locy)); if(1.57079637050629f - fabs(((float)(theta_i))) < 0.001f) { *pdf = 0.0f; return ((float3)(*pdf, *pdf, *pdf)); } float costheta_i = fast_cosf(theta_i); float roughness1_inv = 1.0f / roughness1; float a_TT = fast_atan2f(((1.57079637050629f + theta_r)/2 - offset) * roughness1_inv, 1.0f); float b_TT = fast_atan2f(((-1.57079637050629f + theta_r)/2 - offset) * roughness1_inv, 1.0f); float c_TT = 2 * fast_atan2f(1.57079637050629f / roughness2, 1.0f); float theta_h = (theta_i + theta_r) / 2; float t = theta_h - offset; float phi = fabs(((float)(phi_i))); float p = 3.14159274101257f - phi; float theta_pdf = roughness1 / (2 * (t*t + roughness1 * roughness1) * (a_TT - b_TT)*costheta_i); float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2)); *pdf = phi_pdf * theta_pdf; return ((float3)(*pdf, *pdf, *pdf)); } int bsdf_hair_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float offset = sc->data2; float3 Tg = sc->T; float roughness1 = sc->data0; float roughness2 = sc->data1; float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float3 locx = cross(locy, Tg); float theta_r = 1.57079637050629f - fast_acosf(Iz); float roughness1_inv = 1.0f / roughness1; float a_R = fast_atan2f(((1.57079637050629f + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f); float b_R = fast_atan2f(((-1.57079637050629f + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f); float t = roughness1 * native_tan(((float)(randu * (a_R - b_R) + b_R))); float theta_h = t + offset; float theta_i = 2 * theta_h - theta_r; float costheta_i, sintheta_i; fast_sincosf(theta_i, &sintheta_i, &costheta_i); float phi = 2 * safe_asinf(1 - 2 * randv) * roughness2; float phi_pdf = fast_cosf(phi * 0.5f) * 0.25f / roughness2; float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)*costheta_i); float sinphi, cosphi; fast_sincosf(phi, &sinphi, &cosphi); *omega_in =(cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + ( sintheta_i) * Tg; *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx; *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy; *pdf = fabs(((float)(phi_pdf * theta_pdf))); if(1.57079637050629f - fabs(((float)(theta_i))) < 0.001f) *pdf = 0.0f; *eval = ((float3)(*pdf, *pdf, *pdf)); return LABEL_REFLECT|LABEL_GLOSSY; } int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float offset = sc->data2; float3 Tg = sc->T; float roughness1 = sc->data0; float roughness2 = sc->data1; float Iz = dot(Tg, I); float3 locy = normalize(I - Tg * Iz); float3 locx = cross(locy, Tg); float theta_r = 1.57079637050629f - fast_acosf(Iz); float roughness1_inv = 1.0f / roughness1; float a_TT = fast_atan2f(((1.57079637050629f + theta_r)/2 - offset) * roughness1_inv, 1.0f); float b_TT = fast_atan2f(((-1.57079637050629f + theta_r)/2 - offset) * roughness1_inv, 1.0f); float c_TT = 2 * fast_atan2f(1.57079637050629f / roughness2, 1.0f); float t = roughness1 * native_tan(((float)(randu * (a_TT - b_TT) + b_TT))); float theta_h = t + offset; float theta_i = 2 * theta_h - theta_r; float costheta_i, sintheta_i; fast_sincosf(theta_i, &sintheta_i, &costheta_i); float p = roughness2 * native_tan(((float)(c_TT * (randv - 0.5f)))); float phi = p + 3.14159274101257f; float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_TT - b_TT) * costheta_i); float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2)); float sinphi, cosphi; fast_sincosf(phi, &sinphi, &cosphi); *omega_in =(cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + ( sintheta_i) * Tg; *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx; *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy; *pdf = fabs(((float)(phi_pdf * theta_pdf))); if(1.57079637050629f - fabs(((float)(theta_i))) < 0.001f) { *pdf = 0.0f; } *eval = ((float3)(*pdf, *pdf, *pdf)); ; return LABEL_TRANSMIT|LABEL_GLOSSY; } #line 49995 "C:\\cygwin64\\tmp\\OCL6424T10.cl" int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf) { int label; switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: case CLOSURE_BSDF_BSSRDF_ID: label = bsdf_diffuse_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_OREN_NAYAR_ID: label = bsdf_oren_nayar_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: label = bsdf_translucent_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: label = bsdf_reflection_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: label = bsdf_refraction_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: label = bsdf_transparent_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: label = bsdf_microfacet_ggx_sample(kg, sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: label = bsdf_microfacet_beckmann_sample(kg, sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: label = bsdf_ashikhmin_shirley_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: label = bsdf_ashikhmin_velvet_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: label = bsdf_diffuse_toon_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: label = bsdf_glossy_toon_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: label = bsdf_hair_reflection_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: label = bsdf_hair_transmission_sample(sc, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #line 50085 "C:\\cygwin64\\tmp\\OCL6424T10.cl" default: label = LABEL_NONE; break; } return label; } float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf) { float3 eval; if(dot((sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in) >= 0.0f) { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: case CLOSURE_BSDF_BSSRDF_ID: eval = bsdf_diffuse_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_OREN_NAYAR_ID: eval = bsdf_oren_nayar_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: eval = bsdf_translucent_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: eval = bsdf_reflection_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: eval = bsdf_refraction_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: eval = bsdf_transparent_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: eval = bsdf_microfacet_ggx_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: eval = bsdf_microfacet_beckmann_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: eval = bsdf_ashikhmin_shirley_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: eval = bsdf_ashikhmin_velvet_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: eval = bsdf_diffuse_toon_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: eval = bsdf_glossy_toon_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: eval = bsdf_hair_reflection_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: eval = bsdf_hair_transmission_eval_reflect(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; #line 50165 "C:\\cygwin64\\tmp\\OCL6424T10.cl" default: eval = ((float3)(0.0f, 0.0f, 0.0f)); break; } } else { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: case CLOSURE_BSDF_BSSRDF_ID: eval = bsdf_diffuse_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_OREN_NAYAR_ID: eval = bsdf_oren_nayar_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: eval = bsdf_translucent_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: eval = bsdf_reflection_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: eval = bsdf_refraction_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: eval = bsdf_transparent_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: eval = bsdf_microfacet_ggx_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: eval = bsdf_microfacet_beckmann_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: eval = bsdf_ashikhmin_shirley_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: eval = bsdf_ashikhmin_velvet_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: eval = bsdf_diffuse_toon_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: eval = bsdf_glossy_toon_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: eval = bsdf_hair_reflection_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: eval = bsdf_hair_transmission_eval_transmit(sc, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), omega_in, pdf); break; #line 50227 "C:\\cygwin64\\tmp\\OCL6424T10.cl" default: eval = ((float3)(0.0f, 0.0f, 0.0f)); break; } } return eval; } void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness) { #line 50246 "C:\\cygwin64\\tmp\\OCL6424T10.cl" switch(sc->type) { case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: bsdf_microfacet_ggx_blur(sc, roughness); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: bsdf_microfacet_beckmann_blur(sc, roughness); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: bsdf_ashikhmin_shirley_blur(sc, roughness); break; default: break; } } float emissive_pdf(const float3 Ng, const float3 I) { float cosNO = fabs(((float)(dot(Ng, I)))); return (cosNO > 0.0f)? 1.0f: 0.0f; } void emissive_sample(const float3 Ng, float randu, float randv, float3 *omega_out, float *pdf) { } float3 emissive_simple_eval(const float3 Ng, const float3 I) { float res = emissive_pdf(Ng, I); return ((float3)(res, res, res)); } #line 50823 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 stack_load_float3(float *stack, uint a) { ; return ((float3)(stack[a+0], stack[a+1], stack[a+2])); } void stack_store_float3(float *stack, uint a, float3 f) { ; stack[a+0] = f.x; stack[a+1] = f.y; stack[a+2] = f.z; } float stack_load_float(float *stack, uint a) { ; return stack[a]; } float stack_load_float_default(float *stack, uint a, uint value) { return (a == (uint)255)? as_float(value): stack_load_float(stack, a); } void stack_store_float(float *stack, uint a, float f) { ; stack[a] = f; } int stack_load_int(float *stack, uint a) { ; return as_int(stack[a]); } int stack_load_int_default(float *stack, uint a, uint value) { return (a == (uint)255)? (int)value: stack_load_int(stack, a); } void stack_store_int(float *stack, uint a, int i) { ; stack[a] = as_float(i); } bool stack_valid(uint a) { return a != (uint)255; } uint4 read_node(KernelGlobals *kg, int *offset) { uint4 node = kg->__svm_nodes[*offset]; (*offset)++; return node; } float4 read_node_float(KernelGlobals *kg, int *offset) { uint4 node = kg->__svm_nodes[*offset]; float4 f = ((float4)(as_float(node . x), as_float(node . y), as_float(node . z), as_float(node . w))); (*offset)++; return f; } float4 fetch_node_float(KernelGlobals *kg, int offset) { uint4 node = kg->__svm_nodes[offset]; return ((float4)(as_float(node . x), as_float(node . y), as_float(node . z), as_float(node . w))); } void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w) { if(x) *x = (i & 0xFF); if(y) *y = ((i >> 8) & 0xFF); if(z) *z = ((i >> 16) & 0xFF); if(w) *w = ((i >> 24) & 0xFF); } int quick_floor(float x) { return float_to_int(x) - ((x < 0) ? 1 : 0); } #line 50973 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float bits_to_01(uint bits) { return bits * (1.0f/(float)0xFFFFFFFF); } #line 50985 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uint hash(uint kx, uint ky, uint kz) { #line 51000 "C:\\cygwin64\\tmp\\OCL6424T10.cl" uint a, b, c, len = 3; a = b = c = 0xdeadbeef + (len << 2) + 13; c += kz; b += ky; a += kx; { c ^= b; c -= (((b)<<(14)) | ((b)>>(32-(14)))); a ^= c; a -= (((c)<<(11)) | ((c)>>(32-(11)))); b ^= a; b -= (((a)<<(25)) | ((a)>>(32-(25)))); c ^= b; c -= (((b)<<(16)) | ((b)>>(32-(16)))); a ^= c; a -= (((c)<<(4)) | ((c)>>(32-(4)))); b ^= a; b -= (((a)<<(14)) | ((a)>>(32-(14)))); c ^= b; c -= (((b)<<(24)) | ((b)>>(32-(24)))); }; return c; } #line 51040 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 51053 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float floorfrac(float x, int* i) { *i = quick_floor(x); return x - *i; } #line 51067 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float fade(float t) { return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); } #line 51081 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float nerp(float t, float a, float b) { return (1.0f - t) * a + t * b; } #line 51094 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float grad(int hash, float x, float y, float z) { int h = hash & 15; float u = h<8 ? x : y; float vt = ((h == 12) | (h == 14)) ? x : z; float v = h < 4 ? y : vt; return ((h&1) ? -u : u) + ((h&2) ? -v : v); } #line 51138 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float scale3(float result) { return 0.9820f * result; } #line 51150 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float perlin(float x, float y, float z) { int X; float fx = floorfrac(x, &X); int Y; float fy = floorfrac(y, &Y); int Z; float fz = floorfrac(z, &Z); float u = fade(fx); float v = fade(fy); float w = fade(fz); float result; result = nerp (w, nerp (v, nerp (u, grad (hash (X , Y , Z ), fx , fy , fz ), grad (hash (X+1, Y , Z ), fx-1.0f, fy , fz )), nerp (u, grad (hash (X , Y+1, Z ), fx , fy-1.0f, fz ), grad (hash (X+1, Y+1, Z ), fx-1.0f, fy-1.0f, fz ))), nerp (v, nerp (u, grad (hash (X , Y , Z+1), fx , fy , fz-1.0f ), grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ), grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f )))); float r = scale3(result); return (isfinite(r))? r: 0.0f; } #line 51217 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float noise(float3 p) { float r = perlin(p.x, p.y, p.z); return 0.5f*r + 0.5f; } float snoise(float3 p) { return perlin(p.x, p.y, p.z); } float cellnoise(float3 p) { uint ix = quick_floor(p.x); uint iy = quick_floor(p.y); uint iz = quick_floor(p.z); return bits_to_01(hash(ix, iy, iz)); } float3 cellnoise_color(float3 p) { float r = cellnoise(p); float g = cellnoise(((float3)(p . y, p . x, p . z))); float b = cellnoise(((float3)(p . y, p . z, p . x))); return ((float3)(r, g, b)); } #line 51260 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float noise_turbulence(float3 p, float octaves, int hard) { float fscale = 1.0f; float amp = 1.0f; float sum = 0.0f; int i, n; octaves = clamp(octaves, 0.0f, 16.0f); n = float_to_int(octaves); for(i = 0; i <= n; i++) { float t = noise(fscale*p); if(hard) t = fabs(((float)(2.0f*t - 1.0f))); sum += t*amp; amp *= 0.5f; fscale *= 2.0f; } float rmd = octaves - floor(((float)(octaves))); if(rmd != 0.0f) { float t = noise(fscale*p); if(hard) t = fabs(((float)(2.0f*t - 1.0f))); float sum2 = sum + t*amp; sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1)); return (1.0f - rmd)*sum + rmd*sum2; } else { sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); return sum; } } float average_fac(float3 v) { return (fabs(((float)(v . x))) + fabs(((float)(v . y))) + fabs(((float)(v . z))))/3.0f; } void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2) { if(type == NODE_VECTOR_MATH_ADD) { *Vector = Vector1 + Vector2; *Fac = average_fac(*Vector); } else if(type == NODE_VECTOR_MATH_SUBTRACT) { *Vector = Vector1 - Vector2; *Fac = average_fac(*Vector); } else if(type == NODE_VECTOR_MATH_AVERAGE) { *Fac = len(Vector1 + Vector2); *Vector = normalize(Vector1 + Vector2); } else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) { *Fac = dot(Vector1, Vector2); *Vector = ((float3)(0.0f, 0.0f, 0.0f)); } else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) { float3 c = cross(Vector1, Vector2); *Fac = len(c); *Vector = normalize(c); } else if(type == NODE_VECTOR_MATH_NORMALIZE) { *Fac = len(Vector1); *Vector = normalize(Vector1); } else { *Fac = 0.0f; *Vector = ((float3)(0.0f, 0.0f, 0.0f)); } } float svm_math(NodeMath type, float Fac1, float Fac2) { float Fac; if(type == NODE_MATH_ADD) Fac = Fac1 + Fac2; else if(type == NODE_MATH_SUBTRACT) Fac = Fac1 - Fac2; else if(type == NODE_MATH_MULTIPLY) Fac = Fac1*Fac2; else if(type == NODE_MATH_DIVIDE) Fac = safe_divide(Fac1, Fac2); else if(type == NODE_MATH_SINE) Fac = native_sin(((float)(Fac1))); else if(type == NODE_MATH_COSINE) Fac = native_cos(((float)(Fac1))); else if(type == NODE_MATH_TANGENT) Fac = native_tan(((float)(Fac1))); else if(type == NODE_MATH_ARCSINE) Fac = safe_asinf(Fac1); else if(type == NODE_MATH_ARCCOSINE) Fac = safe_acosf(Fac1); else if(type == NODE_MATH_ARCTANGENT) Fac = atan(((float)(Fac1))); else if(type == NODE_MATH_POWER) Fac = safe_powf(Fac1, Fac2); else if(type == NODE_MATH_LOGARITHM) Fac = safe_logf(Fac1, Fac2); else if(type == NODE_MATH_MINIMUM) Fac = fmin(((float)(Fac1)), ((float)(Fac2))); else if(type == NODE_MATH_MAXIMUM) Fac = fmax(((float)(Fac1)), ((float)(Fac2))); else if(type == NODE_MATH_ROUND) Fac = floor(((float)(Fac1 + 0.5f))); else if(type == NODE_MATH_LESS_THAN) Fac = Fac1 < Fac2; else if(type == NODE_MATH_GREATER_THAN) Fac = Fac1 > Fac2; else if(type == NODE_MATH_MODULO) Fac = safe_modulo(Fac1, Fac2); else if(type == NODE_MATH_ABSOLUTE) Fac = fabs(((float)(Fac1))); else if(type == NODE_MATH_CLAMP) Fac = saturate(Fac1); else Fac = 0.0f; return Fac; } float3 svm_math_blackbody_color(float t) { const float rc[6][3] = { { 2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f }, { 3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f }, { 4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f }, { 4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f }, { 4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f }, { 3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f }, }; const float gc[6][3] = { { -7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f }, { -1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f }, { -1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f }, { -1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f }, { -1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f }, { -5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f }, }; const float bc[6][4] = { { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f }, { -2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f }, { 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f }, }; if(t >= 12000.0f) return ((float3)(0.826270103f, 0.994478524f, 1.56626022f)); if(t >= 6365.0f) return ((float3)(rc[5][0] / t + rc[5][1] * t + rc[5][2], gc[5][0] / t + gc[5][1] * t + gc[5][2], ((bc[5][0] * t + bc[5][1]) * t + bc[5][2]) * t + bc[5][3])); if(t >= 3315.0f) return ((float3)(rc[4][0] / t + rc[4][1] * t + rc[4][2], gc[4][0] / t + gc[4][1] * t + gc[4][2], ((bc[4][0] * t + bc[4][1]) * t + bc[4][2]) * t + bc[4][3])); if(t >= 1902.0f) return ((float3)(rc[3][0] / t + rc[3][1] * t + rc[3][2], gc[3][0] / t + gc[3][1] * t + gc[3][2], ((bc[3][0] * t + bc[3][1]) * t + bc[3][2]) * t + bc[3][3])); if(t >= 1449.0f) return ((float3)(rc[2][0] / t + rc[2][1] * t + rc[2][2], gc[2][0] / t + gc[2][1] * t + gc[2][2], ((bc[2][0] * t + bc[2][1]) * t + bc[2][2]) * t + bc[2][3])); if(t >= 1167.0f) return ((float3)(rc[1][0] / t + rc[1][1] * t + rc[1][2], gc[1][0] / t + gc[1][1] * t + gc[1][2], ((bc[1][0] * t + bc[1][1]) * t + bc[1][2]) * t + bc[1][3])); if(t >= 965.0f) return ((float3)(rc[0][0] / t + rc[0][1] * t + rc[0][2], gc[0][0] / t + gc[0][1] * t + gc[0][2], ((bc[0][0] * t + bc[0][1]) * t + bc[0][2]) * t + bc[0][3])); return ((float3)(4.70366907f, 0.0f, 0.0f)); } void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset) { *out_offset = node.z; *type = (NodeAttributeType)node.w; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { uint id = node.y; uint attr_offset = (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*(*kg->data).bvh.attributes_map_stride; uint4 attr_map = kg->__attributes_map[attr_offset]; while(attr_map.x != id) { if((attr_map . x == ATTR_STD_NONE)) { *elem = ATTR_ELEMENT_NONE; *offset = 0; *mesh_type = (NodeAttributeType)node.w; return; } attr_offset += 2; attr_map = kg->__attributes_map[attr_offset]; } *elem = (AttributeElement)attr_map.y; *offset = as_int(attr_map.z); *mesh_type = (NodeAttributeType)attr_map.w; } else { *elem = ATTR_ELEMENT_NONE; *offset = 0; *mesh_type = (NodeAttributeType)node.w; } } void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { NodeAttributeType type, mesh_type; AttributeElement elem; uint out_offset; int offset; svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); if(type == NODE_ATTR_FLOAT) { if(mesh_type == NODE_ATTR_FLOAT) { float f = primitive_attribute_float(kg, sd, elem, offset, 0, 0); stack_store_float(stack, out_offset, f); } else { float3 f = primitive_attribute_float3(kg, sd, elem, offset, 0, 0); stack_store_float(stack, out_offset, average(f)); } } else { if(mesh_type == NODE_ATTR_FLOAT3) { float3 f = primitive_attribute_float3(kg, sd, elem, offset, 0, 0); stack_store_float3(stack, out_offset, f); } else { float f = primitive_attribute_float(kg, sd, elem, offset, 0, 0); stack_store_float3(stack, out_offset, ((float3)(f, f, f))); } } } void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { NodeAttributeType type, mesh_type; AttributeElement elem; uint out_offset; int offset; svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); if(type == NODE_ATTR_FLOAT) { if(mesh_type == NODE_ATTR_FLOAT) { float dx; float f = primitive_attribute_float(kg, sd, elem, offset, &dx, 0); stack_store_float(stack, out_offset, f+dx); } else { float3 dx; float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, 0); stack_store_float(stack, out_offset, average(f+dx)); } } else { if(mesh_type == NODE_ATTR_FLOAT3) { float3 dx; float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, 0); stack_store_float3(stack, out_offset, f+dx); } else { float dx; float f = primitive_attribute_float(kg, sd, elem, offset, &dx, 0); stack_store_float3(stack, out_offset, ((float3)(f+dx, f+dx, f+dx))); } } } void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { NodeAttributeType type, mesh_type; AttributeElement elem; uint out_offset; int offset; svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); if(type == NODE_ATTR_FLOAT) { if(mesh_type == NODE_ATTR_FLOAT) { float dy; float f = primitive_attribute_float(kg, sd, elem, offset, 0, &dy); stack_store_float(stack, out_offset, f+dy); } else { float3 dy; float3 f = primitive_attribute_float3(kg, sd, elem, offset, 0, &dy); stack_store_float(stack, out_offset, average(f+dy)); } } else { if(mesh_type == NODE_ATTR_FLOAT3) { float3 dy; float3 f = primitive_attribute_float3(kg, sd, elem, offset, 0, &dy); stack_store_float3(stack, out_offset, f+dy); } else { float dy; float f = primitive_attribute_float(kg, sd, elem, offset, 0, &dy); stack_store_float3(stack, out_offset, ((float3)(f+dy, f+dy, f+dy))); } } } float svm_gradient(float3 p, NodeGradientType type) { float x, y, z; x = p.x; y = p.y; z = p.z; if(type == NODE_BLEND_LINEAR) { return x; } else if(type == NODE_BLEND_QUADRATIC) { float r = fmax(((float)(x)), ((float)(0.0f))); return r*r; } else if(type == NODE_BLEND_EASING) { float r = fmin(((float)(fmax(((float)(x)), ((float)(0.0f))))), ((float)(1.0f))); float t = r*r; return (3.0f*t - 2.0f*t*r); } else if(type == NODE_BLEND_DIAGONAL) { return (x + y) * 0.5f; } else if(type == NODE_BLEND_RADIAL) { return atan2(((float)(y)), ((float)(x))) / ((float)6.283185307179586476925286766559005768) + 0.5f; } else { float r = fmax(((float)(1.0f - native_sqrt(((float)(x*x + y*y + z*z))))), ((float)(0.0f))); if(type == NODE_BLEND_QUADRATIC_SPHERE) return r*r; else if(type == NODE_BLEND_SPHERICAL) return r; } return 0.0f; } void svm_node_tex_gradient(ShaderData *sd, float *stack, uint4 node) { uint type, co_offset, color_offset, fac_offset; decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset); float3 co = stack_load_float3(stack, co_offset); float f = svm_gradient(co, (NodeGradientType)type); f = saturate(f); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, ((float3)(f, f, f))); } void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) { float temperature = stack_load_float(stack, temperature_offset); float3 color_rgb = svm_math_blackbody_color(temperature); if(stack_valid(col_offset)) stack_store_float3(stack, col_offset, color_rgb); } void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract) { if(type == CLOSURE_BSDF_SHARP_GLASS_ID) { if(refract) { sc->data0 = eta; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_refraction_setup(sc); } else { sc->data0 = 0.0f; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_reflection_setup(sc); } } else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) { sc->data0 = roughness; sc->data1 = roughness; sc->data2 = eta; if(refract) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_beckmann_refraction_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_beckmann_setup(sc); } else { sc->data0 = roughness; sc->data1 = roughness; sc->data2 = eta; if(refract) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_ggx_refraction_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_ggx_setup(sc); } } ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); if((sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) < 3) { sc->weight *= mix_weight; sc->type = type; sc->data0 = 0.0f; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])++; return sc; } return 0; } ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); float3 weight = sc->weight * mix_weight; float sample_weight = fabs(((float)(average(weight)))); if(sample_weight > 1e-5f && (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) < 3) { sc->weight = weight; sc->sample_weight = sample_weight; (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])++; return sc; } return 0; } ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd, float mix_weight) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); float3 weight = (((float3)(1.0f, 1.0f, 1.0f)) - sc->weight) * mix_weight; float sample_weight = fabs(((float)(average(weight)))); if(sample_weight > 1e-5f && (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) < 3) { sc->weight = weight; sc->sample_weight = sample_weight; (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])++; return sc; } return 0; } void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int *offset) { uint type, param1_offset, param2_offset; uint mix_weight_offset; decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); uint4 data_node = read_node(kg, offset); if(mix_weight == 0.0f) return; float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): as_float(node . z); float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): as_float(node . w); switch(type) { case CLOSURE_BSDF_DIFFUSE_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; float roughness = param1; if(roughness == 0.0f) { sc->data0 = 0.0f; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_diffuse_setup(sc); } else { sc->data0 = roughness; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_oren_nayar_setup(sc); } } break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->data0 = 0.0f; sc->data1 = 0.0f; sc->data2 = 0.0f; sc->N = N; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_translucent_setup(sc); } break; } case CLOSURE_BSDF_TRANSPARENT_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->data0 = 0.0f; sc->data1 = 0.0f; sc->data2 = 0.0f; sc->N = N; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_transparent_setup(sc); } break; } case CLOSURE_BSDF_REFLECTION_ID: case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { if(!(*kg->data).integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; sc->data0 = param1; sc->data1 = param1; sc->data2 = 0.0f; if(type == CLOSURE_BSDF_REFLECTION_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_reflection_setup(sc); else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_beckmann_setup(sc); else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_ggx_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_ashikhmin_shirley_setup(sc); } break; } case CLOSURE_BSDF_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { if(!(*kg->data).integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; float eta = fmax(((float)(param2)), ((float)(1e-5f))); eta = ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BACKFACING)? 1.0f/eta: eta; if(type == CLOSURE_BSDF_REFRACTION_ID) { sc->data0 = eta; sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_refraction_setup(sc); } else { sc->data0 = param1; sc->data1 = param1; sc->data2 = eta; if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_beckmann_refraction_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_ggx_refraction_setup(sc); } } break; } case CLOSURE_BSDF_SHARP_GLASS_ID: case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { if(!(*kg->data).integrator.caustics_reflective && !(*kg->data).integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) { break; } float eta = fmax(((float)(param2)), ((float)(1e-5f))); eta = ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BACKFACING)? 1.0f/eta: eta; float cosNO = dot(N, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); float fresnel = fresnel_dielectric_cos(cosNO, eta); float roughness = param1; ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); float3 weight = sc->weight; float sample_weight = sc->sample_weight; sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); if((*kg->data).integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { if(sc) { sc->N = N; svm_node_glass_setup(sd, sc, type, eta, roughness, 0); } } if(!(*kg->data).integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; if((sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) < 3) { sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); sc->weight = weight; sc->sample_weight = sample_weight; sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel)); if(sc) { sc->N = N; svm_node_glass_setup(sd, sc, type, eta, roughness, 1); } } break; } case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { if(!(*kg->data).integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; sc->T = stack_load_float3(stack, data_node.y); float rotation = stack_load_float(stack, data_node.z); if(rotation != 0.0f) sc->T = rotate_around_axis(sc->T, sc->N, rotation * ((float)6.283185307179586476925286766559005768)); float roughness = param1; float anisotropy = clamp(param2, -0.99f, 0.99f); if(anisotropy < 0.0f) { sc->data0 = roughness/(1.0f + anisotropy); sc->data1 = roughness*(1.0f + anisotropy); } else { sc->data0 = roughness*(1.0f - anisotropy); sc->data1 = roughness/(1.0f - anisotropy); } sc->data2 = 0.0f; if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_beckmann_aniso_setup(sc); else if(type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_microfacet_ggx_aniso_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_ashikhmin_shirley_aniso_setup(sc); } break; } case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; sc->data0 = saturate(param1); sc->data1 = 0.0f; sc->data2 = 0.0f; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_ashikhmin_velvet_setup(sc); } break; } case CLOSURE_BSDF_DIFFUSE_TOON_ID: case CLOSURE_BSDF_GLOSSY_TOON_ID: { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->N = N; sc->data0 = param1; sc->data1 = param2; sc->data2 = 0.0f; if(type == CLOSURE_BSDF_DIFFUSE_TOON_ID) (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_diffuse_toon_setup(sc); else (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= bsdf_glossy_toon_setup(sc); } break; } #line 52240 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 52324 "C:\\cygwin64\\tmp\\OCL6424T10.cl" default: break; } } void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag) { #line 52369 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node) { uint mix_weight_offset = node.y; if(stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); if(mix_weight == 0.0f) return; svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight); } else svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f); (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= SD_EMISSION; } void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node) { uint mix_weight_offset = node.y; if(stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); if(mix_weight == 0.0f) return; svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight); } else svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f); } void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) { uint mix_weight_offset = node.y; if(stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); if(mix_weight == 0.0f) return; svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight); } else svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f); (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= SD_HOLDOUT; } void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node) { uint mix_weight_offset = node.y; if(stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); if(mix_weight == 0.0f) return; svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight); } else svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f); (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= SD_AO; } void svm_node_closure_store_weight(ShaderData *sd, float3 weight) { if((sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) < 3) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]); sc->weight = weight; } } void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b) { float3 weight = ((float3)(as_float(r), as_float(g), as_float(b))); svm_node_closure_store_weight(sd, weight); } void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset) { float3 weight = stack_load_float3(stack, weight_offset); svm_node_closure_store_weight(sd, weight); } void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint color_offset = node.y; uint strength_offset = node.z; float strength = stack_load_float(stack, strength_offset); float3 weight = stack_load_float3(stack, color_offset)*strength; svm_node_closure_store_weight(sd, weight); } void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node) { uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); float weight = stack_load_float(stack, weight_offset); weight = saturate(weight); float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f; if(stack_valid(weight1_offset)) stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight)); if(stack_valid(weight2_offset)) stack_store_float(stack, weight2_offset, in_weight*weight); } void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) { float3 normal = stack_load_float3(stack, in_direction); (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = normal; stack_store_float3(stack, out_normal, normal); } void svm_noise(float3 p, float detail, float distortion, float *fac, float3 *color) { int hard = 0; if(distortion != 0.0f) { float3 r, offset = ((float3)(13.5f, 13.5f, 13.5f)); r.x = noise(p + offset) * distortion; r.y = noise(p) * distortion; r.z = noise(p - offset) * distortion; p += r; } *fac = noise_turbulence(p, detail, hard); *color = ((float3)(*fac, noise_turbulence(((float3)(p . y, p . x, p . z)), detail, hard), noise_turbulence(((float3)(p . y, p . z, p . x)), detail, hard))); } void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset; decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset); uint4 node2 = read_node(kg, offset); float scale = stack_load_float_default(stack, scale_offset, node2.x); float detail = stack_load_float_default(stack, detail_offset, node2.y); float distortion = stack_load_float_default(stack, distortion_offset, node2.z); float3 co = stack_load_float3(stack, co_offset); float3 color; float f; svm_noise(co*scale, detail, distortion, &f, &color); decode_node_uchar4(node.z, &color_offset, &fac_offset, 0, 0); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color); } void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to) { switch(type) { case NODE_CONVERT_FI: { float f = stack_load_float(stack, from); stack_store_int(stack, to, float_to_int(f)); break; } case NODE_CONVERT_FV: { float f = stack_load_float(stack, from); stack_store_float3(stack, to, ((float3)(f, f, f))); break; } case NODE_CONVERT_CF: { float3 f = stack_load_float3(stack, from); float g = linear_rgb_to_gray(f); stack_store_float(stack, to, g); break; } case NODE_CONVERT_CI: { float3 f = stack_load_float3(stack, from); int i = (int)linear_rgb_to_gray(f); stack_store_int(stack, to, i); break; } case NODE_CONVERT_VF: { float3 f = stack_load_float3(stack, from); float g = average(f); stack_store_float(stack, to, g); break; } case NODE_CONVERT_VI: { float3 f = stack_load_float3(stack, from); int i = (int)average(f); stack_store_int(stack, to, i); break; } case NODE_CONVERT_IF: { float f = (float)stack_load_int(stack, from); stack_store_float(stack, to, f); break; } case NODE_CONVERT_IV: { float f = (float)stack_load_int(stack, from); stack_store_float3(stack, to, ((float3)(f, f, f))); break; } } } void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint normal_offset, distance_offset, invert; decode_node_uchar4(node.y, &normal_offset, &distance_offset, &invert, 0); float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float3 Rx = cross((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, normal_in); float3 Ry = cross(normal_in, (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx); uint c_offset, x_offset, y_offset, strength_offset; decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset); float h_c = stack_load_float(stack, c_offset); float h_x = stack_load_float(stack, x_offset); float h_y = stack_load_float(stack, y_offset); float det = dot((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, Rx); float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry; float absdet = fabs(((float)(det))); float strength = stack_load_float(stack, strength_offset); float distance = stack_load_float(stack, distance_offset); if(invert) distance *= -1.0f; strength = max(strength, 0.0f); float3 normal_out = normalize(absdet*normal_in - distance*signf(det)*surfgrad); normal_out = normalize(strength*normal_out + (1.0f - strength)*normal_in); stack_store_float3(stack, node.w, normal_out); } void svm_node_set_displacement(ShaderData *sd, float *stack, uint fac_offset) { float d = stack_load_float(stack, fac_offset); (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) += (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*d*0.1f; } void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node) { uint normal_offset, out_offset; decode_node_uchar4(node, &normal_offset, &out_offset, 0, 0); float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): as_float(ior_value); float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); eta = fmax(((float)(eta)), ((float)(1e-5f))); eta = ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BACKFACING)? 1.0f/eta: eta; float f = fresnel_dielectric_cos(dot((sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), normal_in), eta); stack_store_float(stack, out_offset, f); } void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node) { uint blend_offset = node.y; uint blend_value = node.z; uint type, normal_offset, out_offset; decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, 0); float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): as_float(blend_value); float3 normal_in = (stack_valid(normal_offset))? stack_load_float3(stack, normal_offset): (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float f; if(type == NODE_LAYER_WEIGHT_FRESNEL) { float eta = fmax(((float)(1.0f - blend)), ((float)(1e-5f))); eta = ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BACKFACING)? eta: 1.0f/eta; f = fresnel_dielectric_cos(dot((sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), normal_in), eta); } else { f = fabs(((float)(dot((sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), normal_in)))); if(blend != 0.5f) { blend = clamp(blend, 0.0f, 1.0f-1e-5f); blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend); f = pow(((float)(f)), ((float)(blend))); } f = 1.0f - f; } stack_store_float(stack, out_offset, f); } float wireframe(KernelGlobals *kg, ShaderData *sd, float size, int pixel_size, float3 *P) { if((sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { float3 Co[3]; float pixelwidth = 1.0f; int np = 3; if((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_TRIANGLE) triangle_vertices(kg, (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), Co); else motion_triangle_vertices(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->time[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), Co); if(!((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_TRANSFORM_APPLIED)) { object_position_transform(kg, sd, &Co[0]); object_position_transform(kg, sd, &Co[1]); object_position_transform(kg, sd, &Co[2]); } if(pixel_size) { float pixelwidth_x = len((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx - dot((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])) * (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); float pixelwidth_y = len((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy - dot((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy, (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])) * (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; } pixelwidth *= 0.5f * size; pixelwidth *= pixelwidth; for(int i = 0; i < np; i++) { int i2 = i ? i - 1 : np - 1; float3 dir = *P - Co[i]; float3 edge = Co[i] - Co[i2]; float3 crs = cross(edge, dir); if(dot(crs, crs) < (dot(edge, edge) * pixelwidth)) return 1.0f; } } return 0.0f; } void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint in_size = node.y; uint out_fac = node.z; uint use_pixel_size, bump_offset; decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, 0, 0); float size = stack_load_float(stack, in_size); int pixel_size = (int)use_pixel_size; float3 P = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); float f = wireframe(kg, sd, size, pixel_size, &P); if(bump_offset == NODE_BUMP_OFFSET_DX) { float3 Px = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx; f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx); } else if(bump_offset == NODE_BUMP_OFFSET_DY) { float3 Py = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy; f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len((sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy); } if(stack_valid(out_fac)) stack_store_float(stack, out_fac, f); } void svm_node_wavelength(ShaderData *sd, float *stack, uint wavelength, uint color_out) { const float cie_colour_match[81][3] = { {0.0014f,0.0000f,0.0065f}, {0.0022f,0.0001f,0.0105f}, {0.0042f,0.0001f,0.0201f}, {0.0076f,0.0002f,0.0362f}, {0.0143f,0.0004f,0.0679f}, {0.0232f,0.0006f,0.1102f}, {0.0435f,0.0012f,0.2074f}, {0.0776f,0.0022f,0.3713f}, {0.1344f,0.0040f,0.6456f}, {0.2148f,0.0073f,1.0391f}, {0.2839f,0.0116f,1.3856f}, {0.3285f,0.0168f,1.6230f}, {0.3483f,0.0230f,1.7471f}, {0.3481f,0.0298f,1.7826f}, {0.3362f,0.0380f,1.7721f}, {0.3187f,0.0480f,1.7441f}, {0.2908f,0.0600f,1.6692f}, {0.2511f,0.0739f,1.5281f}, {0.1954f,0.0910f,1.2876f}, {0.1421f,0.1126f,1.0419f}, {0.0956f,0.1390f,0.8130f}, {0.0580f,0.1693f,0.6162f}, {0.0320f,0.2080f,0.4652f}, {0.0147f,0.2586f,0.3533f}, {0.0049f,0.3230f,0.2720f}, {0.0024f,0.4073f,0.2123f}, {0.0093f,0.5030f,0.1582f}, {0.0291f,0.6082f,0.1117f}, {0.0633f,0.7100f,0.0782f}, {0.1096f,0.7932f,0.0573f}, {0.1655f,0.8620f,0.0422f}, {0.2257f,0.9149f,0.0298f}, {0.2904f,0.9540f,0.0203f}, {0.3597f,0.9803f,0.0134f}, {0.4334f,0.9950f,0.0087f}, {0.5121f,1.0000f,0.0057f}, {0.5945f,0.9950f,0.0039f}, {0.6784f,0.9786f,0.0027f}, {0.7621f,0.9520f,0.0021f}, {0.8425f,0.9154f,0.0018f}, {0.9163f,0.8700f,0.0017f}, {0.9786f,0.8163f,0.0014f}, {1.0263f,0.7570f,0.0011f}, {1.0567f,0.6949f,0.0010f}, {1.0622f,0.6310f,0.0008f}, {1.0456f,0.5668f,0.0006f}, {1.0026f,0.5030f,0.0003f}, {0.9384f,0.4412f,0.0002f}, {0.8544f,0.3810f,0.0002f}, {0.7514f,0.3210f,0.0001f}, {0.6424f,0.2650f,0.0000f}, {0.5419f,0.2170f,0.0000f}, {0.4479f,0.1750f,0.0000f}, {0.3608f,0.1382f,0.0000f}, {0.2835f,0.1070f,0.0000f}, {0.2187f,0.0816f,0.0000f}, {0.1649f,0.0610f,0.0000f}, {0.1212f,0.0446f,0.0000f}, {0.0874f,0.0320f,0.0000f}, {0.0636f,0.0232f,0.0000f}, {0.0468f,0.0170f,0.0000f}, {0.0329f,0.0119f,0.0000f}, {0.0227f,0.0082f,0.0000f}, {0.0158f,0.0057f,0.0000f}, {0.0114f,0.0041f,0.0000f}, {0.0081f,0.0029f,0.0000f}, {0.0058f,0.0021f,0.0000f}, {0.0041f,0.0015f,0.0000f}, {0.0029f,0.0010f,0.0000f}, {0.0020f,0.0007f,0.0000f}, {0.0014f,0.0005f,0.0000f}, {0.0010f,0.0004f,0.0000f}, {0.0007f,0.0002f,0.0000f}, {0.0005f,0.0002f,0.0000f}, {0.0003f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f} }; float lambda_nm = stack_load_float(stack, wavelength); float ii = (lambda_nm-380.0f) * (1.0f/5.0f); int i = float_to_int(ii); float3 color; if(i < 0 || i >= 80) { color = ((float3)(0.0f, 0.0f, 0.0f)); } else { ii -= i; const float *c = cie_colour_match[i]; color = interp(((float3)(c[0], c[1], c[2])), ((float3)(c[3], c[4], c[5])), ii); } color = xyz_to_rgb(color.x, color.y, color.z); color *= 1.0f/2.52f; color = max(color, ((float3)(0.0f, 0.0f, 0.0f))); if(stack_valid(color_out)) stack_store_float3(stack, color_out, color); } void svm_node_camera(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_vector, uint out_zdepth, uint out_distance) { float distance; float zdepth; float3 vector; Transform tfm = (*kg->data).cam.worldtocamera; vector = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); zdepth = vector.z; distance = len(vector); if(stack_valid(out_vector)) stack_store_float3(stack, out_vector, normalize(vector)); if(stack_valid(out_zdepth)) stack_store_float(stack, out_zdepth, zdepth); if(stack_valid(out_distance)) stack_store_float(stack, out_distance, distance); } void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; switch(type) { case NODE_GEOM_P: data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_GEOM_N: data = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_GEOM_T: data = primitive_tangent(kg, sd); break; case NODE_GEOM_I: data = (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_GEOM_Ng: data = (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_GEOM_uv: data = ((float3)((sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), 0.0f)); break; } stack_store_float3(stack, out_offset, data); } void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; switch(type) { case NODE_GEOM_P: data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx; break; case NODE_GEOM_uv: data = ((float3)((sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]). dx, (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]). dx, 0.0f)); break; default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); } void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; switch(type) { case NODE_GEOM_P: data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy; break; case NODE_GEOM_uv: data = ((float3)((sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]). dy, (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]). dy, 0.0f)); break; default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); } void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float data; switch(type) { case NODE_INFO_OB_LOCATION: { stack_store_float3(stack, out_offset, object_location(kg, sd)); return; } case NODE_INFO_OB_INDEX: data = object_pass_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break; case NODE_INFO_OB_RANDOM: data = object_random_number(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; default: data = 0.0f; break; } stack_store_float(stack, out_offset, data); } void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { switch(type) { case NODE_INFO_PAR_INDEX: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float(stack, out_offset, particle_index(kg, particle_id)); break; } case NODE_INFO_PAR_AGE: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float(stack, out_offset, particle_age(kg, particle_id)); break; } case NODE_INFO_PAR_LIFETIME: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id)); break; } case NODE_INFO_PAR_LOCATION: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float3(stack, out_offset, particle_location(kg, particle_id)); break; } #line 53218 "C:\\cygwin64\\tmp\\OCL6424T10.cl" case NODE_INFO_PAR_SIZE: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float(stack, out_offset, particle_size(kg, particle_id)); break; } case NODE_INFO_PAR_VELOCITY: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id)); break; } case NODE_INFO_PAR_ANGULAR_VELOCITY: { int particle_id = object_particle_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id)); break; } } } #line 53271 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_color_offset, uint fac_offset, uint out_color_offset, int *offset) { uint4 node1 = read_node(kg, offset); float fac = stack_load_float(stack, fac_offset); float3 in_color = stack_load_float3(stack, in_color_offset); float3 color = in_color; float hue = stack_load_float(stack, node1.y); float sat = stack_load_float(stack, node1.z); float val = stack_load_float(stack, node1.w); color = rgb_to_hsv(color); color.x += hue + 0.5f; color.x = fmod((float)(color . x), (float)(1.0f)); color.y *= sat; color.z *= val; color = hsv_to_rgb(color); color.x = fac*color.x + (1.0f - fac)*in_color.x; color.y = fac*color.y + (1.0f - fac)*in_color.y; color.z = fac*color.z + (1.0f - fac)*in_color.z; color.x = max(color.x, 0.0f); color.y = max(color.y, 0.0f); color.z = max(color.z, 0.0f); if(stack_valid(out_color_offset)) stack_store_float3(stack, out_color_offset, color); } float4 svm_image_texture_read(KernelGlobals *kg, int offset) { uchar4 r = kg->__tex_image_packed[offset]; float f = 1.0f/255.0f; return ((float4)(r . x*f, r . y*f, r . z*f, r . w*f)); } int svm_image_texture_wrap_periodic(int x, int width) { x %= width; if(x < 0) x += width; return x; } int svm_image_texture_wrap_clamp(int x, int width) { return clamp(x, 0, width-1); } float svm_image_texture_frac(float x, int *ix) { int i = float_to_int(x) - ((x < 0.0f)? 1: 0); *ix = i; return x - (float)i; } float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha) { if(id < 5) return ((float4)(1.0f, 0.0f, 1.0f, 1.0f)); id -= 5; uint4 info = kg->__tex_image_packed_info[id]; uint width = info.x; uint height = info.y; uint offset = info.z; uint periodic = (info.w & 0x1); uint interpolation = info.w >> 1; float4 r; int ix, iy, nix, niy; if(interpolation == INTERPOLATION_CLOSEST) { svm_image_texture_frac(x*width, &ix); svm_image_texture_frac(y*height, &iy); if(periodic) { ix = svm_image_texture_wrap_periodic(ix, width); iy = svm_image_texture_wrap_periodic(iy, height); } else { ix = svm_image_texture_wrap_clamp(ix, width); iy = svm_image_texture_wrap_clamp(iy, height); } r = svm_image_texture_read(kg, offset + ix + iy*width); } else { float tx = svm_image_texture_frac(x*width, &ix); float ty = svm_image_texture_frac(y*height, &iy); if(periodic) { ix = svm_image_texture_wrap_periodic(ix, width); iy = svm_image_texture_wrap_periodic(iy, height); nix = svm_image_texture_wrap_periodic(ix+1, width); niy = svm_image_texture_wrap_periodic(iy+1, height); } else { ix = svm_image_texture_wrap_clamp(ix, width); iy = svm_image_texture_wrap_clamp(iy, height); nix = svm_image_texture_wrap_clamp(ix+1, width); niy = svm_image_texture_wrap_clamp(iy+1, height); } r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + iy*width); r += (1.0f - ty)*tx*svm_image_texture_read(kg, offset + nix + iy*width); r += ty*(1.0f - tx)*svm_image_texture_read(kg, offset + ix + niy*width); r += ty*tx*svm_image_texture_read(kg, offset + nix + niy*width); } if(use_alpha && r.w != 1.0f && r.w != 0.0f) { float invw = 1.0f/r.w; r.x *= invw; r.y *= invw; r.z *= invw; if(id >= 5) { r.x = min(r.x, 1.0f); r.y = min(r.y, 1.0f); r.z = min(r.z, 1.0f); } } if(srgb) { r.x = color_srgb_to_scene_linear(r.x); r.y = color_srgb_to_scene_linear(r.y); r.z = color_srgb_to_scene_linear(r.z); } return r; } #line 53696 "C:\\cygwin64\\tmp\\OCL6424T10.cl" float3 texco_remap_square(float3 co) { return (co - ((float3)(0.5f, 0.5f, 0.5f))) * 2.0f; } void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint id = node.y; uint co_offset, out_offset, alpha_offset, srgb; decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); float3 co = stack_load_float3(stack, co_offset); float2 tex_co; uint use_alpha = stack_valid(alpha_offset); if(node.w == NODE_IMAGE_PROJ_SPHERE) { co = texco_remap_square(co); tex_co = map_to_sphere(co); } else if(node.w == NODE_IMAGE_PROJ_TUBE) { co = texco_remap_square(co); tex_co = map_to_tube(co); } else { tex_co = ((float2)(co . x, co . y)); } float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha); if(stack_valid(out_offset)) stack_store_float3(stack, out_offset, ((float3)(f . x, f . y, f . z))); if(stack_valid(alpha_offset)) stack_store_float(stack, alpha_offset, f.w); } void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { float3 N = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); N = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) object_inverse_normal_transform(kg, sd, &N); N.x = fabs(((float)(N . x))); N.y = fabs(((float)(N . y))); N.z = fabs(((float)(N . z))); N /= (N.x + N.y + N.z); float3 weight = ((float3)(0.0f, 0.0f, 0.0f)); float blend = as_float(node . w); float limit = 0.5f*(1.0f + blend); if(N.x > limit*(N.x + N.y) && N.x > limit*(N.x + N.z)) { weight.x = 1.0f; } else if(N.y > limit*(N.x + N.y) && N.y > limit*(N.y + N.z)) { weight.y = 1.0f; } else if(N.z > limit*(N.x + N.z) && N.z > limit*(N.y + N.z)) { weight.z = 1.0f; } else if(blend > 0.0f) { if(N.z < (1.0f - limit)*(N.y + N.x)) { weight.x = N.x/(N.x + N.y); weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend); weight.y = 1.0f - weight.x; } else if(N.x < (1.0f - limit)*(N.y + N.z)) { weight.y = N.y/(N.y + N.z); weight.y = saturate((weight.y - 0.5f*(1.0f - blend))/blend); weight.z = 1.0f - weight.y; } else if(N.y < (1.0f - limit)*(N.x + N.z)) { weight.x = N.x/(N.x + N.z); weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend); weight.z = 1.0f - weight.x; } else { weight.x = ((2.0f - limit)*N.x + (limit - 1.0f))/(2.0f*limit - 1.0f); weight.y = ((2.0f - limit)*N.y + (limit - 1.0f))/(2.0f*limit - 1.0f); weight.z = ((2.0f - limit)*N.z + (limit - 1.0f))/(2.0f*limit - 1.0f); } } else { weight.x = 1.0f; } uint co_offset, out_offset, alpha_offset, srgb; decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); float3 co = stack_load_float3(stack, co_offset); uint id = node.y; float4 f = ((float4)(0.0f, 0.0f, 0.0f, 0.0f)); uint use_alpha = stack_valid(alpha_offset); if(weight.x > 0.0f) f += weight.x*svm_image_texture(kg, id, co.y, co.z, srgb, use_alpha); if(weight.y > 0.0f) f += weight.y*svm_image_texture(kg, id, co.x, co.z, srgb, use_alpha); if(weight.z > 0.0f) f += weight.z*svm_image_texture(kg, id, co.y, co.x, srgb, use_alpha); if(stack_valid(out_offset)) stack_store_float3(stack, out_offset, ((float3)(f . x, f . y, f . z))); if(stack_valid(alpha_offset)) stack_store_float(stack, alpha_offset, f.w); } void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint id = node.y; uint co_offset, out_offset, alpha_offset, srgb; uint projection = node.w; decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); float3 co = stack_load_float3(stack, co_offset); float2 uv; co = normalize(co); if(projection == 0) uv = direction_to_equirectangular(co); else uv = direction_to_mirrorball(co); uint use_alpha = stack_valid(alpha_offset); float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); if(stack_valid(out_offset)) stack_store_float3(stack, out_offset, ((float3)(f . x, f . y, f . z))); if(stack_valid(alpha_offset)) stack_store_float(stack, alpha_offset, f.w); } void svm_node_gamma(ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color) { float3 color = stack_load_float3(stack, in_color); float gamma = stack_load_float(stack, in_gamma); if(color.x > 0.0f) color.x = pow(((float)(color . x)), ((float)(gamma))); if(color.y > 0.0f) color.y = pow(((float)(color . y)), ((float)(gamma))); if(color.z > 0.0f) color.z = pow(((float)(color . z)), ((float)(gamma))); if(stack_valid(out_color)) stack_store_float3(stack, out_color, color); } void svm_node_brightness(ShaderData *sd, float *stack, uint in_color, uint out_color, uint node) { uint bright_offset, contrast_offset; float3 color = stack_load_float3(stack, in_color); decode_node_uchar4(node, &bright_offset, &contrast_offset, 0, 0); float brightness = stack_load_float(stack, bright_offset); float contrast = stack_load_float(stack, contrast_offset); float a = 1.0f + contrast; float b = brightness - contrast*0.5f; color.x = max(a*color.x + b, 0.0f); color.y = max(a*color.y + b, 0.0f); color.z = max(a*color.z + b, 0.0f); if(stack_valid(out_color)) stack_store_float3(stack, out_color, color); } float invert(float color, float factor) { return factor*(1.0f - color) + (1.0f - factor) * color; } void svm_node_invert(ShaderData *sd, float *stack, uint in_fac, uint in_color, uint out_color) { float factor = stack_load_float(stack, in_fac); float3 color = stack_load_float3(stack, in_color); color.x = invert(color.x, factor); color.y = invert(color.y, factor); color.z = invert(color.z, factor); if(stack_valid(out_color)) stack_store_float3(stack, out_color, color); } void svm_node_light_path(ShaderData *sd, float *stack, uint type, uint out_offset, int path_flag) { float info = 0.0f; switch(type) { case NODE_LP_camera: info = (path_flag & PATH_RAY_CAMERA)? 1.0f: 0.0f; break; case NODE_LP_shadow: info = (path_flag & PATH_RAY_SHADOW)? 1.0f: 0.0f; break; case NODE_LP_diffuse: info = (path_flag & PATH_RAY_DIFFUSE)? 1.0f: 0.0f; break; case NODE_LP_glossy: info = (path_flag & PATH_RAY_GLOSSY)? 1.0f: 0.0f; break; case NODE_LP_singular: info = (path_flag & PATH_RAY_SINGULAR)? 1.0f: 0.0f; break; case NODE_LP_reflection: info = (path_flag & PATH_RAY_REFLECT)? 1.0f: 0.0f; break; case NODE_LP_transmission: info = (path_flag & PATH_RAY_TRANSMIT)? 1.0f: 0.0f; break; case NODE_LP_volume_scatter: info = (path_flag & PATH_RAY_VOLUME_SCATTER)? 1.0f: 0.0f; break; case NODE_LP_backfacing: info = ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BACKFACING)? 1.0f: 0.0f; break; case NODE_LP_ray_length: info = (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_LP_ray_depth: info = (float)(sd->ray_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_LP_ray_transparent: info = (float)(sd->transparent_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } stack_store_float(stack, out_offset, info); } void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node) { uint strength_offset, out_offset, smooth_offset; decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, 0); float strength = stack_load_float(stack, strength_offset); uint type = node.y; switch(type) { case NODE_LIGHT_FALLOFF_QUADRATIC: break; case NODE_LIGHT_FALLOFF_LINEAR: strength *= (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; case NODE_LIGHT_FALLOFF_CONSTANT: strength *= (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*(sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } float smooth = stack_load_float(stack, smooth_offset); if(smooth > 0.0f) { float squared = (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*(sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); strength *= squared/(smooth + squared); } stack_store_float(stack, out_offset, strength); } float3 svm_magic(float3 p, int n, float distortion) { float x = native_sin(((float)((p . x + p . y + p . z)*5.0f))); float y = native_cos(((float)((-p . x + p . y - p . z)*5.0f))); float z = -native_cos(((float)((-p . x - p . y + p . z)*5.0f))); if(n > 0) { x *= distortion; y *= distortion; z *= distortion; y = -native_cos(((float)(x-y+z))); y *= distortion; if(n > 1) { x = native_cos(((float)(x-y-z))); x *= distortion; if(n > 2) { z = native_sin(((float)(-x-y-z))); z *= distortion; if(n > 3) { x = -native_cos(((float)(-x+y-z))); x *= distortion; if(n > 4) { y = -native_sin(((float)(-x+y+z))); y *= distortion; if(n > 5) { y = -native_cos(((float)(-x+y+z))); y *= distortion; if(n > 6) { x = native_cos(((float)(x+y+z))); x *= distortion; if(n > 7) { z = native_sin(((float)(x+y-z))); z *= distortion; if(n > 8) { x = -native_cos(((float)(-x-y+z))); x *= distortion; if(n > 9) { y = -native_sin(((float)(x-y+z))); y *= distortion; } } } } } } } } } } if(distortion != 0.0f) { distortion *= 2.0f; x /= distortion; y /= distortion; z /= distortion; } return ((float3)(0.5f - x, 0.5f - y, 0.5f - z)); } void svm_node_tex_magic(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint depth; uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset; decode_node_uchar4(node.y, &depth, &color_offset, &fac_offset, 0); decode_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, 0); uint4 node2 = read_node(kg, offset); float3 co = stack_load_float3(stack, co_offset); float scale = stack_load_float_default(stack, scale_offset, node2.x); float distortion = stack_load_float_default(stack, distortion_offset, node2.y); float3 color = svm_magic(co*scale, depth, distortion); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, average(color)); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color); } void svm_node_mapping(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) { float3 v = stack_load_float3(stack, vec_offset); Transform tfm; tfm.x = read_node_float(kg, offset); tfm.y = read_node_float(kg, offset); tfm.z = read_node_float(kg, offset); tfm.w = read_node_float(kg, offset); float3 r = transform_point(&tfm, v); stack_store_float3(stack, out_offset, r); } void svm_node_min_max(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) { float3 v = stack_load_float3(stack, vec_offset); float3 mn = float4_to_float3(read_node_float(kg, offset)); float3 mx = float4_to_float3(read_node_float(kg, offset)); float3 r = min(max(mn, v), mx); stack_store_float3(stack, out_offset, r); } void svm_node_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_normal_offset, uint out_normal_offset, uint out_dot_offset, int *offset) { uint4 node1 = read_node(kg, offset); float3 normal = stack_load_float3(stack, in_normal_offset); float3 direction; direction.x = as_float(node1 . x); direction.y = as_float(node1 . y); direction.z = as_float(node1 . z); direction = normalize(direction); if(stack_valid(out_normal_offset)) stack_store_float3(stack, out_normal_offset, direction); if(stack_valid(out_dot_offset)) stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal))); } float svm_wave(NodeWaveType type, float3 p, float detail, float distortion, float dscale) { float n; if(type == NODE_WAVE_BANDS) n = (p.x + p.y + p.z) * 10.0f; else n = len(p) * 20.0f; if(distortion != 0.0f) n += distortion * noise_turbulence(p*dscale, detail, 0); return 0.5f + 0.5f * native_sin(((float)(n))); } void svm_node_tex_wave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint4 node2 = read_node(kg, offset); uint type; uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset, fac_offset; decode_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset); decode_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset); float3 co = stack_load_float3(stack, co_offset); float scale = stack_load_float_default(stack, scale_offset, node2.x); float detail = stack_load_float_default(stack, detail_offset, node2.y); float distortion = stack_load_float_default(stack, distortion_offset, node2.z); float dscale = stack_load_float_default(stack, dscale_offset, node2.w); float f = svm_wave((NodeWaveType)type, co*scale, detail, distortion, dscale); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, ((float3)(f, f, f))); } void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset) { NodeMath type = (NodeMath)itype; float f1 = stack_load_float(stack, f1_offset); float f2 = stack_load_float(stack, f2_offset); float f = svm_math(type, f1, f2); uint4 node1 = read_node(kg, offset); stack_store_float(stack, node1.y, f); } void svm_node_vector_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint v1_offset, uint v2_offset, int *offset) { NodeVectorMath type = (NodeVectorMath)itype; float3 v1 = stack_load_float3(stack, v1_offset); float3 v2 = stack_load_float3(stack, v2_offset); float f; float3 v; svm_vector_math(&f, &v, type, v1, v2); uint4 node1 = read_node(kg, offset); if(stack_valid(node1.y)) stack_store_float(stack, node1.y, f); if(stack_valid(node1.z)) stack_store_float3(stack, node1.z, v); } float3 svm_mix_blend(float t, float3 col1, float3 col2) { return interp(col1, col2, t); } float3 svm_mix_add(float t, float3 col1, float3 col2) { return interp(col1, col1 + col2, t); } float3 svm_mix_mul(float t, float3 col1, float3 col2) { return interp(col1, col1 * col2, t); } float3 svm_mix_screen(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 one = ((float3)(1.0f, 1.0f, 1.0f)); float3 tm3 = ((float3)(tm, tm, tm)); return one - (tm3 + t*(one - col2))*(one - col1); } float3 svm_mix_overlay(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 outcol = col1; if(outcol.x < 0.5f) outcol.x *= tm + 2.0f*t*col2.x; else outcol.x = 1.0f - (tm + 2.0f*t*(1.0f - col2.x))*(1.0f - outcol.x); if(outcol.y < 0.5f) outcol.y *= tm + 2.0f*t*col2.y; else outcol.y = 1.0f - (tm + 2.0f*t*(1.0f - col2.y))*(1.0f - outcol.y); if(outcol.z < 0.5f) outcol.z *= tm + 2.0f*t*col2.z; else outcol.z = 1.0f - (tm + 2.0f*t*(1.0f - col2.z))*(1.0f - outcol.z); return outcol; } float3 svm_mix_sub(float t, float3 col1, float3 col2) { return interp(col1, col1 - col2, t); } float3 svm_mix_div(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 outcol = col1; if(col2.x != 0.0f) outcol.x = tm*outcol.x + t*outcol.x/col2.x; if(col2.y != 0.0f) outcol.y = tm*outcol.y + t*outcol.y/col2.y; if(col2.z != 0.0f) outcol.z = tm*outcol.z + t*outcol.z/col2.z; return outcol; } float3 svm_mix_diff(float t, float3 col1, float3 col2) { return interp(col1, fabs(col1 - col2), t); } float3 svm_mix_dark(float t, float3 col1, float3 col2) { return min(col1, col2)*t + col1*(1.0f - t); } float3 svm_mix_light(float t, float3 col1, float3 col2) { return max(col1, col2*t); } float3 svm_mix_dodge(float t, float3 col1, float3 col2) { float3 outcol = col1; if(outcol.x != 0.0f) { float tmp = 1.0f - t*col2.x; if(tmp <= 0.0f) outcol.x = 1.0f; else if((tmp = outcol.x/tmp) > 1.0f) outcol.x = 1.0f; else outcol.x = tmp; } if(outcol.y != 0.0f) { float tmp = 1.0f - t*col2.y; if(tmp <= 0.0f) outcol.y = 1.0f; else if((tmp = outcol.y/tmp) > 1.0f) outcol.y = 1.0f; else outcol.y = tmp; } if(outcol.z != 0.0f) { float tmp = 1.0f - t*col2.z; if(tmp <= 0.0f) outcol.z = 1.0f; else if((tmp = outcol.z/tmp) > 1.0f) outcol.z = 1.0f; else outcol.z = tmp; } return outcol; } float3 svm_mix_burn(float t, float3 col1, float3 col2) { float tmp, tm = 1.0f - t; float3 outcol = col1; tmp = tm + t*col2.x; if(tmp <= 0.0f) outcol.x = 0.0f; else if((tmp = (1.0f - (1.0f - outcol.x)/tmp)) < 0.0f) outcol.x = 0.0f; else if(tmp > 1.0f) outcol.x = 1.0f; else outcol.x = tmp; tmp = tm + t*col2.y; if(tmp <= 0.0f) outcol.y = 0.0f; else if((tmp = (1.0f - (1.0f - outcol.y)/tmp)) < 0.0f) outcol.y = 0.0f; else if(tmp > 1.0f) outcol.y = 1.0f; else outcol.y = tmp; tmp = tm + t*col2.z; if(tmp <= 0.0f) outcol.z = 0.0f; else if((tmp = (1.0f - (1.0f - outcol.z)/tmp)) < 0.0f) outcol.z = 0.0f; else if(tmp > 1.0f) outcol.z = 1.0f; else outcol.z = tmp; return outcol; } float3 svm_mix_hue(float t, float3 col1, float3 col2) { float3 outcol = col1; float3 hsv2 = rgb_to_hsv(col2); if(hsv2.y != 0.0f) { float3 hsv = rgb_to_hsv(outcol); hsv.x = hsv2.x; float3 tmp = hsv_to_rgb(hsv); outcol = interp(outcol, tmp, t); } return outcol; } float3 svm_mix_sat(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 outcol = col1; float3 hsv = rgb_to_hsv(outcol); if(hsv.y != 0.0f) { float3 hsv2 = rgb_to_hsv(col2); hsv.y = tm*hsv.y + t*hsv2.y; outcol = hsv_to_rgb(hsv); } return outcol; } float3 svm_mix_val(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 hsv = rgb_to_hsv(col1); float3 hsv2 = rgb_to_hsv(col2); hsv.z = tm*hsv.z + t*hsv2.z; return hsv_to_rgb(hsv); } float3 svm_mix_color(float t, float3 col1, float3 col2) { float3 outcol = col1; float3 hsv2 = rgb_to_hsv(col2); if(hsv2.y != 0.0f) { float3 hsv = rgb_to_hsv(outcol); hsv.x = hsv2.x; hsv.y = hsv2.y; float3 tmp = hsv_to_rgb(hsv); outcol = interp(outcol, tmp, t); } return outcol; } float3 svm_mix_soft(float t, float3 col1, float3 col2) { float tm = 1.0f - t; float3 one = ((float3)(1.0f, 1.0f, 1.0f)); float3 scr = one - (one - col2)*(one - col1); return tm*col1 + t*((one - col1)*col2*col1 + col1*scr); } float3 svm_mix_linear(float t, float3 col1, float3 col2) { return col1 + t*(2.0f*col2 + ((float3)(-1.0f, -1.0f, -1.0f))); } float3 svm_mix_clamp(float3 col) { float3 outcol = col; outcol.x = saturate(col.x); outcol.y = saturate(col.y); outcol.z = saturate(col.z); return outcol; } float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) { float t = saturate(fac); switch(type) { case NODE_MIX_BLEND: return svm_mix_blend(t, c1, c2); case NODE_MIX_ADD: return svm_mix_add(t, c1, c2); case NODE_MIX_MUL: return svm_mix_mul(t, c1, c2); case NODE_MIX_SCREEN: return svm_mix_screen(t, c1, c2); case NODE_MIX_OVERLAY: return svm_mix_overlay(t, c1, c2); case NODE_MIX_SUB: return svm_mix_sub(t, c1, c2); case NODE_MIX_DIV: return svm_mix_div(t, c1, c2); case NODE_MIX_DIFF: return svm_mix_diff(t, c1, c2); case NODE_MIX_DARK: return svm_mix_dark(t, c1, c2); case NODE_MIX_LIGHT: return svm_mix_light(t, c1, c2); case NODE_MIX_DODGE: return svm_mix_dodge(t, c1, c2); case NODE_MIX_BURN: return svm_mix_burn(t, c1, c2); case NODE_MIX_HUE: return svm_mix_hue(t, c1, c2); case NODE_MIX_SAT: return svm_mix_sat(t, c1, c2); case NODE_MIX_VAL: return svm_mix_val (t, c1, c2); case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2); case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2); case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2); case NODE_MIX_CLAMP: return svm_mix_clamp(c1); } return ((float3)(0.0f, 0.0f, 0.0f)); } void svm_node_mix(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset, uint c1_offset, uint c2_offset, int *offset) { uint4 node1 = read_node(kg, offset); float fac = stack_load_float(stack, fac_offset); float3 c1 = stack_load_float3(stack, c1_offset); float3 c2 = stack_load_float3(stack, c2_offset); float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2); stack_store_float3(stack, node1.z, result); } float4 rgb_ramp_lookup(KernelGlobals *kg, int offset, float f, bool interpolate) { f = saturate(f)*(256-1); int i = clamp(float_to_int(f), 0, 256-1); float t = f - (float)i; float4 a = fetch_node_float(kg, offset+i); if(interpolate && t > 0.0f) a = (1.0f - t)*a + t*fetch_node_float(kg, offset+i+1); return a; } void svm_node_rgb_ramp(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint fac_offset, color_offset, alpha_offset; uint interpolate = node.z; decode_node_uchar4(node.y, &fac_offset, &color_offset, &alpha_offset, 0); float fac = stack_load_float(stack, fac_offset); float4 color = rgb_ramp_lookup(kg, *offset, fac, interpolate); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, float4_to_float3(color)); if(stack_valid(alpha_offset)) stack_store_float(stack, alpha_offset, color.w); *offset += 256; } void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint fac_offset = node.y; uint color_offset = node.z; uint out_offset = node.w; float fac = stack_load_float(stack, fac_offset); float3 color = stack_load_float3(stack, color_offset); float r = rgb_ramp_lookup(kg, *offset, color.x, 1).x; float g = rgb_ramp_lookup(kg, *offset, color.y, 1).y; float b = rgb_ramp_lookup(kg, *offset, color.z, 1).z; color = (1.0f - fac)*color + fac*((float3)(r, g, b)); stack_store_float3(stack, out_offset, color); *offset += 256; } void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint fac_offset = node.y; uint color_offset = node.z; uint out_offset = node.w; float fac = stack_load_float(stack, fac_offset); float3 color = stack_load_float3(stack, color_offset); float r = rgb_ramp_lookup(kg, *offset, (color.x + 1.0f)*0.5f, 1).x; float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f, 1).y; float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f, 1).z; color = (1.0f - fac)*color + fac*((float3)(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f)); stack_store_float3(stack, out_offset, color); *offset += 256; } void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint hue_in, uint saturation_in, uint value_in, int *offset) { uint4 node1 = read_node(kg, offset); uint color_out = node1.y; float hue = stack_load_float(stack, hue_in); float saturation = stack_load_float(stack, saturation_in); float value = stack_load_float(stack, value_in); float3 color = hsv_to_rgb(((float3)(hue, saturation, value))); if(stack_valid(color_out)) stack_store_float3(stack, color_out, color); } void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint color_in, uint hue_out, uint saturation_out, int *offset) { uint4 node1 = read_node(kg, offset); uint value_out = node1.y; float3 color = stack_load_float3(stack, color_in); color = rgb_to_hsv(color); if(stack_valid(hue_out)) stack_store_float(stack, hue_out, color.x); if(stack_valid(saturation_out)) stack_store_float(stack, saturation_out, color.y); if(stack_valid(value_out)) stack_store_float(stack, value_out, color.z); } void svm_node_combine_vector(ShaderData *sd, float *stack, uint in_offset, uint vector_index, uint out_offset) { float vector = stack_load_float(stack, in_offset); if(stack_valid(out_offset)) stack_store_float(stack, out_offset+vector_index, vector); } void svm_node_separate_vector(ShaderData *sd, float *stack, uint ivector_offset, uint vector_index, uint out_offset) { float3 vector = stack_load_float3(stack, ivector_offset); if(stack_valid(out_offset)) { if(vector_index == 0) stack_store_float(stack, out_offset, vector.x); else if(vector_index == 1) stack_store_float(stack, out_offset, vector.y); else stack_store_float(stack, out_offset, vector.z); } } float noise_musgrave_fBm(float3 p, float H, float lacunarity, float octaves) { float rmd; float value = 0.0f; float pwr = 1.0f; float pwHL = pow(((float)(lacunarity)), ((float)(-H))); int i; for(i = 0; i < float_to_int(octaves); i++) { value += snoise(p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(((float)(octaves))); if(rmd != 0.0f) value += rmd * snoise(p) * pwr; return value; } float noise_musgrave_multi_fractal(float3 p, float H, float lacunarity, float octaves) { float rmd; float value = 1.0f; float pwr = 1.0f; float pwHL = pow(((float)(lacunarity)), ((float)(-H))); int i; for(i = 0; i < float_to_int(octaves); i++) { value *= (pwr * snoise(p) + 1.0f); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(((float)(octaves))); if(rmd != 0.0f) value *= (rmd * pwr * snoise(p) + 1.0f); return value; } float noise_musgrave_hetero_terrain(float3 p, float H, float lacunarity, float octaves, float offset) { float value, increment, rmd; float pwHL = pow(((float)(lacunarity)), ((float)(-H))); float pwr = pwHL; int i; value = offset + snoise(p); p *= lacunarity; for(i = 1; i < float_to_int(octaves); i++) { increment = (snoise(p) + offset) * pwr * value; value += increment; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(((float)(octaves))); if(rmd != 0.0f) { increment = (snoise(p) + offset) * pwr * value; value += rmd * increment; } return value; } float noise_musgrave_hybrid_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain) { float result, signal, weight, rmd; float pwHL = pow(((float)(lacunarity)), ((float)(-H))); float pwr = pwHL; int i; result = snoise(p) + offset; weight = gain * result; p *= lacunarity; for(i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) { if(weight > 1.0f) weight = 1.0f; signal = (snoise(p) + offset) * pwr; pwr *= pwHL; result += weight * signal; weight *= gain * signal; p *= lacunarity; } rmd = octaves - floor(((float)(octaves))); if(rmd != 0.0f) result += rmd * ((snoise(p) + offset) * pwr); return result; } float noise_musgrave_ridged_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain) { float result, signal, weight; float pwHL = pow(((float)(lacunarity)), ((float)(-H))); float pwr = pwHL; int i; signal = offset - fabs(((float)(snoise(p)))); signal *= signal; result = signal; weight = 1.0f; for(i = 1; i < float_to_int(octaves); i++) { p *= lacunarity; weight = saturate(signal * gain); signal = offset - fabs(((float)(snoise(p)))); signal *= signal; signal *= weight; result += signal * pwr; pwr *= pwHL; } return result; } float svm_musgrave(NodeMusgraveType type, float dimension, float lacunarity, float octaves, float offset, float intensity, float gain, float3 p) { if(type == NODE_MUSGRAVE_MULTIFRACTAL) return intensity*noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves); else if(type == NODE_MUSGRAVE_FBM) return intensity*noise_musgrave_fBm(p, dimension, lacunarity, octaves); else if(type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL) return intensity*noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); else if(type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL) return intensity*noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); else if(type == NODE_MUSGRAVE_HETERO_TERRAIN) return intensity*noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset); return 0.0f; } void svm_node_tex_musgrave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint4 node2 = read_node(kg, offset); uint4 node3 = read_node(kg, offset); uint type, co_offset, color_offset, fac_offset; uint dimension_offset, lacunarity_offset, detail_offset, offset_offset; uint gain_offset, scale_offset; decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset); decode_node_uchar4(node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset); decode_node_uchar4(node.w, &gain_offset, &scale_offset, 0, 0); float3 co = stack_load_float3(stack, co_offset); float dimension = stack_load_float_default(stack, dimension_offset, node2.x); float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y); float detail = stack_load_float_default(stack, detail_offset, node2.z); float foffset = stack_load_float_default(stack, offset_offset, node2.w); float gain = stack_load_float_default(stack, gain_offset, node3.x); float scale = stack_load_float_default(stack, scale_offset, node3.y); dimension = fmax(((float)(dimension)), ((float)(1e-5f))); detail = clamp(detail, 0.0f, 16.0f); lacunarity = fmax(((float)(lacunarity)), ((float)(1e-5f))); float f = svm_musgrave((NodeMusgraveType)type, dimension, lacunarity, detail, foffset, 1.0f, gain, co*scale); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, ((float3)(f, f, f))); } float sky_angle_between(float thetav, float phiv, float theta, float phi) { float cospsi = native_sin(((float)(thetav)))*native_sin(((float)(theta)))*native_cos(((float)(phi - phiv))) + native_cos(((float)(thetav)))*native_cos(((float)(theta))); return safe_acosf(cospsi); } float sky_perez_function(float *lam, float theta, float gamma) { float ctheta = native_cos(((float)(theta))); float cgamma = native_cos(((float)(gamma))); return (1.0f + lam[0]*native_exp(((float)(lam[1]/ctheta)))) * (1.0f + lam[2]*native_exp(((float)(lam[3]*gamma))) + lam[4]*cgamma*cgamma); } float3 sky_radiance_old(KernelGlobals *kg, float3 dir, float sunphi, float suntheta, float radiance_x, float radiance_y, float radiance_z, float *config_x, float *config_y, float *config_z) { float2 spherical = direction_to_spherical(dir); float theta = spherical.x; float phi = spherical.y; float gamma = sky_angle_between(theta, phi, suntheta, sunphi); theta = min(theta, 1.57079637050629f - 0.001f); float x = radiance_y * sky_perez_function(config_y, theta, gamma); float y = radiance_z * sky_perez_function(config_z, theta, gamma); float Y = radiance_x * sky_perez_function(config_x, theta, gamma); float3 xyz = xyY_to_xyz(x, y, Y); return xyz_to_rgb(xyz.x, xyz.y, xyz.z); } float sky_radiance_internal(float *configuration, float theta, float gamma) { float ctheta = native_cos(((float)(theta))); float cgamma = native_cos(((float)(gamma))); float expM = native_exp(((float)(configuration[4] * gamma))); float rayM = cgamma * cgamma; float mieM = (1.0f + rayM) / pow(((float)((1.0f + configuration[8]*configuration[8] - 2.0f*configuration[8]*cgamma))), ((float)(1.5f))); float zenith = native_sqrt(((float)(ctheta))); return (1.0f + configuration[0] * native_exp(((float)(configuration[1] / (ctheta + 0.01f))))) * (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith); } float3 sky_radiance_new(KernelGlobals *kg, float3 dir, float sunphi, float suntheta, float radiance_x, float radiance_y, float radiance_z, float *config_x, float *config_y, float *config_z) { float2 spherical = direction_to_spherical(dir); float theta = spherical.x; float phi = spherical.y; float gamma = sky_angle_between(theta, phi, suntheta, sunphi); theta = min(theta, 1.57079637050629f - 0.001f); float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x; float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y; float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z; return xyz_to_rgb(x, y, z) * (((float)6.283185307179586476925286766559005768)/683); } void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { float sunphi, suntheta, radiance_x, radiance_y, radiance_z; float config_x[9], config_y[9], config_z[9]; uint dir_offset = node.y; uint out_offset = node.z; int sky_model = node.w; float4 data = read_node_float(kg, offset); sunphi = data.x; suntheta = data.y; radiance_x = data.z; radiance_y = data.w; data = read_node_float(kg, offset); radiance_z = data.x; config_x[0] = data.y; config_x[1] = data.z; config_x[2] = data.w; data = read_node_float(kg, offset); config_x[3] = data.x; config_x[4] = data.y; config_x[5] = data.z; config_x[6] = data.w; data = read_node_float(kg, offset); config_x[7] = data.x; config_x[8] = data.y; config_y[0] = data.z; config_y[1] = data.w; data = read_node_float(kg, offset); config_y[2] = data.x; config_y[3] = data.y; config_y[4] = data.z; config_y[5] = data.w; data = read_node_float(kg, offset); config_y[6] = data.x; config_y[7] = data.y; config_y[8] = data.z; config_z[0] = data.w; data = read_node_float(kg, offset); config_z[1] = data.x; config_z[2] = data.y; config_z[3] = data.z; config_z[4] = data.w; data = read_node_float(kg, offset); config_z[5] = data.x; config_z[6] = data.y; config_z[7] = data.z; config_z[8] = data.w; float3 dir = stack_load_float3(stack, dir_offset); float3 f; if(sky_model == 0) f = sky_radiance_old(kg, dir, sunphi, suntheta, radiance_x, radiance_y, radiance_z, config_x, config_y, config_z); else f = sky_radiance_new(kg, dir, sunphi, suntheta, radiance_x, radiance_y, radiance_z, config_x, config_y, config_z); stack_store_float3(stack, out_offset, f); } void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { float3 data; uint type = node.y; uint out_offset = node.z; switch(type) { case NODE_TEXCO_OBJECT: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); if(node.w == 0) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { object_inverse_position_transform(kg, sd, &data); } } else { Transform tfm; tfm.x = read_node_float(kg, offset); tfm.y = read_node_float(kg, offset); tfm.z = read_node_float(kg, offset); tfm.w = read_node_float(kg, offset); data = transform_point(&tfm, data); } break; } case NODE_TEXCO_NORMAL: { data = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { Transform tfm = (*kg->data).cam.worldtocamera; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); else data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { if((path_flag & PATH_RAY_CAMERA) && (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0) && (*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) data = camera_world_to_ndc(kg, sd, (sd->ray_P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); else data = camera_world_to_ndc(kg, sd, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); data.z = 0.0f; break; } case NODE_TEXCO_REFLECTION: { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = 2.0f*dot((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else data = (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } case NODE_TEXCO_DUPLI_GENERATED: { data = object_dupli_generated(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_DUPLI_UV: { data = object_dupli_uv(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_VOLUME_GENERATED: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } } stack_store_float3(stack, out_offset, data); } void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { float3 data; uint type = node.y; uint out_offset = node.z; switch(type) { case NODE_TEXCO_OBJECT: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx; if(node.w == 0) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { object_inverse_position_transform(kg, sd, &data); } } else { Transform tfm; tfm.x = read_node_float(kg, offset); tfm.y = read_node_float(kg, offset); tfm.z = read_node_float(kg, offset); tfm.w = read_node_float(kg, offset); data = transform_point(&tfm, data); } break; } case NODE_TEXCO_NORMAL: { data = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { Transform tfm = (*kg->data).cam.worldtocamera; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx); else data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { if((path_flag & PATH_RAY_CAMERA) && (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0) && (*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) data = camera_world_to_ndc(kg, sd, (sd->ray_P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->ray_dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx); else data = camera_world_to_ndc(kg, sd, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx); data.z = 0.0f; break; } case NODE_TEXCO_REFLECTION: { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = 2.0f*dot((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else data = (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } case NODE_TEXCO_DUPLI_GENERATED: { data = object_dupli_generated(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_DUPLI_UV: { data = object_dupli_uv(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_VOLUME_GENERATED: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dx; break; } } stack_store_float3(stack, out_offset, data); } void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { float3 data; uint type = node.y; uint out_offset = node.z; switch(type) { case NODE_TEXCO_OBJECT: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy; if(node.w == 0) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { object_inverse_position_transform(kg, sd, &data); } } else { Transform tfm; tfm.x = read_node_float(kg, offset); tfm.y = read_node_float(kg, offset); tfm.z = read_node_float(kg, offset); tfm.w = read_node_float(kg, offset); data = transform_point(&tfm, data); } break; } case NODE_TEXCO_NORMAL: { data = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { Transform tfm = (*kg->data).cam.worldtocamera; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy); else data = transform_point(&tfm, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { if((path_flag & PATH_RAY_CAMERA) && (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0) && (*kg->data).cam.type == CAMERA_ORTHOGRAPHIC) data = camera_world_to_ndc(kg, sd, (sd->ray_P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->ray_dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy); else data = camera_world_to_ndc(kg, sd, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy); data.z = 0.0f; break; } case NODE_TEXCO_REFLECTION: { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) data = 2.0f*dot((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) - (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else data = (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); break; } case NODE_TEXCO_DUPLI_GENERATED: { data = object_dupli_generated(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_DUPLI_UV: { data = object_dupli_uv(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); break; } case NODE_TEXCO_VOLUME_GENERATED: { data = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]).dy; break; } } stack_store_float3(stack, out_offset, data); } void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint color_offset, strength_offset, normal_offset, space; decode_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space); float3 color = stack_load_float3(stack, color_offset); color = 2.0f*((float3)(color . x - 0.5f, color . y - 0.5f, color . z - 0.5f)); float3 N; if(space == NODE_NORMAL_MAP_TANGENT) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) == (~0)) { stack_store_float3(stack, normal_offset, ((float3)(0.0f, 0.0f, 0.0f))); return; } AttributeElement attr_elem, attr_sign_elem, attr_normal_elem; int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem); int attr_normal_offset = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL, &attr_normal_elem); if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND || attr_normal_offset == ATTR_STD_NOT_FOUND) { stack_store_float3(stack, normal_offset, ((float3)(0.0f, 0.0f, 0.0f))); return; } float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, 0, 0); float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, 0, 0); float3 normal; if((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_SMOOTH_NORMAL) { normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, 0, 0); } else { normal = (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); object_inverse_normal_transform(kg, sd, &normal); } float3 B = sign * cross(normal, tangent); N = normalize(color.x * tangent + color.y * B + color.z * normal); object_normal_transform(kg, sd, &N); } else { if(space == NODE_NORMAL_MAP_BLENDER_OBJECT || space == NODE_NORMAL_MAP_BLENDER_WORLD) { color.y = -color.y; color.z = -color.z; } N = color; if(space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT) object_normal_transform(kg, sd, &N); else N = normalize(N); } float strength = stack_load_float(stack, strength_offset); if(strength != 1.0f) { strength = max(strength, 0.0f); N = normalize((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) + (N - (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]))*strength); } stack_store_float3(stack, normal_offset, N); } void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint tangent_offset, direction_type, axis; decode_node_uchar4(node.y, &tangent_offset, &direction_type, &axis, 0); float3 tangent; if(direction_type == NODE_TANGENT_UVMAP) { AttributeElement attr_elem; int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); if(attr_offset == ATTR_STD_NOT_FOUND) tangent = ((float3)(0.0f, 0.0f, 0.0f)); else tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, 0, 0); } else { AttributeElement attr_elem; int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); float3 generated; if(attr_offset == ATTR_STD_NOT_FOUND) generated = (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else generated = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, 0, 0); if(axis == NODE_TANGENT_AXIS_X) tangent = ((float3)(0.0f, -(generated . z - 0.5f), (generated . y - 0.5f))); else if(axis == NODE_TANGENT_AXIS_Y) tangent = ((float3)(-(generated . z - 0.5f), 0.0f, (generated . x - 0.5f))); else tangent = ((float3)(-(generated . y - 0.5f), (generated . x - 0.5f), 0.0f)); } object_normal_transform(kg, sd, &tangent); tangent = cross((sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), normalize(cross(tangent, (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])))); stack_store_float3(stack, tangent_offset, tangent); } void svm_node_value_f(KernelGlobals *kg, ShaderData *sd, float *stack, uint ivalue, uint out_offset) { stack_store_float(stack, out_offset, as_float(ivalue)); } void svm_node_value_v(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_offset, int *offset) { uint4 node1 = read_node(kg, offset); float3 p = ((float3)(as_float(node1 . y), as_float(node1 . z), as_float(node1 . w))); stack_store_float3(stack, out_offset, p); } float voronoi_F1_distance(float3 p) { float da = 1e10f; int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z); for(int xx = -1; xx <= 1; xx++) { for(int yy = -1; yy <= 1; yy++) { for(int zz = -1; zz <= 1; zz++) { float3 ip = ((float3)(ix + xx, iy + yy, iz + zz)); float3 vp = ip + cellnoise_color(ip); float d = len_squared(p - vp); da = min(d, da); } } } #line 55797 "C:\\cygwin64\\tmp\\OCL6424T10.cl" return da; } float3 voronoi_F1_color(float3 p) { float da = 1e10f; float3 pa; int ix = floor_to_int(p.x), iy = floor_to_int(p.y), iz = floor_to_int(p.z); for(int xx = -1; xx <= 1; xx++) { for(int yy = -1; yy <= 1; yy++) { for(int zz = -1; zz <= 1; zz++) { float3 ip = ((float3)(ix + xx, iy + yy, iz + zz)); float3 vp = ip + cellnoise_color(ip); float d = len_squared(p - vp); if(d < da) { da = d; pa = vp; } } } } return cellnoise_color(pa); #line 55848 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } float4 svm_voronoi(NodeVoronoiColoring coloring, float3 p) { if(coloring == NODE_VORONOI_INTENSITY) { float fac = voronoi_F1_distance(p); return ((float4)(fac, fac, fac, fac)); } else { float3 color = voronoi_F1_color(p); return ((float4)(color . x, color . y, color . z, average(color))); } } void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint coloring = node.y; uint scale_offset, co_offset, fac_offset, color_offset; decode_node_uchar4(node.z, &scale_offset, &co_offset, &fac_offset, &color_offset); float3 co = stack_load_float3(stack, co_offset); float scale = stack_load_float_default(stack, scale_offset, node.w); float4 result = svm_voronoi((NodeVoronoiColoring)coloring, co*scale); float3 color = ((float3)(result . x, result . y, result . z)); float f = result.w; if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color); } float svm_checker(float3 p) { p.x = (p.x + 0.000001f)*0.999999f; p.y = (p.y + 0.000001f)*0.999999f; p.z = (p.z + 0.000001f)*0.999999f; int xi = float_to_int(fabs(((float)(floor(((float)(p . x))))))); int yi = float_to_int(fabs(((float)(floor(((float)(p . y))))))); int zi = float_to_int(fabs(((float)(floor(((float)(p . z))))))); return ((xi % 2 == yi % 2) == (zi % 2))? 1.0f: 0.0f; } void svm_node_tex_checker(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint co_offset, color1_offset, color2_offset, scale_offset; uint color_offset, fac_offset; decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset); decode_node_uchar4(node.z, &color_offset, &fac_offset, 0, 0); float3 co = stack_load_float3(stack, co_offset); float3 color1 = stack_load_float3(stack, color1_offset); float3 color2 = stack_load_float3(stack, color2_offset); float scale = stack_load_float_default(stack, scale_offset, node.w); float f = svm_checker(co*scale); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, (f == 1.0f)? color1: color2); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); } float brick_noise(int n) { int nn; n = (n + 1013) & 0x7fffffff; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; return 0.5f * ((float)nn / 1073741824.0f); } float2 svm_brick(float3 p, float mortar_size, float bias, float brick_width, float row_height, float offset_amount, int offset_frequency, float squash_amount, int squash_frequency) { int bricknum, rownum; float offset = 0.0f; float x, y; rownum = floor_to_int(p.y / row_height); if(offset_frequency && squash_frequency) { brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; offset = (rownum % offset_frequency) ? 0.0f : (brick_width*offset_amount); } bricknum = floor_to_int((p.x+offset) / brick_width); x = (p.x+offset) - brick_width*bricknum; y = p.y - row_height*rownum; return ((float2)(saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias)), (x < mortar_size || y < mortar_size || x > (brick_width - mortar_size) || y > (row_height - mortar_size)) ? 1.0f : 0.0f)); } void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { uint4 node2 = read_node(kg, offset); uint4 node3 = read_node(kg, offset); uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset; uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset; uint color_offset, fac_offset; uint offset_frequency, squash_frequency; decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset); decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset); decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, 0); decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, 0, 0); float3 co = stack_load_float3(stack, co_offset); float3 color1 = stack_load_float3(stack, color1_offset); float3 color2 = stack_load_float3(stack, color2_offset); float3 mortar = stack_load_float3(stack, mortar_offset); float scale = stack_load_float_default(stack, scale_offset, node2.y); float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z); float bias = stack_load_float_default(stack, bias_offset, node2.w); float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x); float row_height = stack_load_float_default(stack, row_height_offset, node3.y); float offset_amount = as_float(node3 . z); float squash_amount = as_float(node3 . w); float2 f2 = svm_brick(co*scale, mortar_size, bias, brick_width, row_height, offset_amount, offset_frequency, squash_amount, squash_frequency); float tint = f2.x; float f = f2.y; if(f != 1.0f) { float facm = 1.0f - tint; color1 = facm * color1 + tint * color2; } if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, (f == 1.0f)? mortar: color1); if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); } void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { uint itype, ifrom, ito; uint vector_in, vector_out; decode_node_uchar4(node.y, &itype, &ifrom, &ito, 0); decode_node_uchar4(node.z, &vector_in, &vector_out, 0, 0); float3 in = stack_load_float3(stack, vector_in); NodeVectorTransformType type = (NodeVectorTransformType)itype; NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom; NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito; Transform tfm; bool is_object = ((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)); bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR || type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL); if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD) { if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { tfm = (*kg->data).cam.worldtocamera; if(is_direction) in = transform_direction(&tfm, in); else in = transform_point(&tfm, in); } else if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { if(is_direction) object_inverse_dir_transform(kg, sd, &in); else object_inverse_position_transform(kg, sd, &in); } } else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { tfm = (*kg->data).cam.cameratoworld; if(is_direction) in = transform_direction(&tfm, in); else in = transform_point(&tfm, in); } if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { if(is_direction) object_inverse_dir_transform(kg, sd, &in); else object_inverse_position_transform(kg, sd, &in); } } else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { if((to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) && is_object) { if(is_direction) object_dir_transform(kg, sd, &in); else object_position_transform(kg, sd, &in); } if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { tfm = (*kg->data).cam.worldtocamera; if(is_direction) in = transform_direction(&tfm, in); else in = transform_point(&tfm, in); } } if(type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL) in = normalize(in); if(stack_valid(vector_out)) { stack_store_float3(stack, vector_out, in); } } #line 56216 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, int path_flag) { float stack[255]; int offset = (sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_MASK; while(1) { uint4 node = read_node(kg, &offset); switch(node.x) { case NODE_SHADER_JUMP: { if(type == SHADER_TYPE_SURFACE) offset = node.y; else if(type == SHADER_TYPE_VOLUME) offset = node.z; else if(type == SHADER_TYPE_DISPLACEMENT) offset = node.w; else return; break; } case NODE_CLOSURE_BSDF: svm_node_closure_bsdf(kg, sd, stack, node, path_flag, &offset); break; case NODE_CLOSURE_EMISSION: svm_node_closure_emission(sd, stack, node); break; case NODE_CLOSURE_BACKGROUND: svm_node_closure_background(sd, stack, node); break; case NODE_CLOSURE_SET_WEIGHT: svm_node_closure_set_weight(sd, node.y, node.z, node.w); break; case NODE_CLOSURE_WEIGHT: svm_node_closure_weight(sd, stack, node.y); break; case NODE_EMISSION_WEIGHT: svm_node_emission_weight(kg, sd, stack, node); break; case NODE_MIX_CLOSURE: svm_node_mix_closure(sd, stack, node); break; case NODE_JUMP_IF_ZERO: if(stack_load_float(stack, node.z) == 0.0f) offset += node.y; break; case NODE_JUMP_IF_ONE: if(stack_load_float(stack, node.z) == 1.0f) offset += node.y; break; case NODE_GEOMETRY: svm_node_geometry(kg, sd, stack, node.y, node.z); break; case NODE_CONVERT: svm_node_convert(sd, stack, node.y, node.z, node.w); break; case NODE_TEX_COORD: svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset); break; case NODE_VALUE_F: svm_node_value_f(kg, sd, stack, node.y, node.z); break; case NODE_VALUE_V: svm_node_value_v(kg, sd, stack, node.y, &offset); break; case NODE_ATTR: svm_node_attr(kg, sd, stack, node); break; case NODE_GEOMETRY_BUMP_DX: svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z); break; case NODE_GEOMETRY_BUMP_DY: svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z); break; case NODE_SET_DISPLACEMENT: svm_node_set_displacement(sd, stack, node.y); break; case NODE_TEX_IMAGE: svm_node_tex_image(kg, sd, stack, node); break; case NODE_TEX_IMAGE_BOX: svm_node_tex_image_box(kg, sd, stack, node); break; case NODE_TEX_NOISE: svm_node_tex_noise(kg, sd, stack, node, &offset); break; case NODE_SET_BUMP: svm_node_set_bump(kg, sd, stack, node); break; case NODE_ATTR_BUMP_DX: svm_node_attr_bump_dx(kg, sd, stack, node); break; case NODE_ATTR_BUMP_DY: svm_node_attr_bump_dy(kg, sd, stack, node); break; case NODE_TEX_COORD_BUMP_DX: svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset); break; case NODE_TEX_COORD_BUMP_DY: svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset); break; case NODE_CLOSURE_SET_NORMAL: svm_node_set_normal(kg, sd, stack, node.y, node.z); break; case NODE_HSV: svm_node_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_CLOSURE_HOLDOUT: svm_node_closure_holdout(sd, stack, node); break; case NODE_CLOSURE_AMBIENT_OCCLUSION: svm_node_closure_ambient_occlusion(sd, stack, node); break; case NODE_FRESNEL: svm_node_fresnel(sd, stack, node.y, node.z, node.w); break; case NODE_LAYER_WEIGHT: svm_node_layer_weight(sd, stack, node); break; #line 56359 "C:\\cygwin64\\tmp\\OCL6424T10.cl" case NODE_MATH: svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_VECTOR_MATH: svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_RGB_RAMP: svm_node_rgb_ramp(kg, sd, stack, node, &offset); break; case NODE_GAMMA: svm_node_gamma(sd, stack, node.y, node.z, node.w); break; case NODE_BRIGHTCONTRAST: svm_node_brightness(sd, stack, node.y, node.z, node.w); break; case NODE_LIGHT_PATH: svm_node_light_path(sd, stack, node.y, node.z, path_flag); break; case NODE_OBJECT_INFO: svm_node_object_info(kg, sd, stack, node.y, node.z); break; case NODE_PARTICLE_INFO: svm_node_particle_info(kg, sd, stack, node.y, node.z); break; #line 56392 "C:\\cygwin64\\tmp\\OCL6424T10.cl" case NODE_MAPPING: svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); break; case NODE_MIN_MAX: svm_node_min_max(kg, sd, stack, node.y, node.z, &offset); break; case NODE_CAMERA: svm_node_camera(kg, sd, stack, node.y, node.z, node.w); break; case NODE_TEX_ENVIRONMENT: svm_node_tex_environment(kg, sd, stack, node); break; case NODE_TEX_SKY: svm_node_tex_sky(kg, sd, stack, node, &offset); break; case NODE_TEX_GRADIENT: svm_node_tex_gradient(sd, stack, node); break; case NODE_TEX_VORONOI: svm_node_tex_voronoi(kg, sd, stack, node, &offset); break; case NODE_TEX_MUSGRAVE: svm_node_tex_musgrave(kg, sd, stack, node, &offset); break; case NODE_TEX_WAVE: svm_node_tex_wave(kg, sd, stack, node, &offset); break; case NODE_TEX_MAGIC: svm_node_tex_magic(kg, sd, stack, node, &offset); break; case NODE_TEX_CHECKER: svm_node_tex_checker(kg, sd, stack, node); break; case NODE_TEX_BRICK: svm_node_tex_brick(kg, sd, stack, node, &offset); break; case NODE_NORMAL: svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; case NODE_RGB_CURVES: svm_node_rgb_curves(kg, sd, stack, node, &offset); break; case NODE_VECTOR_CURVES: svm_node_vector_curves(kg, sd, stack, node, &offset); break; case NODE_TANGENT: svm_node_tangent(kg, sd, stack, node); break; case NODE_NORMAL_MAP: svm_node_normal_map(kg, sd, stack, node); break; case NODE_INVERT: svm_node_invert(sd, stack, node.y, node.z, node.w); break; case NODE_MIX: svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_SEPARATE_VECTOR: svm_node_separate_vector(sd, stack, node.y, node.z, node.w); break; case NODE_COMBINE_VECTOR: svm_node_combine_vector(sd, stack, node.y, node.z, node.w); break; case NODE_SEPARATE_HSV: svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_COMBINE_HSV: svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); break; case NODE_VECTOR_TRANSFORM: svm_node_vector_transform(kg, sd, stack, node); break; case NODE_WIREFRAME: svm_node_wireframe(kg, sd, stack, node); break; case NODE_WAVELENGTH: svm_node_wavelength(sd, stack, node.y, node.z); break; case NODE_BLACKBODY: svm_node_blackbody(kg, sd, stack, node.y, node.z); break; #line 56493 "C:\\cygwin64\\tmp\\OCL6424T10.cl" case NODE_END: return; default: ; return; } } } #line 56529 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, int bounce, int transparent_bounce) { (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (isect->object == (~0))? kg->__prim_object[isect->prim]: isect->object; (sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = isect->type; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__object_flag[(sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__prim_index[isect->prim]; (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = isect->t; (sd->ray_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = bounce; (sd->transparent_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = transparent_bounce; (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = isect->u; (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = isect->v; #line 56566 "C:\\cygwin64\\tmp\\OCL6424T10.cl" if((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_TRIANGLE) { float3 Ng = triangle_normal(kg, sd); (sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__tri_shader[(sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = triangle_refine(kg, sd, isect, ray); (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; if((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_SMOOTH_NORMAL) (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = triangle_smooth_normal(kg, (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); triangle_dPdudv(kg, (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } else { motion_triangle_shader_setup(kg, sd, isect, ray, 0); } (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -ray->D; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= kg->__shader_flag[((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_MASK)*2]; if(isect->object != (~0)) { object_normal_transform_addrspace(kg, sd, &(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); object_normal_transform_addrspace(kg, sd, &(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); object_dir_transform_addrspace(kg, sd, &(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); object_dir_transform_addrspace(kg, sd, &(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } bool backfacing = (dot((sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])) < 0.0f); if(backfacing) { (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= SD_BACKFACING; (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); } differential_transfer(&(sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), ray->dP, ray->D, ray->dD, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), isect->t); differential_incoming(&(sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), ray->dD); differential_dudv(&(sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &(sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } #line 56704 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, const float3 P, const float3 Ng, const float3 I, int shader, int object, int prim, float u, float v, float t, float time, int bounce, int transparent_bounce) { (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = P; (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = Ng; (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = I; (sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = shader; (sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (prim == (~0))? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE; (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = object; (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = prim; (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = u; (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = v; (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = t; (sd->ray_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = bounce; (sd->transparent_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = transparent_bounce; bool instanced = 0; if((sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) >= 0) instanced = 1; else (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ~(sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); } (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__shader_flag[((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_MASK)*2]; if((sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= kg->__object_flag[(sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])]; #line 56757 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } if((sd->type[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & PRIMITIVE_TRIANGLE) { if((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_SMOOTH_NORMAL) { (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = triangle_smooth_normal(kg, (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); if(instanced) object_normal_transform_addrspace(kg, sd, &(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } triangle_dPdudv(kg, (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), &(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); if(instanced) { object_dir_transform_addrspace(kg, sd, &(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); object_dir_transform_addrspace(kg, sd, &(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } } else { (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ((float3)(0.0f, 0.0f, 0.0f)); (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ((float3)(0.0f, 0.0f, 0.0f)); } if((sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) != (~0)) { bool backfacing = (dot((sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])) < 0.0f); if(backfacing) { (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) |= SD_BACKFACING; (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -(sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); } } (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential3_zero(); (sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential3_zero(); (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential_zero(); (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential_zero(); } void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, int object, int prim, float u, float v) { float3 P, Ng, I = ((float3)(0.0f, 0.0f, 0.0f)); int shader; triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader); shader |= SHADER_SMOOTH_NORMAL; shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, 0x1.fffffep127f, 0, 0); } void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray, int bounce, int transparent_bounce) { (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ray->D; (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -ray->D; (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -ray->D; (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = -ray->D; (sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (*kg->data).background.surface_shader; (sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = kg->__shader_flag[((sd->shader[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SHADER_MASK)*2]; (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0.0f; (sd->ray_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = bounce; (sd->transparent_depth[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = transparent_bounce; (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (~0); (sd->prim[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = (~0); (sd->u[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0.0f; (sd->v[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0.0f; (sd->dPdu[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ((float3)(0.0f, 0.0f, 0.0f)); (sd->dPdv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ((float3)(0.0f, 0.0f, 0.0f)); (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = ray->dD; differential_incoming(&(sd->dI[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); (sd->du[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential_zero(); (sd->dv[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = differential_zero(); } #line 56923 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 56968 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf, int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight) { for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { if(i == skip_bsdf) continue; const ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type <= CLOSURE_BSDF_TRANSPARENT_ID)) { float bsdf_pdf = 0.0f; float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf); if(bsdf_pdf != 0.0f) { bsdf_eval_accum(result_eval, sc->type, eval*sc->weight); sum_pdf += bsdf_pdf*sc->sample_weight; } sum_sample_weight += sc->sample_weight; } } *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f; } void shader_bsdf_eval(KernelGlobals *kg, ShaderData *sd, const float3 omega_in, BsdfEval *eval, float *pdf) { bsdf_eval_init(eval, NBUILTIN_CLOSURES, ((float3)(0.0f, 0.0f, 0.0f)), (*kg->data).film.use_light_pass); _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f); } int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, float randu, float randv, BsdfEval *bsdf_eval, float3 *omega_in, differential3 *domega_in, float *pdf) { int sampled = 0; if((sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) > 1) { float sum = 0.0f; for(sampled = 0; sampled < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); sampled++) { const ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + sampled]); if((sc->type <= CLOSURE_BSDF_TRANSPARENT_ID)) sum += sc->sample_weight; } float r = (sd->randb_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*sum; sum = 0.0f; for(sampled = 0; sampled < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); sampled++) { const ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + sampled]); if((sc->type <= CLOSURE_BSDF_TRANSPARENT_ID)) { sum += sc->sample_weight; if(r <= sum) break; } } if(sampled == (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))])) { *pdf = 0.0f; return LABEL_NONE; } } const ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + sampled]); int label; float3 eval; *pdf = 0.0f; label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if(*pdf != 0.0f) { bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, (*kg->data).film.use_light_pass); if((sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) > 1) { float sweight = sc->sample_weight; _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight); } } return label; } int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval, float3 *omega_in, differential3 *domega_in, float *pdf) { int label; float3 eval; *pdf = 0.0f; label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if(*pdf != 0.0f) bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, (*kg->data).film.use_light_pass); return label; } void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness) { for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type <= CLOSURE_BSDF_TRANSPARENT_ID)) bsdf_blur(kg, sc, roughness); } } float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd) { if((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_HAS_ONLY_VOLUME) return ((float3)(1.0f, 1.0f, 1.0f)); float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) eval += sc->weight; } return eval; } float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd) { float3 alpha = ((float3)(1.0f, 1.0f, 1.0f)) - shader_bsdf_transparency(kg, sd); alpha = max(alpha, ((float3)(0.0f, 0.0f, 0.0f))); alpha = min(alpha, ((float3)(1.0f, 1.0f, 1.0f))); return alpha; } float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSDF_DIFFUSE_ID && sc->type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)) eval += sc->weight; } return eval; } float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSDF_GLOSSY_ID && sc->type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)) eval += sc->weight; } return eval; } float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSDF_TRANSMISSION_ID && sc->type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)) eval += sc->weight; } return eval; } float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSSRDF_CUBIC_ID && sc->type <= CLOSURE_BSSRDF_GAUSSIAN_ID) || (sc->type == CLOSURE_BSDF_BSSRDF_ID)) eval += sc->weight; } return eval; } float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); float3 N = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSDF_DIFFUSE_ID && sc->type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)) { eval += sc->weight*ao_factor; N += sc->N*average(sc->weight); } else if((sc->type == CLOSURE_AMBIENT_OCCLUSION_ID)) { eval += sc->weight; N += (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))])*average(sc->weight); } } if(is_zero(N)) N = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else N = normalize(N); *N_ = N; return eval; } float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_blur_) { float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); float3 N = ((float3)(0.0f, 0.0f, 0.0f)); float texture_blur = 0.0f, weight_sum = 0.0f; for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type >= CLOSURE_BSSRDF_CUBIC_ID && sc->type <= CLOSURE_BSSRDF_GAUSSIAN_ID)) { float avg_weight = fabs(((float)(average(sc->weight)))); N += sc->N*avg_weight; eval += sc->weight; texture_blur += sc->data1*avg_weight; weight_sum += avg_weight; } } if(N_) *N_ = (is_zero(N))? (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]): normalize(N); if(texture_blur_) *texture_blur_ = texture_blur/weight_sum; return eval; } float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc) { return emissive_simple_eval((sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); } float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd) { float3 eval; eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type == CLOSURE_EMISSION_ID)) eval += emissive_eval(kg, sd, sc)*sc->weight; } return eval; } float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd) { float3 weight = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type == CLOSURE_HOLDOUT_ID)) weight += sc->weight; } return weight; } void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx) { (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0; (sd->randb_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = randb; { svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag); #line 57288 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } } float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) { (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0; (sd->randb_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0.0f; #line 57304 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag); float3 eval = ((float3)(0.0f, 0.0f, 0.0f)); for(int i = 0; i < (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); i++) { const ShaderClosure *sc = (&sd->closure[(get_global_id(1) * get_global_size(0) + get_global_id(0)) * 3 + i]); if((sc->type == CLOSURE_BACKGROUND_ID)) eval += sc->weight; } return eval; } } #line 57480 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx) { (sd->num_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0; (sd->randb_closure[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) = 0.0f; #line 57495 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0); } } bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect) { int prim = kg->__prim_index[isect->prim]; int shader = 0; shader = kg->__tri_shader[prim]; #line 57520 "C:\\cygwin64\\tmp\\OCL6424T10.cl" int flag = kg->__shader_flag[(shader & SHADER_MASK)*2]; return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0; } typedef struct LightSample { float3 P; float3 Ng; float3 D; float t; float u, v; float pdf; float eval_fac; int object; int prim; int shader; int lamp; LightType type; } LightSample; float area_light_sample(float3 P, float3 *light_p, float3 axisu, float3 axisv, float randu, float randv, bool sample_coord) { float3 corner = *light_p - axisu * 0.5f - axisv * 0.5f; float axisu_len, axisv_len; float3 x = normalize_len(axisu, &axisu_len); float3 y = normalize_len(axisv, &axisv_len); float3 z = cross(x, y); float3 dir = corner - P; float z0 = dot(dir, z); if(z0 > 0.0f) { z *= -1.0f; z0 *= -1.0f; } float x0 = dot(dir, x); float y0 = dot(dir, y); float x1 = x0 + axisu_len; float y1 = y0 + axisv_len; float3 v00 = ((float3)(x0, y0, z0)); float3 v01 = ((float3)(x0, y1, z0)); float3 v10 = ((float3)(x1, y0, z0)); float3 v11 = ((float3)(x1, y1, z0)); float3 n0 = normalize(cross(v00, v10)); float3 n1 = normalize(cross(v10, v11)); float3 n2 = normalize(cross(v11, v01)); float3 n3 = normalize(cross(v01, v00)); float g0 = safe_acosf(-dot(n0, n1)); float g1 = safe_acosf(-dot(n1, n2)); float g2 = safe_acosf(-dot(n2, n3)); float g3 = safe_acosf(-dot(n3, n0)); float b0 = n0.z; float b1 = n2.z; float b0sq = b0 * b0; float k = ((float)6.283185307179586476925286766559005768) - g2 - g3; float S = g0 + g1 - k; if(sample_coord) { float au = randu * S + k; float fu = (native_cos(((float)(au))) * b0 - b1) / native_sin(((float)(au))); float cu = 1.0f / native_sqrt(((float)(fu * fu + b0sq))) * (fu > 0.0f ? 1.0f : -1.0f); cu = clamp(cu, -1.0f, 1.0f); float xu = -(cu * z0) / native_sqrt(((float)(1.0f - cu * cu))); xu = clamp(xu, x0, x1); float z0sq = z0 * z0; float y0sq = y0 * y0; float y1sq = y1 * y1; float d = native_sqrt(((float)(xu * xu + z0sq))); float h0 = y0 / native_sqrt(((float)(d * d + y0sq))); float h1 = y1 / native_sqrt(((float)(d * d + y1sq))); float hv = h0 + randv * (h1 - h0), hv2 = hv * hv; float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / native_sqrt(((float)(1.0f - hv2))) : y1; *light_p = P + xu * x + yv * y + z0 * z; } if(S != 0.0f) return 1.0f / S; else return 0.0f; } float3 background_map_sample(KernelGlobals *kg, float randu, float randv, float *pdf) { int res = (*kg->data).integrator.pdf_background_res; int cdf_count = res + 1; int first = 0; int count = res; while(count > 0) { int step = count >> 1; int middle = first + step; if(kg->__light_background_marginal_cdf[middle].y < randv) { first = middle + 1; count -= step + 1; } else count = step; } int index_v = max(0, first - 1); ; float2 cdf_v = kg->__light_background_marginal_cdf[index_v]; float2 cdf_next_v = kg->__light_background_marginal_cdf[index_v + 1]; float2 cdf_last_v = kg->__light_background_marginal_cdf[res]; float dv = (randv - cdf_v.y) / (cdf_next_v.y - cdf_v.y); float v = (index_v + dv) / res; first = 0; count = res; while(count > 0) { int step = count >> 1; int middle = first + step; if(kg->__light_background_conditional_cdf[index_v * cdf_count + middle].y < randu) { first = middle + 1; count -= step + 1; } else count = step; } int index_u = max(0, first - 1); ; float2 cdf_u = kg->__light_background_conditional_cdf[index_v * cdf_count + index_u]; float2 cdf_next_u = kg->__light_background_conditional_cdf[index_v * cdf_count + index_u + 1]; float2 cdf_last_u = kg->__light_background_conditional_cdf[index_v * cdf_count + res]; float du = (randu - cdf_u.y) / (cdf_next_u.y - cdf_u.y); float u = (index_u + du) / res; float denom = cdf_last_u.x * cdf_last_v.x; float sin_theta = native_sin(((float)(3.14159274101257f * v))); if(sin_theta == 0.0f || denom == 0.0f) *pdf = 0.0f; else *pdf = (cdf_u.x * cdf_v.x)/(((float)6.283185307179586476925286766559005768) * 3.14159274101257f * sin_theta * denom); return equirectangular_to_direction(u, v); } float background_map_pdf(KernelGlobals *kg, float3 direction) { float2 uv = direction_to_equirectangular(direction); int res = (*kg->data).integrator.pdf_background_res; float sin_theta = native_sin(((float)(uv . y * 3.14159274101257f))); if(sin_theta == 0.0f) return 0.0f; int index_u = clamp(float_to_int(uv.x * res), 0, res - 1); int index_v = clamp(float_to_int(uv.y * res), 0, res - 1); float2 cdf_last_u = kg->__light_background_conditional_cdf[index_v * (res + 1) + res]; float2 cdf_last_v = kg->__light_background_marginal_cdf[res]; float denom = cdf_last_u.x * cdf_last_v.x; if(denom == 0.0f) return 0.0f; float2 cdf_u = kg->__light_background_conditional_cdf[index_v * (res + 1) + index_u]; float2 cdf_v = kg->__light_background_marginal_cdf[index_v]; return (cdf_u.x * cdf_v.x)/(((float)6.283185307179586476925286766559005768) * 3.14159274101257f * sin_theta * denom); } bool background_portal_data_fetch_and_check_side(KernelGlobals *kg, float3 P, int index, float3 *lightpos, float3 *dir) { float4 data0 = kg->__light_data[(index + (*kg->data). integrator . portal_offset)*5 + 0]; float4 data3 = kg->__light_data[(index + (*kg->data). integrator . portal_offset)*5 + 3]; *lightpos = ((float3)(data0 . y, data0 . z, data0 . w)); *dir = ((float3)(data3 . y, data3 . z, data3 . w)); if(dot(*dir, P - *lightpos) > 1e-5f) return 1; return 0; } float background_portal_pdf(KernelGlobals *kg, float3 P, float3 direction, int ignore_portal, bool *is_possible) { float portal_pdf = 0.0f; for(int p = 0; p < (*kg->data).integrator.num_portals; p++) { if(p == ignore_portal) continue; float3 lightpos, dir; if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir)) continue; if(is_possible) { *is_possible = 1; } float t = -(dot(P, dir) - dot(lightpos, dir)) / dot(direction, dir); if(t <= 1e-5f) { continue; } float4 data1 = kg->__light_data[(p + (*kg->data). integrator . portal_offset)*5 + 1]; float4 data2 = kg->__light_data[(p + (*kg->data). integrator . portal_offset)*5 + 2]; float3 axisu = ((float3)(data1 . y, data1 . z, data1 . w)); float3 axisv = ((float3)(data2 . y, data2 . z, data2 . w)); float3 hit = P + t*direction; float3 inplane = hit - lightpos; if(fabs(((float)(dot(inplane, axisu) / dot(axisu, axisu)))) > 0.5f) continue; if(fabs(((float)(dot(inplane, axisv) / dot(axisv, axisv)))) > 0.5f) continue; portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, 0); } return (*kg->data).integrator.num_portals? portal_pdf / (*kg->data).integrator.num_portals: 0.0f; } int background_num_possible_portals(KernelGlobals *kg, float3 P) { int num_possible_portals = 0; for(int p = 0; p < (*kg->data).integrator.num_portals; p++) { float3 lightpos, dir; if(background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir)) num_possible_portals++; } return num_possible_portals; } float3 background_portal_sample(KernelGlobals *kg, float3 P, float randu, float randv, int num_possible, int *sampled_portal, float *pdf) { randv *= num_possible; int portal = (int)randv; randv -= portal; for(int p = 0; p < (*kg->data).integrator.num_portals; p++) { float3 lightpos, dir; if(!background_portal_data_fetch_and_check_side(kg, P, p, &lightpos, &dir)) continue; if(portal == 0) { float4 data1 = kg->__light_data[(p + (*kg->data). integrator . portal_offset)*5 + 1]; float4 data2 = kg->__light_data[(p + (*kg->data). integrator . portal_offset)*5 + 2]; float3 axisu = ((float3)(data1 . y, data1 . z, data1 . w)); float3 axisv = ((float3)(data2 . y, data2 . z, data2 . w)); *pdf = area_light_sample(P, &lightpos, axisu, axisv, randu, randv, 1); *pdf /= num_possible; *sampled_portal = p; return normalize(lightpos - P); } portal--; } return ((float3)(0.0f, 0.0f, 0.0f)); } float3 background_light_sample(KernelGlobals *kg, float3 P, float randu, float randv, float *pdf) { float portal_sampling_pdf = (*kg->data).integrator.portal_pdf; if(portal_sampling_pdf > 0.0f) { int num_portals = background_num_possible_portals(kg, P); if(num_portals > 0) { if(portal_sampling_pdf == 1.0f || randu < portal_sampling_pdf) { if(portal_sampling_pdf < 1.0f) { randu /= portal_sampling_pdf; } int portal; float3 D = background_portal_sample(kg, P, randu, randv, num_portals, &portal, pdf); if(num_portals > 1) { *pdf += background_portal_pdf(kg, P, D, portal, 0); } if(portal_sampling_pdf < 1.0f) { float cdf_pdf = background_map_pdf(kg, D); *pdf = (portal_sampling_pdf * (*pdf) + (1.0f - portal_sampling_pdf) * cdf_pdf); } return D; } else { randu = (randu - portal_sampling_pdf) / (1.0f - portal_sampling_pdf); } } else { if(portal_sampling_pdf == 1.0f) { *pdf = 1.0f / ((float)12.56637061435917295385057353311801153); return sample_uniform_sphere(randu, randv); } else { portal_sampling_pdf = 0.0f; } } } float3 D = background_map_sample(kg, randu, randv, pdf); if(portal_sampling_pdf > 0.0f) { float portal_pdf = background_portal_pdf(kg, P, D, -1, 0); *pdf = (portal_sampling_pdf * portal_pdf + (1.0f - portal_sampling_pdf) * (*pdf)); } return D; } float background_light_pdf(KernelGlobals *kg, float3 P, float3 direction) { float portal_sampling_pdf = (*kg->data).integrator.portal_pdf; if(portal_sampling_pdf > 0.0f) { bool is_possible = 0; float portal_pdf = background_portal_pdf(kg, P, direction, -1, &is_possible); if(portal_pdf == 0.0f) { if(portal_sampling_pdf == 1.0f) { return is_possible? 0.0f: (*kg->data).integrator.pdf_lights / ((float)12.56637061435917295385057353311801153); } else { return background_map_pdf(kg, direction) * (*kg->data).integrator.pdf_lights; } } else { if(portal_sampling_pdf == 1.0f) { return portal_pdf * (*kg->data).integrator.pdf_lights; } else { return (background_map_pdf(kg, direction) * (1.0f - portal_sampling_pdf) + portal_pdf * portal_sampling_pdf) * (*kg->data).integrator.pdf_lights; } } } return background_map_pdf(kg, direction) * (*kg->data).integrator.pdf_lights; } float3 disk_light_sample(float3 v, float randu, float randv) { float3 ru, rv; make_orthonormals(v, &ru, &rv); to_unit_disk(&randu, &randv); return ru*randu + rv*randv; } float3 distant_light_sample(float3 D, float radius, float randu, float randv) { return normalize(D + disk_light_sample(D, randu, randv)*radius); } float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv) { return disk_light_sample(normalize(P - center), randu, randv)*radius; } float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls) { float3 dir = ((float3)(data2 . y, data2 . z, data2 . w)); float3 I = ls->Ng; float spot_angle = data1.w; float spot_smooth = data2.x; float attenuation = dot(dir, I); if(attenuation <= spot_angle) { attenuation = 0.0f; } else { float t = attenuation - spot_angle; if(t < spot_smooth && spot_smooth != 0.0f) attenuation *= smoothstepf(t/spot_smooth); } return attenuation; } float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) { float cos_pi = dot(Ng, I); if(cos_pi <= 0.0f) return 0.0f; return t*t/cos_pi; } void lamp_light_sample(KernelGlobals *kg, int lamp, float randu, float randv, float3 P, LightSample *ls) { float4 data0 = kg->__light_data[lamp*5 + 0]; float4 data1 = kg->__light_data[lamp*5 + 1]; LightType type = (LightType)as_int(data0 . x); ls->type = type; ls->shader = as_int(data1 . x); ls->object = (~0); ls->prim = (~0); ls->lamp = lamp; ls->u = randu; ls->v = randv; if(type == LIGHT_DISTANT) { float3 lightD = ((float3)(data0 . y, data0 . z, data0 . w)); float3 D = lightD; float radius = data1.y; float invarea = data1.w; if(radius > 0.0f) D = distant_light_sample(D, radius, randu, randv); ls->P = D; ls->Ng = D; ls->D = -D; ls->t = 0x1.fffffep127f; float costheta = dot(lightD, D); ls->pdf = invarea/(costheta*costheta*costheta); ls->eval_fac = ls->pdf*(*kg->data).integrator.inv_pdf_lights; } else if(type == LIGHT_BACKGROUND) { float3 D = -background_light_sample(kg, P, randu, randv, &ls->pdf); ls->P = D; ls->Ng = D; ls->D = -D; ls->t = 0x1.fffffep127f; ls->eval_fac = 1.0f; ls->pdf *= (*kg->data).integrator.pdf_lights; } else { ls->P = ((float3)(data0 . y, data0 . z, data0 . w)); if(type == LIGHT_POINT || type == LIGHT_SPOT) { float radius = data1.y; if(radius > 0.0f) ls->P += sphere_light_sample(P, ls->P, radius, randu, randv); ls->D = normalize_len(ls->P - P, &ls->t); ls->Ng = -ls->D; float invarea = data1.z; ls->eval_fac = (0.25f*0.31830987334251f)*invarea; ls->pdf = invarea; if(type == LIGHT_SPOT) { float4 data2 = kg->__light_data[lamp*5 + 2]; ls->eval_fac *= spot_light_attenuation(data1, data2, ls); } ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } else { float4 data2 = kg->__light_data[lamp*5 + 2]; float4 data3 = kg->__light_data[lamp*5 + 3]; float3 axisu = ((float3)(data1 . y, data1 . z, data1 . w)); float3 axisv = ((float3)(data2 . y, data2 . z, data2 . w)); float3 D = ((float3)(data3 . y, data3 . z, data3 . w)); ls->pdf = area_light_sample(P, &ls->P, axisu, axisv, randu, randv, 1); ls->Ng = D; ls->D = normalize_len(ls->P - P, &ls->t); float invarea = data2.x; ls->eval_fac = 0.25f*invarea; if(dot(ls->D, D) > 0.0f) ls->pdf = 0.0f; } ls->eval_fac *= (*kg->data).integrator.inv_pdf_lights; } } bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls) { float4 data0 = kg->__light_data[lamp*5 + 0]; float4 data1 = kg->__light_data[lamp*5 + 1]; LightType type = (LightType)as_int(data0 . x); ls->type = type; ls->shader = as_int(data1 . x); ls->object = (~0); ls->prim = (~0); ls->lamp = lamp; ls->u = 0.0f; ls->v = 0.0f; if(!(ls->shader & SHADER_USE_MIS)) return 0; if(type == LIGHT_DISTANT) { float radius = data1.y; if(radius == 0.0f) return 0; if(t != 0x1.fffffep127f) return 0; float3 lightD = ((float3)(data0 . y, data0 . z, data0 . w)); float costheta = dot(-lightD, D); float cosangle = data1.z; if(costheta < cosangle) return 0; ls->P = -D; ls->Ng = -D; ls->D = D; ls->t = 0x1.fffffep127f; float invarea = data1.w; ls->pdf = invarea/(costheta*costheta*costheta); ls->eval_fac = ls->pdf; } else if(type == LIGHT_POINT || type == LIGHT_SPOT) { float3 lightP = ((float3)(data0 . y, data0 . z, data0 . w)); float radius = data1.y; if(radius == 0.0f) return 0; if(!ray_aligned_disk_intersect(P, D, t, lightP, radius, &ls->P, &ls->t)) return 0; ls->Ng = -D; ls->D = D; float invarea = data1.z; ls->eval_fac = (0.25f*0.31830987334251f)*invarea; ls->pdf = invarea; if(type == LIGHT_SPOT) { float4 data2 = kg->__light_data[lamp*5 + 2]; ls->eval_fac *= spot_light_attenuation(data1, data2, ls); if(ls->eval_fac == 0.0f) return 0; } if(ls->t != 0x1.fffffep127f) ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } else if(type == LIGHT_AREA) { float4 data2 = kg->__light_data[lamp*5 + 2]; float4 data3 = kg->__light_data[lamp*5 + 3]; float invarea = data2.x; if(invarea == 0.0f) return 0; float3 axisu = ((float3)(data1 . y, data1 . z, data1 . w)); float3 axisv = ((float3)(data2 . y, data2 . z, data2 . w)); float3 Ng = ((float3)(data3 . y, data3 . z, data3 . w)); if(dot(D, Ng) >= 0.0f) return 0; float3 light_P = ((float3)(data0 . y, data0 . z, data0 . w)); if(!ray_quad_intersect(P, D, t, light_P, axisu, axisv, &ls->P, &ls->t)) return 0; ls->D = D; ls->Ng = Ng; ls->pdf = area_light_sample(P, &light_P, axisu, axisv, 0, 0, 0); ls->eval_fac = 0.25f*invarea; } else return 0; return 1; } void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time) { if(object >= 0) { Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); ls->P = transform_point(&tfm, ls->P); ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); } } void triangle_light_sample(KernelGlobals *kg, int prim, int object, float randu, float randv, float time, LightSample *ls) { float u, v; randu = native_sqrt(((float)(randu))); u = 1.0f - randu; v = randv*randu; triangle_point_normal(kg, object, prim, u, v, &ls->P, &ls->Ng, &ls->shader); ls->object = object; ls->prim = prim; ls->lamp = (~0); ls->shader |= SHADER_USE_MIS; ls->t = 0.0f; ls->u = u; ls->v = v; ls->type = LIGHT_TRIANGLE; ls->eval_fac = 1.0f; object_transform_light_sample(kg, ls, object, time); } float triangle_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) { float pdf = (*kg->data).integrator.pdf_triangles; float cos_pi = fabs(((float)(dot(Ng, I)))); if(cos_pi == 0.0f) return 0.0f; return t*t*pdf/cos_pi; } int light_distribution_sample(KernelGlobals *kg, float randt) { int first = 0; int len = (*kg->data).integrator.num_distribution + 1; while(len > 0) { int half_len = len >> 1; int middle = first + half_len; if(randt < kg->__light_distribution[middle].x) { len = half_len; } else { first = middle + 1; len = len - half_len - 1; } } return clamp(first-1, 0, (*kg->data).integrator.num_distribution-1); } bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce) { float4 data4 = kg->__light_data[index*5 + 4]; return (bounce > as_int(data4 . x)); } void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, int bounce, LightSample *ls) { int index = light_distribution_sample(kg, randt); float4 l = kg->__light_distribution[index]; int prim = as_int(l . y); if(prim >= 0) { int object = as_int(l . w); int shader_flag = as_int(l . z); triangle_light_sample(kg, prim, object, randu, randv, time, ls); ls->D = normalize_len(ls->P - P, &ls->t); ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t); ls->shader |= shader_flag; } else { int lamp = -prim-1; if((light_select_reached_max_bounces(kg, lamp, bounce))) { ls->pdf = 0.0f; return; } lamp_light_sample(kg, lamp, randu, randv, P, ls); } } int light_select_num_samples(KernelGlobals *kg, int index) { float4 data3 = kg->__light_data[index*5 + 3]; return as_int(data3 . x); } void kernel_write_pass_float(__global float *buffer, int sample, float value) { __global float *buf = buffer; atomic_add_float(buf, value); } void kernel_write_pass_float3(__global float *buffer, int sample, float3 value) { __global float *buf_x = buffer + 0; __global float *buf_y = buffer + 1; __global float *buf_z = buffer + 2; atomic_add_float(buf_x, value.x); atomic_add_float(buf_y, value.y); atomic_add_float(buf_z, value.z); } void kernel_write_pass_float4(__global float *buffer, int sample, float4 value) { __global float *buf_x = buffer + 0; __global float *buf_y = buffer + 1; __global float *buf_z = buffer + 2; __global float *buf_w = buffer + 3; atomic_add_float(buf_x, value.x); atomic_add_float(buf_y, value.y); atomic_add_float(buf_z, value.z); atomic_add_float(buf_w, value.w); } void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, ShaderData *sd, int sample, __global PathState *state, float3 throughput) { int path_flag = state->flag; if(!(path_flag & PATH_RAY_CAMERA)) return; int flag = (*kg->data).film.pass_flag; if(!(flag & (~0))) return; if(!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) { if(!((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_TRANSPARENT) || (*kg->data).film.pass_alpha_threshold == 0.0f || average(shader_bsdf_alpha(kg, sd)) >= (*kg->data).film.pass_alpha_threshold) { if(sample == 0) { if(flag & PASS_DEPTH) { float depth = camera_distance(kg, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); kernel_write_pass_float(buffer + (*kg->data).film.pass_depth, sample, depth); } if(flag & PASS_OBJECT_ID) { float id = object_pass_id(kg, (sd->object[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); kernel_write_pass_float(buffer + (*kg->data).film.pass_object_id, sample, id); } if(flag & PASS_MATERIAL_ID) { float id = shader_pass_id(kg, sd); kernel_write_pass_float(buffer + (*kg->data).film.pass_material_id, sample, id); } } if(flag & PASS_NORMAL) { float3 normal = (sd->N[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); kernel_write_pass_float3(buffer + (*kg->data).film.pass_normal, sample, normal); } if(flag & PASS_UV) { float3 uv = primitive_uv(kg, sd); kernel_write_pass_float3(buffer + (*kg->data).film.pass_uv, sample, uv); } if(flag & PASS_MOTION) { float4 speed = primitive_motion_vector(kg, sd); kernel_write_pass_float4(buffer + (*kg->data).film.pass_motion, sample, speed); kernel_write_pass_float(buffer + (*kg->data).film.pass_motion_weight, sample, 1.0f); } state->flag |= PATH_RAY_SINGLE_PASS_DONE; } } if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT)) L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput; if(flag & (PASS_GLOSSY_INDIRECT|PASS_GLOSSY_COLOR|PASS_GLOSSY_DIRECT)) L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput; if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT)) L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput; if(flag & (PASS_SUBSURFACE_INDIRECT|PASS_SUBSURFACE_COLOR|PASS_SUBSURFACE_DIRECT)) L->color_subsurface += shader_bsdf_subsurface(kg, sd)*throughput; if(flag & PASS_MIST) { float mist_start = (*kg->data).film.mist_start; float mist_inv_depth = (*kg->data).film.mist_inv_depth; float depth = camera_distance(kg, (sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); float mist = saturate((depth - mist_start)*mist_inv_depth); float mist_falloff = (*kg->data).film.mist_falloff; if(mist_falloff == 1.0f) ; else if(mist_falloff == 2.0f) mist = mist*mist; else if(mist_falloff == 0.5f) mist = native_sqrt(((float)(mist))); else mist = pow(((float)(mist)), ((float)(mist_falloff))); float3 alpha = shader_bsdf_alpha(kg, sd); L->mist += (1.0f - mist)*average(throughput*alpha); } } void kernel_write_light_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, int sample) { int flag = (*kg->data).film.pass_flag; if(!(*kg->data).film.use_light_pass) return; if(flag & PASS_DIFFUSE_INDIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_diffuse_indirect, sample, L->indirect_diffuse); if(flag & PASS_GLOSSY_INDIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_glossy_indirect, sample, L->indirect_glossy); if(flag & PASS_TRANSMISSION_INDIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_transmission_indirect, sample, L->indirect_transmission); if(flag & PASS_SUBSURFACE_INDIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_subsurface_indirect, sample, L->indirect_subsurface); if(flag & PASS_DIFFUSE_DIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_diffuse_direct, sample, L->direct_diffuse); if(flag & PASS_GLOSSY_DIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_glossy_direct, sample, L->direct_glossy); if(flag & PASS_TRANSMISSION_DIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_transmission_direct, sample, L->direct_transmission); if(flag & PASS_SUBSURFACE_DIRECT) kernel_write_pass_float3(buffer + (*kg->data).film.pass_subsurface_direct, sample, L->direct_subsurface); if(flag & PASS_EMISSION) kernel_write_pass_float3(buffer + (*kg->data).film.pass_emission, sample, L->emission); if(flag & PASS_BACKGROUND) kernel_write_pass_float3(buffer + (*kg->data).film.pass_background, sample, L->background); if(flag & PASS_AO) kernel_write_pass_float3(buffer + (*kg->data).film.pass_ao, sample, L->ao); if(flag & PASS_DIFFUSE_COLOR) kernel_write_pass_float3(buffer + (*kg->data).film.pass_diffuse_color, sample, L->color_diffuse); if(flag & PASS_GLOSSY_COLOR) kernel_write_pass_float3(buffer + (*kg->data).film.pass_glossy_color, sample, L->color_glossy); if(flag & PASS_TRANSMISSION_COLOR) kernel_write_pass_float3(buffer + (*kg->data).film.pass_transmission_color, sample, L->color_transmission); if(flag & PASS_SUBSURFACE_COLOR) kernel_write_pass_float3(buffer + (*kg->data).film.pass_subsurface_color, sample, L->color_subsurface); if(flag & PASS_SHADOW) { float4 shadow = L->shadow; shadow.w = (*kg->data).film.pass_shadow_scale; kernel_write_pass_float4(buffer + (*kg->data).film.pass_shadow, sample, shadow); } if(flag & PASS_MIST) kernel_write_pass_float(buffer + (*kg->data).film.pass_mist, sample, 1.0f - L->mist); } #line 59039 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 60233 "C:\\cygwin64\\tmp\\OCL6424T10.cl" void path_state_init(KernelGlobals *kg, __global PathState *state, __global RNG *rng, int sample, __global Ray *ray) { state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP; state->rng_offset = PRNG_BASE_NUM; state->sample = sample; state->num_samples = (*kg->data).integrator.aa_samples; state->bounce = 0; state->diffuse_bounce = 0; state->glossy_bounce = 0; state->transmission_bounce = 0; state->transparent_bounce = 0; state->min_ray_pdf = 0x1.fffffep127f; state->ray_pdf = 0.0f; state->ray_t = 0.0f; #line 60286 "C:\\cygwin64\\tmp\\OCL6424T10.cl" } void path_state_next(KernelGlobals *kg, __global PathState *state, int label) { if(label & LABEL_TRANSPARENT) { state->flag |= PATH_RAY_TRANSPARENT; state->transparent_bounce++; if(!(*kg->data).integrator.transparent_shadows) state->flag |= PATH_RAY_MIS_SKIP; return; } state->bounce++; #line 60317 "C:\\cygwin64\\tmp\\OCL6424T10.cl" { if(label & LABEL_REFLECT) { state->flag |= PATH_RAY_REFLECT; state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); if(label & LABEL_DIFFUSE) state->diffuse_bounce++; else state->glossy_bounce++; } else { ; state->flag |= PATH_RAY_TRANSMIT; state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); state->transmission_bounce++; } if(label & LABEL_DIFFUSE) { state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR; state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); } else if(label & LABEL_GLOSSY) { state->flag |= PATH_RAY_GLOSSY; state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); } else { ; state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP; state->flag &= ~PATH_RAY_DIFFUSE; } } state->rng_offset += PRNG_BOUNCE_NUM; } uint path_state_ray_visibility(KernelGlobals *kg, PathState *state) { uint flag = state->flag & PATH_RAY_ALL_VISIBILITY; if(flag & PATH_RAY_TRANSMIT) flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY); if(state->flag & PATH_RAY_VOLUME_SCATTER) flag |= PATH_RAY_DIFFUSE; if(flag & PATH_RAY_CAMERA) flag |= (*kg->data).integrator.layer_flag; return flag; } float path_state_terminate_probability(KernelGlobals *kg, __global PathState *state, const float3 throughput) { if(state->flag & PATH_RAY_TRANSPARENT) { if(state->transparent_bounce >= (*kg->data).integrator.transparent_max_bounce) return 0.0f; else if(state->transparent_bounce <= (*kg->data).integrator.transparent_min_bounce) return 1.0f; } else { if((state->bounce >= (*kg->data).integrator.max_bounce) || (state->diffuse_bounce >= (*kg->data).integrator.max_diffuse_bounce) || (state->glossy_bounce >= (*kg->data).integrator.max_glossy_bounce) || (state->transmission_bounce >= (*kg->data).integrator.max_transmission_bounce)) { return 0.0f; } else if(state->bounce <= (*kg->data).integrator.min_bounce) { return 1.0f; } } return average(throughput); } #line 60583 "C:\\cygwin64\\tmp\\OCL6424T10.cl" bool shadow_blocked(KernelGlobals *kg, __global PathState *state, __global Ray *ray_input, float3 *shadow , ShaderData *sd_mem, Intersection *isect_mem ) { *shadow = ((float3)(1.0f, 1.0f, 1.0f)); if(ray_input->t == 0.0f) return 0; Ray private_ray = *ray_input; Ray *ray = &private_ray; Intersection *isect = isect_mem; bool blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect, 0, 0.0f, 0.0f); if(blocked && (*kg->data).integrator.transparent_shadows) { if(shader_transparent_shadow(kg, isect)) { float3 throughput = ((float3)(1.0f, 1.0f, 1.0f)); float3 Pend = ray->P + ray->D*ray->t; int bounce = state->transparent_bounce; for(;;) { if(bounce >= (*kg->data).integrator.transparent_max_bounce) return 1; if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect, 0, 0.0f, 0.0f)) { *shadow *= throughput; return 0; } if(!shader_transparent_shadow(kg, isect)) return 1; #line 60657 "C:\\cygwin64\\tmp\\OCL6424T10.cl" ShaderData *sd = sd_mem; shader_setup_from_ray(kg, sd, isect, ray, state->bounce+1, bounce); if(!((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_HAS_ONLY_VOLUME)) { shader_eval_surface(kg, sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); throughput *= shader_bsdf_transparency(kg, sd); } if(is_zero(throughput)) return 1; ray->P = ray_offset((sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), -(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); if(ray->t != 0x1.fffffep127f) ray->D = normalize_len(Pend - ray->P, &ray->t); bounce++; } } } #line 60697 "C:\\cygwin64\\tmp\\OCL6424T10.cl" return blocked; } float3 direct_emissive_eval(KernelGlobals *kg, LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce ,ShaderData *sd_input ) { ShaderData *sd = sd_input; float3 eval; if(ls->type == LIGHT_BACKGROUND) { Ray ray; ray.D = ls->D; ray.P = ls->P; ray.t = 1.0f; ray.dP = differential3_zero(); ray.dD = dI; shader_setup_from_background(kg, sd, &ray, bounce+1, transparent_bounce); eval = shader_eval_background(kg, sd, 0, SHADER_CONTEXT_EMISSION); } else { shader_setup_from_sample(kg, sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, transparent_bounce); ls->Ng = (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); shader_eval_surface(kg, sd, 0.0f, 0, SHADER_CONTEXT_EMISSION); if((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_EMISSION) eval = shader_emissive_eval(kg, sd); else eval = ((float3)(0.0f, 0.0f, 0.0f)); } eval *= ls->eval_fac; return eval; } bool direct_emission(KernelGlobals *kg, ShaderData *sd, LightSample *ls, Ray *ray, BsdfEval *eval, bool *is_lamp, int bounce, int transparent_bounce , ShaderData *sd_DL ) { if(ls->pdf == 0.0f) return 0; differential3 dD = differential3_zero(); float3 light_eval = direct_emissive_eval(kg, ls, -ls->D, dD, ls->t, (sd->time[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), bounce, transparent_bounce ,sd_DL ); if(is_zero(light_eval)) return 0; float bsdf_pdf; #line 60817 "C:\\cygwin64\\tmp\\OCL6424T10.cl" shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf); if(ls->shader & SHADER_USE_MIS) { float mis_weight = power_heuristic(ls->pdf, bsdf_pdf); light_eval *= mis_weight; } bsdf_eval_mul(eval, light_eval/ls->pdf); if(ls->shader & SHADER_EXCLUDE_ANY) { if(ls->shader & SHADER_EXCLUDE_DIFFUSE) eval->diffuse = ((float3)(0.0f, 0.0f, 0.0f)); if(ls->shader & SHADER_EXCLUDE_GLOSSY) eval->glossy = ((float3)(0.0f, 0.0f, 0.0f)); if(ls->shader & SHADER_EXCLUDE_TRANSMIT) eval->transmission = ((float3)(0.0f, 0.0f, 0.0f)); if(ls->shader & SHADER_EXCLUDE_SCATTER) eval->scatter = ((float3)(0.0f, 0.0f, 0.0f)); } if(bsdf_eval_is_zero(eval)) return 0; if(ls->shader & SHADER_CAST_SHADOW) { bool transmit = (dot((sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), ls->D) < 0.0f); ray->P = ray_offset((sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (transmit)? -(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]): (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); if(ls->t == 0x1.fffffep127f) { ray->D = ls->D; ray->t = ls->t; } else { ray->D = ray_offset(ls->P, ls->Ng) - ray->P; ray->D = normalize_len(ray->D, &ray->t); } ray->dP = (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); ray->dD = differential3_zero(); } else { ray->t = 0.0f; } *is_lamp = (ls->prim == (~0) && ls->type != LIGHT_BACKGROUND); return 1; } float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) { float3 L = shader_emissive_eval(kg, sd); if(!(path_flag & PATH_RAY_MIS_SKIP) && ((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_USE_MIS)) { float pdf = triangle_light_pdf(kg, (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (sd->I[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), t); float mis_weight = power_heuristic(bsdf_pdf, pdf); return L*mis_weight; } return L; } bool indirect_lamp_emission(KernelGlobals *kg, PathState *state, Ray *ray, float3 *emission ,ShaderData *sd ) { bool hit_lamp = 0; *emission = ((float3)(0.0f, 0.0f, 0.0f)); for(int lamp = 0; lamp < (*kg->data).integrator.num_all_lights; lamp++) { LightSample ls; if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls)) continue; if(ls.shader & SHADER_EXCLUDE_ANY) { if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || ((ls.shader & SHADER_EXCLUDE_GLOSSY) && ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) || ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) continue; } float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, state->bounce, state->transparent_bounce ,sd ); #line 60947 "C:\\cygwin64\\tmp\\OCL6424T10.cl" if(!(state->flag & PATH_RAY_MIS_SKIP)) { float mis_weight = power_heuristic(state->ray_pdf, ls.pdf); L *= mis_weight; } *emission += L; hit_lamp = 1; } return hit_lamp; } float3 indirect_background(KernelGlobals *kg, __global PathState *state, __global Ray *ray ,ShaderData *sd_global ) { int shader = (*kg->data).background.surface_shader; if(shader & SHADER_EXCLUDE_ANY) { if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) || ((shader & SHADER_EXCLUDE_GLOSSY) && ((state->flag & (PATH_RAY_GLOSSY|PATH_RAY_REFLECT)) == (PATH_RAY_GLOSSY|PATH_RAY_REFLECT))) || ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) || ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) || ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER))) return ((float3)(0.0f, 0.0f, 0.0f)); } Ray priv_ray = *ray; shader_setup_from_background(kg, sd_global, &priv_ray, state->bounce+1, state->transparent_bounce); float3 L = shader_eval_background(kg, sd_global, state->flag, SHADER_CONTEXT_EMISSION); #line 60995 "C:\\cygwin64\\tmp\\OCL6424T10.cl" int res = (*kg->data).integrator.pdf_background_res; if(!(state->flag & PATH_RAY_MIS_SKIP) && res) { float pdf = background_light_pdf(kg, ray->P, ray->D); float mis_weight = power_heuristic(state->ray_pdf, pdf); return L*mis_weight; } return L; } void kernel_path_trace_setup(KernelGlobals *kg, __global uint *rng_state, int sample, int x, int y, __global RNG *rng, __global Ray *ray) { float filter_u; float filter_v; int num_samples = (*kg->data).integrator.aa_samples; path_rng_init(kg, rng_state, sample, num_samples, rng, x, y, &filter_u, &filter_v); float lens_u = 0.0f, lens_v = 0.0f; if((*kg->data).cam.aperturesize > 0.0f) path_rng_2D(kg, rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); float time = 0.0f; camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray); } #line 61256 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 61294 "C:\\cygwin64\\tmp\\OCL6424T10.cl" bool kernel_path_surface_bounce(KernelGlobals *kg, __global RNG *rng, ShaderData *sd, __global float3 *throughput, __global PathState *state, PathRadiance *L, __global Ray *ray) { if((sd->flag[(get_global_id(1) * get_global_size(0) + get_global_id(0))]) & SD_BSDF) { float bsdf_pdf; BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; float bsdf_u, bsdf_v; path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) return 0; path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); if(!(label & LABEL_TRANSPARENT)) { state->ray_pdf = bsdf_pdf; state->ray_t = 0.0f; state->min_ray_pdf = fmin(((float)(bsdf_pdf)), ((float)(state ->min_ray_pdf))); } path_state_next(kg, state, label); ray->P = ray_offset((sd->P[(get_global_id(1) * get_global_size(0) + get_global_id(0))]), (label & LABEL_TRANSMIT)? -(sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))]): (sd->Ng[(get_global_id(1) * get_global_size(0) + get_global_id(0))])); ray->D = bsdf_omega_in; if(state->bounce == 0) ray->t -= (sd->ray_length[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); else ray->t = 0x1.fffffep127f; ray->dP = (sd->dP[(get_global_id(1) * get_global_size(0) + get_global_id(0))]); ray->dD = bsdf_domega_in; return 1; } #line 61375 "C:\\cygwin64\\tmp\\OCL6424T10.cl" else { return 0; } } #line 61653 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #line 61714 "C:\\cygwin64\\tmp\\OCL6424T10.cl" #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable #pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable void enqueue_ray_index( int ray_index, int queue_number, __global int *queues, int queue_size, __global int *queue_index) { int my_queue_index = atomic_inc(&queue_index[queue_number]) + (queue_number * queue_size); queues[my_queue_index] = ray_index; } int get_ray_index( int thread_index, int queue_number, __global int *queues, int queuesize, int empty_queue) { int ray_index = queues[queue_number * queuesize + thread_index]; if(empty_queue && ray_index != -1) { queues[queue_number * queuesize + thread_index] = -1; } return ray_index; } void enqueue_ray_index_local( int ray_index, int queue_number, char enqueue_flag, int queuesize, __local unsigned int *local_queue_atomics, __global int *Queue_data, __global int *Queue_index) { int lidx = get_local_id(1) * get_local_size(0) + get_local_id(0); unsigned int lqidx; if(enqueue_flag) { lqidx = atomic_inc(local_queue_atomics); } barrier(CLK_LOCAL_MEM_FENCE); if(lidx == 0) { *local_queue_atomics = atomic_add(&Queue_index[queue_number], *local_queue_atomics); } barrier(CLK_LOCAL_MEM_FENCE); if(enqueue_flag) { unsigned int my_gqidx = queue_number * queuesize + (*local_queue_atomics) + lqidx; Queue_data[my_gqidx] = ray_index; } } unsigned int get_local_queue_index( int queue_number, __local unsigned int *local_queue_atomics) { int my_lqidx = atomic_inc(&local_queue_atomics[queue_number]); return my_lqidx; } unsigned int get_global_per_queue_offset( int queue_number, __local unsigned int *local_queue_atomics, __global int* global_queue_atomics) { unsigned int queue_offset = atomic_add(&global_queue_atomics[queue_number], local_queue_atomics[queue_number]); return queue_offset; } unsigned int get_global_queue_index( int queue_number, int queuesize, unsigned int lqidx, __local unsigned int * global_per_queue_offset) { int my_gqidx = queuesize * queue_number + lqidx + global_per_queue_offset[queue_number]; return my_gqidx; } #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable uint get_group_id_with_ray_index(uint ray_index, uint tile_dim_x, uint tile_dim_y, uint parallel_samples, int dim) { if(dim == 0) { uint x_span = ray_index % (tile_dim_x * parallel_samples); return x_span / get_local_size(0); } else { ; uint y_span = ray_index / (tile_dim_x * parallel_samples); return y_span / get_local_size(1); } } uint get_total_work(uint tile_dim_x, uint tile_dim_y, uint grp_idx, uint grp_idy, uint num_samples) { uint threads_within_tile_border_x = (grp_idx == (get_num_groups(0) - 1)) ? tile_dim_x % get_local_size(0) : get_local_size(0); uint threads_within_tile_border_y = (grp_idy == (get_num_groups(1) - 1)) ? tile_dim_y % get_local_size(1) : get_local_size(1); threads_within_tile_border_x = (threads_within_tile_border_x == 0) ? get_local_size(0) : threads_within_tile_border_x; threads_within_tile_border_y = (threads_within_tile_border_y == 0) ? get_local_size(1) : threads_within_tile_border_y; return threads_within_tile_border_x * threads_within_tile_border_y * num_samples; } int get_next_work(__global uint *work_pool, __private uint *my_work, uint tile_dim_x, uint tile_dim_y, uint num_samples, uint parallel_samples, uint ray_index) { uint grp_idx = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 0); uint grp_idy = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 1); uint total_work = get_total_work(tile_dim_x, tile_dim_y, grp_idx, grp_idy, num_samples); uint group_index = grp_idy * get_num_groups(0) + grp_idx; *my_work = atomic_inc(&work_pool[group_index]); return (*my_work < total_work) ? 1 : 0; } uint get_my_sample(uint my_work, uint tile_dim_x, uint tile_dim_y, uint parallel_samples, uint ray_index) { uint grp_idx = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 0); uint grp_idy = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 1); uint threads_within_tile_border_x = (grp_idx == (get_num_groups(0) - 1)) ? tile_dim_x % get_local_size(0) : get_local_size(0); uint threads_within_tile_border_y = (grp_idy == (get_num_groups(1) - 1)) ? tile_dim_y % get_local_size(1) : get_local_size(1); threads_within_tile_border_x = (threads_within_tile_border_x == 0) ? get_local_size(0) : threads_within_tile_border_x; threads_within_tile_border_y = (threads_within_tile_border_y == 0) ? get_local_size(1) : threads_within_tile_border_y; return my_work / (threads_within_tile_border_x * threads_within_tile_border_y); } void get_pixel_tile_position(__private uint *pixel_x, __private uint *pixel_y, __private uint *tile_x, __private uint *tile_y, uint my_work, uint tile_dim_x, uint tile_dim_y, uint tile_offset_x, uint tile_offset_y, uint parallel_samples, uint ray_index) { uint grp_idx = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 0); uint grp_idy = get_group_id_with_ray_index(ray_index, tile_dim_x, tile_dim_y, parallel_samples, 1); uint threads_within_tile_border_x = (grp_idx == (get_num_groups(0) - 1)) ? tile_dim_x % get_local_size(0) : get_local_size(0); uint threads_within_tile_border_y = (grp_idy == (get_num_groups(1) - 1)) ? tile_dim_y % get_local_size(1) : get_local_size(1); threads_within_tile_border_x = (threads_within_tile_border_x == 0) ? get_local_size(0) : threads_within_tile_border_x; threads_within_tile_border_y = (threads_within_tile_border_y == 0) ? get_local_size(1) : threads_within_tile_border_y; uint total_associated_pixels = threads_within_tile_border_x * threads_within_tile_border_y; uint work_group_pixel_index = my_work % total_associated_pixels; uint work_group_pixel_x = work_group_pixel_index % threads_within_tile_border_x; uint work_group_pixel_y = work_group_pixel_index / threads_within_tile_border_x; *pixel_x = tile_offset_x + (grp_idx * get_local_size(0)) + work_group_pixel_x; *pixel_y = tile_offset_y + (grp_idy * get_local_size(1)) + work_group_pixel_y; *tile_x = *pixel_x - tile_offset_x; *tile_y = *pixel_y - tile_offset_y; } char kernel_next_iteration_setup( __global char *globals, __constant KernelData *data, __global char *shader_data, __global uint *rng_coop, __global float3 *throughput_coop, PathRadiance *PathRadiance_coop, __global Ray *Ray_coop, __global PathState *PathState_coop, __global Ray *LightRay_dl_coop, __global int *ISLamp_coop, __global BsdfEval *BSDFEval_coop, __global Ray *LightRay_ao_coop, __global float3 *AOBSDF_coop, __global float3 *AOAlpha_coop, __global char *ray_state, __global char *use_queues_flag, int ray_index) { char enqueue_flag = 0; KernelGlobals *kg = (KernelGlobals *)globals; ShaderData *sd = (ShaderData *)shader_data; PathRadiance *L = 0x0; __global PathState *state = 0x0; if((ray_state[ray_index] & RAY_SHADOW_RAY_CAST_DL) || (ray_state[ray_index] & RAY_SHADOW_RAY_CAST_AO)) { state = &PathState_coop[ray_index]; L = &PathRadiance_coop[ray_index]; float3 _throughput = throughput_coop[ray_index]; if((ray_state[ray_index] & RAY_SHADOW_RAY_CAST_AO)) { float3 shadow = LightRay_ao_coop[ray_index].P; char update_path_radiance = LightRay_ao_coop[ray_index].t; if(update_path_radiance) { path_radiance_accum_ao(L, _throughput, AOAlpha_coop[ray_index], AOBSDF_coop[ray_index], shadow, state->bounce); } (ray_state[ray_index] = (ray_state[ray_index] & (~RAY_SHADOW_RAY_CAST_AO))); } if((ray_state[ray_index] & RAY_SHADOW_RAY_CAST_DL)) { float3 shadow = LightRay_dl_coop[ray_index].P; char update_path_radiance = LightRay_dl_coop[ray_index].t; if(update_path_radiance) { BsdfEval L_light = BSDFEval_coop[ray_index]; path_radiance_accum_light(L, _throughput, &L_light, shadow, 1.0f, state->bounce, ISLamp_coop[ray_index]); } (ray_state[ray_index] = (ray_state[ray_index] & (~RAY_SHADOW_RAY_CAST_DL))); } } if(((ray_state[ray_index] & 0x007) == RAY_ACTIVE)) { __global float3 *throughput = &throughput_coop[ray_index]; __global Ray *ray = &Ray_coop[ray_index]; __global RNG* rng = &rng_coop[ray_index]; state = &PathState_coop[ray_index]; L = &PathRadiance_coop[ray_index]; if(!kernel_path_surface_bounce(kg, rng, sd, throughput, state, L, ray)) { (ray_state[ray_index] = ((ray_state[ray_index] & 0x0F8) | RAY_UPDATE_BUFFER)); enqueue_flag = 1; } } return enqueue_flag; } __kernel void kernel_ocl_path_trace_next_iteration_setup( __global char *globals, __constant KernelData *data, __global char *shader_data, __global uint *rng_coop, __global float3 *throughput_coop, PathRadiance *PathRadiance_coop, __global Ray *Ray_coop, __global PathState *PathState_coop, __global Ray *LightRay_dl_coop, __global int *ISLamp_coop, __global BsdfEval *BSDFEval_coop, __global Ray *LightRay_ao_coop, __global float3 *AOBSDF_coop, __global float3 *AOAlpha_coop, __global char *ray_state, __global int *Queue_data, __global int *Queue_index, int queuesize, __global char *use_queues_flag) { __local unsigned int local_queue_atomics; if(get_local_id(0) == 0 && get_local_id(1) == 0) { local_queue_atomics = 0; } barrier(CLK_LOCAL_MEM_FENCE); if(get_global_id(0) == 0 && get_global_id(1) == 0) { use_queues_flag[0] = 1; Queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS] = 0; Queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS] = 0; } char enqueue_flag = 0; int ray_index = get_global_id(1) * get_global_size(0) + get_global_id(0); ray_index = get_ray_index(ray_index, QUEUE_ACTIVE_AND_REGENERATED_RAYS, Queue_data, queuesize, 0); if(ray_index == -1) { return; } enqueue_flag = kernel_next_iteration_setup(globals, data, shader_data, rng_coop, throughput_coop, PathRadiance_coop, Ray_coop, PathState_coop, LightRay_dl_coop, ISLamp_coop, BSDFEval_coop, LightRay_ao_coop, AOBSDF_coop, AOAlpha_coop, ray_state, use_queues_flag, ray_index); enqueue_ray_index_local(ray_index, QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS, enqueue_flag, queuesize, &local_queue_atomics, Queue_data, Queue_index); }