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);