SmallptGPU-v1.6/preprocessed_rendering_kernel.cl
2017-03-09 21:17:55 +00:00

587 lines
23 KiB
Common Lisp

# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
# 26 "<stdin>"
# 1 "camera.h" 1
# 27 "camera.h"
# 1 "vec.h" 1
# 27 "vec.h"
typedef struct {
float x, y, z;
} Vec;
# 28 "camera.h" 2
typedef struct {
Vec orig, target;
Vec dir, x, y;
} Camera;
# 27 "<stdin>" 2
# 1 "geomfunc.h" 1
# 27 "geomfunc.h"
# 1 "geom.h" 1
# 32 "geom.h"
typedef struct {
Vec o, d;
} Ray;
enum Refl {
DIFF, SPEC, REFR
};
typedef struct {
float rad;
Vec p, e, c;
enum Refl refl;
} Sphere;
# 28 "geomfunc.h" 2
# 1 "simplernd.h" 1
# 34 "simplernd.h"
static float GetRandom(unsigned int *seed0, unsigned int *seed1) {
*seed0 = 36969 * ((*seed0) & 65535) + ((*seed0) >> 16);
*seed1 = 18000 * ((*seed1) & 65535) + ((*seed1) >> 16);
unsigned int ires = ((*seed0) << 16) + (*seed1);
union {
float f;
unsigned int ui;
} res;
res.ui = (ires & 0x007fffff) | 0x40000000;
return (res.f - 2.f) / 2.f;
}
# 29 "geomfunc.h" 2
static float SphereIntersect(
__constant
const Sphere *s,
const Ray *r) {
Vec op;
{ (op).x = (s->p).x - (r->o).x; (op).y = (s->p).y - (r->o).y; (op).z = (s->p).z - (r->o).z; };
float b = ((op).x * (r->d).x + (op).y * (r->d).y + (op).z * (r->d).z);
float det = b * b - ((op).x * (op).x + (op).y * (op).y + (op).z * (op).z) + s->rad * s->rad;
if (det < 0.f)
return 0.f;
else
det = sqrt(det);
float t = b - det;
if (t > 0.01f)
return t;
else {
t = b + det;
if (t > 0.01f)
return t;
else
return 0.f;
}
}
static void UniformSampleSphere(const float u1, const float u2, Vec *v) {
const float zz = 1.f - 2.f * u1;
const float r = sqrt(max(0.f, 1.f - zz * zz));
const float phi = 2.f * 3.14159265358979323846f * u2;
const float xx = r * cos(phi);
const float yy = r * sin(phi);
{ (*v).x = xx; (*v).y = yy; (*v).z = zz; };
}
static int Intersect(
__constant
const Sphere *spheres,
const unsigned int sphereCount,
const Ray *r,
float *t,
unsigned int *id) {
float inf = (*t) = 1e20f;
unsigned int i = sphereCount;
for (; i--;) {
const float d = SphereIntersect(&spheres[i], r);
if ((d != 0.f) && (d < *t)) {
*t = d;
*id = i;
}
}
return (*t < inf);
}
static int IntersectP(
__constant
const Sphere *spheres,
const unsigned int sphereCount,
const Ray *r,
const float maxt) {
unsigned int i = sphereCount;
for (; i--;) {
const float d = SphereIntersect(&spheres[i], r);
if ((d != 0.f) && (d < maxt))
return 1;
}
return 0;
}
static void SampleLights(
__constant
const Sphere *spheres,
const unsigned int sphereCount,
unsigned int *seed0, unsigned int *seed1,
const Vec *hitPoint,
const Vec *normal,
Vec *result) {
{ (*result).x = 0.f; (*result).y = 0.f; (*result).z = 0.f; };
unsigned int i;
for (i = 0; i < sphereCount; i++) {
__constant
const Sphere *light = &spheres[i];
if (!(((light->e).x == 0.f) && ((light->e).x == 0.f) && ((light->e).z == 0.f))) {
Ray shadowRay;
shadowRay.o = *hitPoint;
Vec unitSpherePoint;
UniformSampleSphere(GetRandom(seed0, seed1), GetRandom(seed0, seed1), &unitSpherePoint);
Vec spherePoint;
{ float k = (light->rad); { (spherePoint).x = k * (unitSpherePoint).x; (spherePoint).y = k * (unitSpherePoint).y; (spherePoint).z = k * (unitSpherePoint).z; } };
{ (spherePoint).x = (spherePoint).x + (light->p).x; (spherePoint).y = (spherePoint).y + (light->p).y; (spherePoint).z = (spherePoint).z + (light->p).z; };
{ (shadowRay.d).x = (spherePoint).x - (*hitPoint).x; (shadowRay.d).y = (spherePoint).y - (*hitPoint).y; (shadowRay.d).z = (spherePoint).z - (*hitPoint).z; };
const float len = sqrt(((shadowRay.d).x * (shadowRay.d).x + (shadowRay.d).y * (shadowRay.d).y + (shadowRay.d).z * (shadowRay.d).z));
{ float k = (1.f / len); { (shadowRay.d).x = k * (shadowRay.d).x; (shadowRay.d).y = k * (shadowRay.d).y; (shadowRay.d).z = k * (shadowRay.d).z; } };
float wo = ((shadowRay.d).x * (unitSpherePoint).x + (shadowRay.d).y * (unitSpherePoint).y + (shadowRay.d).z * (unitSpherePoint).z);
if (wo > 0.f) {
continue;
} else
wo = -wo;
const float wi = ((shadowRay.d).x * (*normal).x + (shadowRay.d).y * (*normal).y + (shadowRay.d).z * (*normal).z);
if ((wi > 0.f) && (!IntersectP(spheres, sphereCount, &shadowRay, len - 0.01f))) {
Vec c; { (c).x = (light->e).x; (c).y = (light->e).y; (c).z = (light->e).z; };
const float s = (4.f * 3.14159265358979323846f * light->rad * light->rad) * wi * wo / (len *len);
{ float k = (s); { (c).x = k * (c).x; (c).y = k * (c).y; (c).z = k * (c).z; } };
{ (*result).x = (*result).x + (c).x; (*result).y = (*result).y + (c).y; (*result).z = (*result).z + (c).z; };
}
}
}
}
static void RadiancePathTracing(
__constant
const Sphere *spheres,
const unsigned int sphereCount,
const Ray *startRay,
unsigned int *seed0, unsigned int *seed1,
Vec *result) {
Ray currentRay; { { ((currentRay).o).x = ((*startRay).o).x; ((currentRay).o).y = ((*startRay).o).y; ((currentRay).o).z = ((*startRay).o).z; }; { ((currentRay).d).x = ((*startRay).d).x; ((currentRay).d).y = ((*startRay).d).y; ((currentRay).d).z = ((*startRay).d).z; }; };
Vec rad; { (rad).x = 0.f; (rad).y = 0.f; (rad).z = 0.f; };
Vec throughput; { (throughput).x = 1.f; (throughput).y = 1.f; (throughput).z = 1.f; };
unsigned int depth = 0;
int specularBounce = 1;
for (;; ++depth) {
if (depth > 6) {
*result = rad;
return;
}
float t;
unsigned int id = 0;
if (!Intersect(spheres, sphereCount, &currentRay, &t, &id)) {
*result = rad;
return;
}
__constant
const Sphere *obj = &spheres[id];
Vec hitPoint;
{ float k = (t); { (hitPoint).x = k * (currentRay.d).x; (hitPoint).y = k * (currentRay.d).y; (hitPoint).z = k * (currentRay.d).z; } };
{ (hitPoint).x = (currentRay.o).x + (hitPoint).x; (hitPoint).y = (currentRay.o).y + (hitPoint).y; (hitPoint).z = (currentRay.o).z + (hitPoint).z; };
Vec normal;
{ (normal).x = (hitPoint).x - (obj->p).x; (normal).y = (hitPoint).y - (obj->p).y; (normal).z = (hitPoint).z - (obj->p).z; };
{ float l = 1.f / sqrt(((normal).x * (normal).x + (normal).y * (normal).y + (normal).z * (normal).z)); { float k = (l); { (normal).x = k * (normal).x; (normal).y = k * (normal).y; (normal).z = k * (normal).z; } }; };
const float dp = ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z);
Vec nl;
const float invSignDP = -1.f * sign(dp);
{ float k = (invSignDP); { (nl).x = k * (normal).x; (nl).y = k * (normal).y; (nl).z = k * (normal).z; } };
Vec eCol; { (eCol).x = (obj->e).x; (eCol).y = (obj->e).y; (eCol).z = (obj->e).z; };
if (!(((eCol).x == 0.f) && ((eCol).x == 0.f) && ((eCol).z == 0.f))) {
if (specularBounce) {
{ float k = (fabs(dp)); { (eCol).x = k * (eCol).x; (eCol).y = k * (eCol).y; (eCol).z = k * (eCol).z; } };
{ (eCol).x = (throughput).x * (eCol).x; (eCol).y = (throughput).y * (eCol).y; (eCol).z = (throughput).z * (eCol).z; };
{ (rad).x = (rad).x + (eCol).x; (rad).y = (rad).y + (eCol).y; (rad).z = (rad).z + (eCol).z; };
}
*result = rad;
return;
}
if (obj->refl == DIFF) {
specularBounce = 0;
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
Vec Ld;
SampleLights(spheres, sphereCount, seed0, seed1, &hitPoint, &nl, &Ld);
{ (Ld).x = (throughput).x * (Ld).x; (Ld).y = (throughput).y * (Ld).y; (Ld).z = (throughput).z * (Ld).z; };
{ (rad).x = (rad).x + (Ld).x; (rad).y = (rad).y + (Ld).y; (rad).z = (rad).z + (Ld).z; };
float r1 = 2.f * 3.14159265358979323846f * GetRandom(seed0, seed1);
float r2 = GetRandom(seed0, seed1);
float r2s = sqrt(r2);
Vec w; { (w).x = (nl).x; (w).y = (nl).y; (w).z = (nl).z; };
Vec u, a;
if (fabs(w.x) > .1f) {
{ (a).x = 0.f; (a).y = 1.f; (a).z = 0.f; };
} else {
{ (a).x = 1.f; (a).y = 0.f; (a).z = 0.f; };
}
{ (u).x = (a).y * (w).z - (a).z * (w).y; (u).y = (a).z * (w).x - (a).x * (w).z; (u).z = (a).x * (w).y - (a).y * (w).x; };
{ float l = 1.f / sqrt(((u).x * (u).x + (u).y * (u).y + (u).z * (u).z)); { float k = (l); { (u).x = k * (u).x; (u).y = k * (u).y; (u).z = k * (u).z; } }; };
Vec v;
{ (v).x = (w).y * (u).z - (w).z * (u).y; (v).y = (w).z * (u).x - (w).x * (u).z; (v).z = (w).x * (u).y - (w).y * (u).x; };
Vec newDir;
{ float k = (cos(r1) * r2s); { (u).x = k * (u).x; (u).y = k * (u).y; (u).z = k * (u).z; } };
{ float k = (sin(r1) * r2s); { (v).x = k * (v).x; (v).y = k * (v).y; (v).z = k * (v).z; } };
{ (newDir).x = (u).x + (v).x; (newDir).y = (u).y + (v).y; (newDir).z = (u).z + (v).z; };
{ float k = (sqrt(1 - r2)); { (w).x = k * (w).x; (w).y = k * (w).y; (w).z = k * (w).z; } };
{ (newDir).x = (newDir).x + (w).x; (newDir).y = (newDir).y + (w).y; (newDir).z = (newDir).z + (w).z; };
currentRay.o = hitPoint;
currentRay.d = newDir;
continue;
} else if (obj->refl == SPEC) {
specularBounce = 1;
Vec newDir;
{ float k = (2.f * ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z)); { (newDir).x = k * (normal).x; (newDir).y = k * (normal).y; (newDir).z = k * (normal).z; } };
{ (newDir).x = (currentRay.d).x - (newDir).x; (newDir).y = (currentRay.d).y - (newDir).y; (newDir).z = (currentRay.d).z - (newDir).z; };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = (hitPoint).x; ((currentRay).o).y = (hitPoint).y; ((currentRay).o).z = (hitPoint).z; }; { ((currentRay).d).x = (newDir).x; ((currentRay).d).y = (newDir).y; ((currentRay).d).z = (newDir).z; }; };
continue;
} else {
specularBounce = 1;
Vec newDir;
{ float k = (2.f * ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z)); { (newDir).x = k * (normal).x; (newDir).y = k * (normal).y; (newDir).z = k * (normal).z; } };
{ (newDir).x = (currentRay.d).x - (newDir).x; (newDir).y = (currentRay.d).y - (newDir).y; (newDir).z = (currentRay.d).z - (newDir).z; };
Ray reflRay; { { ((reflRay).o).x = (hitPoint).x; ((reflRay).o).y = (hitPoint).y; ((reflRay).o).z = (hitPoint).z; }; { ((reflRay).d).x = (newDir).x; ((reflRay).d).y = (newDir).y; ((reflRay).d).z = (newDir).z; }; };
int into = (((normal).x * (nl).x + (normal).y * (nl).y + (normal).z * (nl).z) > 0);
float nc = 1.f;
float nt = 1.5f;
float nnt = into ? nc / nt : nt / nc;
float ddn = ((currentRay.d).x * (nl).x + (currentRay.d).y * (nl).y + (currentRay.d).z * (nl).z);
float cos2t = 1.f - nnt * nnt * (1.f - ddn * ddn);
if (cos2t < 0.f) {
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = ((reflRay).o).x; ((currentRay).o).y = ((reflRay).o).y; ((currentRay).o).z = ((reflRay).o).z; }; { ((currentRay).d).x = ((reflRay).d).x; ((currentRay).d).y = ((reflRay).d).y; ((currentRay).d).z = ((reflRay).d).z; }; };
continue;
}
float kk = (into ? 1 : -1) * (ddn * nnt + sqrt(cos2t));
Vec nkk;
{ float k = (kk); { (nkk).x = k * (normal).x; (nkk).y = k * (normal).y; (nkk).z = k * (normal).z; } };
Vec transDir;
{ float k = (nnt); { (transDir).x = k * (currentRay.d).x; (transDir).y = k * (currentRay.d).y; (transDir).z = k * (currentRay.d).z; } };
{ (transDir).x = (transDir).x - (nkk).x; (transDir).y = (transDir).y - (nkk).y; (transDir).z = (transDir).z - (nkk).z; };
{ float l = 1.f / sqrt(((transDir).x * (transDir).x + (transDir).y * (transDir).y + (transDir).z * (transDir).z)); { float k = (l); { (transDir).x = k * (transDir).x; (transDir).y = k * (transDir).y; (transDir).z = k * (transDir).z; } }; };
float a = nt - nc;
float b = nt + nc;
float R0 = a * a / (b * b);
float c = 1 - (into ? -ddn : ((transDir).x * (normal).x + (transDir).y * (normal).y + (transDir).z * (normal).z));
float Re = R0 + (1 - R0) * c * c * c * c*c;
float Tr = 1.f - Re;
float P = .25f + .5f * Re;
float RP = Re / P;
float TP = Tr / (1.f - P);
if (GetRandom(seed0, seed1) < P) {
{ float k = (RP); { (throughput).x = k * (throughput).x; (throughput).y = k * (throughput).y; (throughput).z = k * (throughput).z; } };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = ((reflRay).o).x; ((currentRay).o).y = ((reflRay).o).y; ((currentRay).o).z = ((reflRay).o).z; }; { ((currentRay).d).x = ((reflRay).d).x; ((currentRay).d).y = ((reflRay).d).y; ((currentRay).d).z = ((reflRay).d).z; }; };
continue;
} else {
{ float k = (TP); { (throughput).x = k * (throughput).x; (throughput).y = k * (throughput).y; (throughput).z = k * (throughput).z; } };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = (hitPoint).x; ((currentRay).o).y = (hitPoint).y; ((currentRay).o).z = (hitPoint).z; }; { ((currentRay).d).x = (transDir).x; ((currentRay).d).y = (transDir).y; ((currentRay).d).z = (transDir).z; }; };
continue;
}
}
}
}
static void RadianceDirectLighting(
__constant
const Sphere *spheres,
const unsigned int sphereCount,
const Ray *startRay,
unsigned int *seed0, unsigned int *seed1,
Vec *result) {
Ray currentRay; { { ((currentRay).o).x = ((*startRay).o).x; ((currentRay).o).y = ((*startRay).o).y; ((currentRay).o).z = ((*startRay).o).z; }; { ((currentRay).d).x = ((*startRay).d).x; ((currentRay).d).y = ((*startRay).d).y; ((currentRay).d).z = ((*startRay).d).z; }; };
Vec rad; { (rad).x = 0.f; (rad).y = 0.f; (rad).z = 0.f; };
Vec throughput; { (throughput).x = 1.f; (throughput).y = 1.f; (throughput).z = 1.f; };
unsigned int depth = 0;
int specularBounce = 1;
for (;; ++depth) {
if (depth > 6) {
*result = rad;
return;
}
float t;
unsigned int id = 0;
if (!Intersect(spheres, sphereCount, &currentRay, &t, &id)) {
*result = rad;
return;
}
__constant
const Sphere *obj = &spheres[id];
Vec hitPoint;
{ float k = (t); { (hitPoint).x = k * (currentRay.d).x; (hitPoint).y = k * (currentRay.d).y; (hitPoint).z = k * (currentRay.d).z; } };
{ (hitPoint).x = (currentRay.o).x + (hitPoint).x; (hitPoint).y = (currentRay.o).y + (hitPoint).y; (hitPoint).z = (currentRay.o).z + (hitPoint).z; };
Vec normal;
{ (normal).x = (hitPoint).x - (obj->p).x; (normal).y = (hitPoint).y - (obj->p).y; (normal).z = (hitPoint).z - (obj->p).z; };
{ float l = 1.f / sqrt(((normal).x * (normal).x + (normal).y * (normal).y + (normal).z * (normal).z)); { float k = (l); { (normal).x = k * (normal).x; (normal).y = k * (normal).y; (normal).z = k * (normal).z; } }; };
const float dp = ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z);
Vec nl;
const float invSignDP = -1.f * sign(dp);
{ float k = (invSignDP); { (nl).x = k * (normal).x; (nl).y = k * (normal).y; (nl).z = k * (normal).z; } };
Vec eCol; { (eCol).x = (obj->e).x; (eCol).y = (obj->e).y; (eCol).z = (obj->e).z; };
if (!(((eCol).x == 0.f) && ((eCol).x == 0.f) && ((eCol).z == 0.f))) {
if (specularBounce) {
{ float k = (fabs(dp)); { (eCol).x = k * (eCol).x; (eCol).y = k * (eCol).y; (eCol).z = k * (eCol).z; } };
{ (eCol).x = (throughput).x * (eCol).x; (eCol).y = (throughput).y * (eCol).y; (eCol).z = (throughput).z * (eCol).z; };
{ (rad).x = (rad).x + (eCol).x; (rad).y = (rad).y + (eCol).y; (rad).z = (rad).z + (eCol).z; };
}
*result = rad;
return;
}
if (obj->refl == DIFF) {
specularBounce = 0;
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
Vec Ld;
SampleLights(spheres, sphereCount, seed0, seed1, &hitPoint, &nl, &Ld);
{ (Ld).x = (throughput).x * (Ld).x; (Ld).y = (throughput).y * (Ld).y; (Ld).z = (throughput).z * (Ld).z; };
{ (rad).x = (rad).x + (Ld).x; (rad).y = (rad).y + (Ld).y; (rad).z = (rad).z + (Ld).z; };
*result = rad;
return;
} else if (obj->refl == SPEC) {
specularBounce = 1;
Vec newDir;
{ float k = (2.f * ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z)); { (newDir).x = k * (normal).x; (newDir).y = k * (normal).y; (newDir).z = k * (normal).z; } };
{ (newDir).x = (currentRay.d).x - (newDir).x; (newDir).y = (currentRay.d).y - (newDir).y; (newDir).z = (currentRay.d).z - (newDir).z; };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = (hitPoint).x; ((currentRay).o).y = (hitPoint).y; ((currentRay).o).z = (hitPoint).z; }; { ((currentRay).d).x = (newDir).x; ((currentRay).d).y = (newDir).y; ((currentRay).d).z = (newDir).z; }; };
continue;
} else {
specularBounce = 1;
Vec newDir;
{ float k = (2.f * ((normal).x * (currentRay.d).x + (normal).y * (currentRay.d).y + (normal).z * (currentRay.d).z)); { (newDir).x = k * (normal).x; (newDir).y = k * (normal).y; (newDir).z = k * (normal).z; } };
{ (newDir).x = (currentRay.d).x - (newDir).x; (newDir).y = (currentRay.d).y - (newDir).y; (newDir).z = (currentRay.d).z - (newDir).z; };
Ray reflRay; { { ((reflRay).o).x = (hitPoint).x; ((reflRay).o).y = (hitPoint).y; ((reflRay).o).z = (hitPoint).z; }; { ((reflRay).d).x = (newDir).x; ((reflRay).d).y = (newDir).y; ((reflRay).d).z = (newDir).z; }; };
int into = (((normal).x * (nl).x + (normal).y * (nl).y + (normal).z * (nl).z) > 0);
float nc = 1.f;
float nt = 1.5f;
float nnt = into ? nc / nt : nt / nc;
float ddn = ((currentRay.d).x * (nl).x + (currentRay.d).y * (nl).y + (currentRay.d).z * (nl).z);
float cos2t = 1.f - nnt * nnt * (1.f - ddn * ddn);
if (cos2t < 0.f) {
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = ((reflRay).o).x; ((currentRay).o).y = ((reflRay).o).y; ((currentRay).o).z = ((reflRay).o).z; }; { ((currentRay).d).x = ((reflRay).d).x; ((currentRay).d).y = ((reflRay).d).y; ((currentRay).d).z = ((reflRay).d).z; }; };
continue;
}
float kk = (into ? 1 : -1) * (ddn * nnt + sqrt(cos2t));
Vec nkk;
{ float k = (kk); { (nkk).x = k * (normal).x; (nkk).y = k * (normal).y; (nkk).z = k * (normal).z; } };
Vec transDir;
{ float k = (nnt); { (transDir).x = k * (currentRay.d).x; (transDir).y = k * (currentRay.d).y; (transDir).z = k * (currentRay.d).z; } };
{ (transDir).x = (transDir).x - (nkk).x; (transDir).y = (transDir).y - (nkk).y; (transDir).z = (transDir).z - (nkk).z; };
{ float l = 1.f / sqrt(((transDir).x * (transDir).x + (transDir).y * (transDir).y + (transDir).z * (transDir).z)); { float k = (l); { (transDir).x = k * (transDir).x; (transDir).y = k * (transDir).y; (transDir).z = k * (transDir).z; } }; };
float a = nt - nc;
float b = nt + nc;
float R0 = a * a / (b * b);
float c = 1 - (into ? -ddn : ((transDir).x * (normal).x + (transDir).y * (normal).y + (transDir).z * (normal).z));
float Re = R0 + (1 - R0) * c * c * c * c*c;
float Tr = 1.f - Re;
float P = .25f + .5f * Re;
float RP = Re / P;
float TP = Tr / (1.f - P);
if (GetRandom(seed0, seed1) < P) {
{ float k = (RP); { (throughput).x = k * (throughput).x; (throughput).y = k * (throughput).y; (throughput).z = k * (throughput).z; } };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = ((reflRay).o).x; ((currentRay).o).y = ((reflRay).o).y; ((currentRay).o).z = ((reflRay).o).z; }; { ((currentRay).d).x = ((reflRay).d).x; ((currentRay).d).y = ((reflRay).d).y; ((currentRay).d).z = ((reflRay).d).z; }; };
continue;
} else {
{ float k = (TP); { (throughput).x = k * (throughput).x; (throughput).y = k * (throughput).y; (throughput).z = k * (throughput).z; } };
{ (throughput).x = (throughput).x * (obj->c).x; (throughput).y = (throughput).y * (obj->c).y; (throughput).z = (throughput).z * (obj->c).z; };
{ { ((currentRay).o).x = (hitPoint).x; ((currentRay).o).y = (hitPoint).y; ((currentRay).o).z = (hitPoint).z; }; { ((currentRay).d).x = (transDir).x; ((currentRay).d).y = (transDir).y; ((currentRay).d).z = (transDir).z; }; };
continue;
}
}
}
}
# 28 "<stdin>" 2
static void GenerateCameraRay(__constant Camera *camera,
unsigned int *seed0, unsigned int *seed1,
const int width, const int height, const int x, const int y, Ray *ray) {
const float invWidth = 1.f / width;
const float invHeight = 1.f / height;
const float r1 = GetRandom(seed0, seed1) - .5f;
const float r2 = GetRandom(seed0, seed1) - .5f;
const float kcx = (x + r1) * invWidth - .5f;
const float kcy = (y + r2) * invHeight - .5f;
Vec rdir;
{ (rdir).x = camera->x.x * kcx + camera->y.x * kcy + camera->dir.x; (rdir).y = camera->x.y * kcx + camera->y.y * kcy + camera->dir.y; (rdir).z = camera->x.z * kcx + camera->y.z * kcy + camera->dir.z; };
Vec rorig;
{ float k = (0.1f); { (rorig).x = k * (rdir).x; (rorig).y = k * (rdir).y; (rorig).z = k * (rdir).z; } };
{ (rorig).x = (rorig).x + (camera->orig).x; (rorig).y = (rorig).y + (camera->orig).y; (rorig).z = (rorig).z + (camera->orig).z; }
{ float l = 1.f / sqrt(((rdir).x * (rdir).x + (rdir).y * (rdir).y + (rdir).z * (rdir).z)); { float k = (l); { (rdir).x = k * (rdir).x; (rdir).y = k * (rdir).y; (rdir).z = k * (rdir).z; } }; };
{ { ((*ray).o).x = (rorig).x; ((*ray).o).y = (rorig).y; ((*ray).o).z = (rorig).z; }; { ((*ray).d).x = (rdir).x; ((*ray).d).y = (rdir).y; ((*ray).d).z = (rdir).z; }; };
}
__kernel void RadianceGPU(
__global Vec *colors, __global unsigned int *seedsInput,
__constant Sphere *sphere, __constant Camera *camera,
const unsigned int sphereCount,
const int width, const int height,
const int currentSample,
__global int *pixels) {
const int gid = get_global_id(0);
const int gid2 = 2 * gid;
const int x = gid % width;
const int y = gid / width;
if (y >= height)
return;
unsigned int seed0 = seedsInput[gid2];
unsigned int seed1 = seedsInput[gid2 + 1];
Ray ray;
GenerateCameraRay(camera, &seed0, &seed1, width, height, x, y, &ray);
Vec r;
RadiancePathTracing(sphere, sphereCount, &ray, &seed0, &seed1, &r);
const int i = (height - y - 1) * width + x;
if (currentSample == 0) {
{ (colors[i]).x = (r).x; (colors[i]).y = (r).y; (colors[i]).z = (r).z; };
} else {
const float k1 = currentSample;
const float k2 = 1.f / (currentSample + 1.f);
colors[i].x = (colors[i].x * k1 + r.x) * k2;
colors[i].y = (colors[i].y * k1 + r.y) * k2;
colors[i].z = (colors[i].z * k1 + r.z) * k2;
}
pixels[y * width + x] = ((int)(pow(clamp(colors[i].x, 0.f, 1.f), 1.f / 2.2f) * 255.f + .5f)) |
(((int)(pow(clamp(colors[i].y, 0.f, 1.f), 1.f / 2.2f) * 255.f + .5f)) << 8) |
(((int)(pow(clamp(colors[i].z, 0.f, 1.f), 1.f / 2.2f) * 255.f + .5f)) << 16);
seedsInput[gid2] = seed0;
seedsInput[gid2 + 1] = seed1;
}