clray
changeset 9:a09622aaa043
moving to triangles
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 24 Jul 2010 06:28:17 +0100 |
parents | deaf85acf6af |
children | 2da57bedc550 |
files | rt.cl src/mesh.h src/rt.cc |
diffstat | 3 files changed, 108 insertions(+), 60 deletions(-) [+] |
line diff
1.1 --- a/rt.cl Fri Jul 23 19:48:43 2010 +0100 1.2 +++ b/rt.cl Sat Jul 24 06:28:17 2010 +0100 1.3 @@ -1,14 +1,25 @@ 1.4 struct RendInfo { 1.5 int xsz, ysz; 1.6 - int num_sph, num_lights; 1.7 + int num_faces, num_lights; 1.8 int max_iter; 1.9 }; 1.10 1.11 -struct Sphere { 1.12 +struct Vertex { 1.13 float4 pos; 1.14 + float4 normal; 1.15 + float2 tex; 1.16 +}; 1.17 + 1.18 +struct Face { 1.19 + struct Vertex v[3]; 1.20 + float4 normal; 1.21 + int matid; 1.22 +}; 1.23 + 1.24 +struct Material { 1.25 float4 kd, ks; 1.26 - float radius; 1.27 - float spow, kr, kt; 1.28 + float kr, kt; 1.29 + float spow; 1.30 }; 1.31 1.32 struct Light { 1.33 @@ -22,22 +33,25 @@ 1.34 struct SurfPoint { 1.35 float t; 1.36 float4 pos, norm; 1.37 - global const struct Sphere *obj; 1.38 + global const struct Face *obj; 1.39 + global const struct Material *mat; 1.40 }; 1.41 1.42 #define EPSILON 1e-6 1.43 1.44 float4 shade(struct Ray ray, struct SurfPoint sp, 1.45 global const struct Light *lights, int num_lights); 1.46 -bool intersect(struct Ray ray, global const struct Sphere *sph, struct SurfPoint *sp); 1.47 +bool intersect(struct Ray ray, global const struct Face *face, struct SurfPoint *sp); 1.48 float4 reflect(float4 v, float4 n); 1.49 float4 transform(float4 v, global const float *xform); 1.50 struct Ray transform_ray(global const struct Ray *ray, global const float *xform); 1.51 +float4 calc_bary(float4 pt, global const struct Face *face); 1.52 1.53 1.54 kernel void render(global float4 *fb, 1.55 global const struct RendInfo *rinf, 1.56 - global const struct Sphere *sphlist, 1.57 + global const struct Face *faces, 1.58 + global const struct Material *matlib, 1.59 global const struct Light *lights, 1.60 global const struct Ray *primrays, 1.61 global const float *xform) 1.62 @@ -50,13 +64,14 @@ 1.63 sp0.t = FLT_MAX; 1.64 sp0.obj = 0; 1.65 1.66 - for(int i=0; i<rinf->num_sph; i++) { 1.67 - if(intersect(ray, sphlist + i, &sp) && sp.t < sp0.t) { 1.68 + for(int i=0; i<rinf->num_faces; i++) { 1.69 + if(intersect(ray, faces + i, &sp) && sp.t < sp0.t) { 1.70 sp0 = sp; 1.71 } 1.72 } 1.73 1.74 if(sp0.obj) { 1.75 + sp0.mat = matlib + sp0.obj->matid; 1.76 fb[idx] = shade(ray, sp0, lights, rinf->num_lights); 1.77 } else { 1.78 fb[idx] = (float4)(0, 0, 0, 0); 1.79 @@ -75,49 +90,46 @@ 1.80 float4 vref = reflect(vdir, sp.norm); 1.81 1.82 float diff = fmax(dot(ldir, sp.norm), 0.0f); 1.83 - float spec = powr(fmax(dot(ldir, vref), 0.0f), sp.obj->spow); 1.84 + float spec = powr(fmax(dot(ldir, vref), 0.0f), sp.mat->spow); 1.85 1.86 - dcol += sp.obj->kd * diff * lights[i].color; 1.87 - scol += sp.obj->ks * spec * lights[i].color; 1.88 + dcol += sp.mat->kd * diff * lights[i].color; 1.89 + scol += sp.mat->ks * spec * lights[i].color; 1.90 } 1.91 1.92 return dcol + scol; 1.93 } 1.94 1.95 bool intersect(struct Ray ray, 1.96 - global const struct Sphere *sph, 1.97 + global const struct Face *face, 1.98 struct SurfPoint *sp) 1.99 { 1.100 - float4 dir = ray.dir; 1.101 - float4 orig = ray.origin; 1.102 - float4 spos = sph->pos; 1.103 + float ndotdir = dot(face->normal, ray.dir); 1.104 + if(fabs(ndotdir) <= EPSILON) { 1.105 + return false; 1.106 + } 1.107 1.108 - float a = dot(dir, dir); 1.109 - float b = 2.0 * dir.x * (orig.x - spos.x) + 1.110 - 2.0 * dir.y * (orig.y - spos.y) + 1.111 - 2.0 * dir.z * (orig.z - spos.z); 1.112 - float c = dot(spos, spos) + dot(orig, orig) + 1.113 - 2.0 * dot(-spos, orig) - sph->radius * sph->radius; 1.114 + float4 pt = face->v[0].pos; 1.115 + float4 vec = pt - ray.origin; 1.116 1.117 - float d = b * b - 4.0 * a * c; 1.118 - if(d < 0.0) return false; 1.119 - 1.120 - float sqrt_d = sqrt(d); 1.121 - float t1 = (-b + sqrt_d) / (2.0 * a); 1.122 - float t2 = (-b - sqrt_d) / (2.0 * a); 1.123 - 1.124 - if(t1 < EPSILON) t1 = t2; 1.125 - if(t2 < EPSILON) t2 = t1; 1.126 - float t = t1 < t2 ? t1 : t2; 1.127 + float ndotvec = dot(face->normal, vec); 1.128 + float t = ndotvec / ndotdir; 1.129 1.130 if(t < EPSILON || t > 1.0) { 1.131 return false; 1.132 } 1.133 + pt = ray.origin + ray.dir * t; 1.134 + 1.135 + float4 bc = calc_bary(pt, face); 1.136 + float bc_sum = bc.x + bc.y + bc.z; 1.137 + 1.138 + if(bc_sum < -EPSILON || bc_sum > 1.0) { 1.139 + return false; 1.140 + } 1.141 1.142 sp->t = t; 1.143 - sp->pos = orig + dir * sp->t; 1.144 - sp->norm = (sp->pos - spos) / sph->radius; 1.145 - sp->obj = sph; 1.146 + sp->pos = pt; 1.147 + sp->norm = face->normal; 1.148 + sp->obj = face; 1.149 return true; 1.150 } 1.151 1.152 @@ -151,3 +163,29 @@ 1.153 res.dir = transform(ray->dir, xform); 1.154 return res; 1.155 } 1.156 + 1.157 +float4 calc_bary(float4 pt, global const struct Face *face) 1.158 +{ 1.159 + float4 bc = {0, 0, 0, 0}; 1.160 + 1.161 + float4 vi = face->v[1].pos - face->v[0].pos; 1.162 + float4 vj = face->v[2].pos - face->v[0].pos; 1.163 + float area = fabs(dot(cross(vi, vj), face->normal) / 2.0); 1.164 + if(area < EPSILON) { 1.165 + return bc; 1.166 + } 1.167 + 1.168 + float4 pv0 = face->v[0].pos - pt; 1.169 + float4 pv1 = face->v[1].pos - pt; 1.170 + float4 pv2 = face->v[2].pos - pt; 1.171 + 1.172 + // calculate the areas of each sub-triangle 1.173 + float a0 = fabs(dot(cross(pv1, pv2), face->normal) / 2.0); 1.174 + float a1 = fabs(dot(cross(pv2, pv0), face->normal) / 2.0); 1.175 + float a2 = fabs(dot(cross(pv0, pv1), face->normal) / 2.0); 1.176 + 1.177 + bc.x = a0 / area; 1.178 + bc.y = a1 / area; 1.179 + bc.z = a2 / area; 1.180 + return bc; 1.181 +}
2.1 --- a/src/mesh.h Fri Jul 23 19:48:43 2010 +0100 2.2 +++ b/src/mesh.h Sat Jul 24 06:28:17 2010 +0100 2.3 @@ -4,19 +4,19 @@ 2.4 #include <vector> 2.5 2.6 struct Vertex { 2.7 - float pos[3]; 2.8 - float normal[3]; 2.9 + float pos[4]; 2.10 + float normal[4]; 2.11 float tex[2]; 2.12 }; 2.13 2.14 struct Face { 2.15 Vertex v[3]; 2.16 - float normal[3]; 2.17 + float normal[4]; 2.18 int matid; 2.19 }; 2.20 2.21 struct Material { 2.22 - float kd[3], ks[3]; 2.23 + float kd[4], ks[4]; 2.24 float kr, kt; 2.25 float spow; 2.26 };
3.1 --- a/src/rt.cc Fri Jul 23 19:48:43 2010 +0100 3.2 +++ b/src/rt.cc Sat Jul 24 06:28:17 2010 +0100 3.3 @@ -3,21 +3,14 @@ 3.4 #include <math.h> 3.5 #include <assert.h> 3.6 #include "ocl.h" 3.7 +#include "mesh.h" 3.8 3.9 struct RendInfo { 3.10 int xsz, ysz; 3.11 - int num_sph, num_lights; 3.12 + int num_faces, num_lights; 3.13 int max_iter; 3.14 } __attribute__((packed)); 3.15 3.16 -struct Sphere { 3.17 - float pos[4]; 3.18 - float kd[4], ks[4]; 3.19 - float radius; 3.20 - float spow; 3.21 - float kr, kt; 3.22 -} __attribute__((packed)); 3.23 - 3.24 struct Ray { 3.25 float origin[4], dir[4]; 3.26 } __attribute__((packed)); 3.27 @@ -32,9 +25,28 @@ 3.28 static CLProgram *prog; 3.29 static int global_size; 3.30 3.31 -static Sphere sphlist[] = { 3.32 - {{0, 0, 0, 1}, {0.7, 0.2, 0.15, 1}, {1, 1, 1, 1}, 1.0, 60, 0, 0}, 3.33 - {{-0.2, 0.4, -3, 1}, {0.2, 0.9, 0.3, 1}, {1, 1, 1, 1}, 0.25, 40, 0, 0} 3.34 +static Face faces[] = { 3.35 + {/* face0 */ 3.36 + { 3.37 + {{-1, 0, 0, 1}, {0, 0, -1, 1}, {0, 0}}, 3.38 + {{0, 1, 0, 1}, {0, 0, -1, 1}, {0, 0}}, 3.39 + {{1, 0, 0, 1}, {0, 0, -1, 1}, {0, 0}} 3.40 + }, 3.41 + {0, 0, -1, 1}, 0 3.42 + }, 3.43 + {/* face1 */ 3.44 + { 3.45 + {{-5, 0, -3, 1}, {0, 0, -1, 1}, {0, 0}}, 3.46 + {{0, 0, 3, 1}, {0, 0, -1, 1}, {0, 0}}, 3.47 + {{5, 0, -3, 1}, {0, 0, -1, 1}, {0, 0}} 3.48 + }, 3.49 + {0, 0, -1, 1}, 1 3.50 + } 3.51 +}; 3.52 + 3.53 +static Material matlib[] = { 3.54 + {{1, 0, 0, 1}, {1, 1, 1, 1}, 0, 0, 60.0}, 3.55 + {{0.2, 0.8, 0.3, 1}, {0, 0, 0, 0}, 0, 0, 0} 3.56 }; 3.57 3.58 static Light lightlist[] = { 3.59 @@ -53,7 +65,7 @@ 3.60 // render info 3.61 rinf.xsz = xsz; 3.62 rinf.ysz = ysz; 3.63 - rinf.num_sph = sizeof sphlist / sizeof *sphlist; 3.64 + rinf.num_faces = sizeof faces / sizeof *faces; 3.65 rinf.num_lights = sizeof lightlist / sizeof *lightlist; 3.66 rinf.max_iter = 6; 3.67 3.68 @@ -75,10 +87,11 @@ 3.69 /* setup argument buffers */ 3.70 prog->set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb); 3.71 prog->set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf); 3.72 - prog->set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist); 3.73 - prog->set_arg_buffer(3, ARG_RD, sizeof lightlist, lightlist); 3.74 - prog->set_arg_buffer(4, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); 3.75 - prog->set_arg_buffer(5, ARG_RD, sizeof xform, &xform); 3.76 + prog->set_arg_buffer(2, ARG_RD, sizeof faces, faces); 3.77 + prog->set_arg_buffer(3, ARG_RD, sizeof matlib, matlib); 3.78 + prog->set_arg_buffer(4, ARG_RD, sizeof lightlist, lightlist); 3.79 + prog->set_arg_buffer(5, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); 3.80 + prog->set_arg_buffer(6, ARG_RD, sizeof xform, &xform); 3.81 3.82 global_size = xsz * ysz; 3.83 return true; 3.84 @@ -98,16 +111,13 @@ 3.85 3.86 CLMemBuffer *mbuf = prog->get_arg_buffer(0); 3.87 map_mem_buffer(mbuf, MAP_RD); 3.88 - /*if(!write_ppm("out.ppm", fb, xsz, ysz)) { 3.89 - return 1; 3.90 - }*/ 3.91 unmap_mem_buffer(mbuf); 3.92 return true; 3.93 } 3.94 3.95 void set_xform(float *matrix) 3.96 { 3.97 - CLMemBuffer *mbuf = prog->get_arg_buffer(5); 3.98 + CLMemBuffer *mbuf = prog->get_arg_buffer(6); 3.99 assert(mbuf); 3.100 3.101 assert(map_mem_buffer(mbuf, MAP_WR) == xform);