clray
diff rt.cl @ 16:9e4a28063394
cl compiler segfaults...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 09 Aug 2010 04:18:21 +0100 |
parents | 754faf15ba36 |
children | 074a64b9d6bd |
line diff
1.1 --- a/rt.cl Sun Aug 08 09:51:45 2010 +0100 1.2 +++ b/rt.cl Mon Aug 09 04:18:21 2010 +0100 1.3 @@ -4,6 +4,7 @@ 1.4 int xsz, ysz; 1.5 int num_faces, num_lights; 1.6 int max_iter; 1.7 + float4 ambient; 1.8 int dbg; 1.9 }; 1.10 1.11 @@ -34,6 +35,7 @@ 1.12 1.13 struct Ray { 1.14 float4 origin, dir; 1.15 + float energy, pad[3]; 1.16 }; 1.17 1.18 struct SurfPoint { 1.19 @@ -43,14 +45,26 @@ 1.20 global const struct Material *mat; 1.21 }; 1.22 1.23 -#define EPSILON 1e-6 1.24 +struct Scene { 1.25 + float4 ambient; 1.26 + global const struct Face *faces; 1.27 + int num_faces; 1.28 + global const struct Light *lights; 1.29 + int num_lights; 1.30 + global const struct Material *matlib; 1.31 +}; 1.32 1.33 -float4 shade(struct Ray ray, struct SurfPoint sp, 1.34 - global const struct Light *lights, int num_lights); 1.35 +#define MIN_ENERGY 0.001 1.36 +#define EPSILON 1e-6 1.37 + 1.38 +float4 trace(struct Ray ray, struct Scene *scn); 1.39 +float4 shade(struct Ray ray, struct Scene *scn, const struct SurfPoint *sp); 1.40 +bool find_intersection(struct Ray ray, const struct Scene *scn, struct SurfPoint *sp); 1.41 bool intersect(struct Ray ray, global const struct Face *face, struct SurfPoint *sp); 1.42 + 1.43 float4 reflect(float4 v, float4 n); 1.44 float4 transform(float4 v, global const float *xform); 1.45 -struct Ray transform_ray(global const struct Ray *ray, global const float *xform, global const float *invtrans); 1.46 +void transform_ray(struct Ray *ray, global const float *xform, global const float *invtrans); 1.47 float4 calc_bary(float4 pt, global const struct Face *face, float4 norm); 1.48 1.49 kernel void render(global float4 *fb, 1.50 @@ -64,79 +78,114 @@ 1.51 global struct Face *outfaces) 1.52 { 1.53 int idx = get_global_id(0); 1.54 - 1.55 - if(idx == 0) { 1.56 - for(int i=0; i<rinf->num_faces; i++) { 1.57 - outfaces[i] = faces[i]; 1.58 - } 1.59 - } 1.60 1.61 - struct Ray ray = transform_ray(primrays + idx, xform, invtrans); 1.62 + struct Scene scn; 1.63 + scn.ambient = rinf->ambient; 1.64 + scn.faces = faces; 1.65 + scn.num_faces = rinf->num_faces; 1.66 + scn.lights = lights; 1.67 + scn.num_lights = rinf->num_lights; 1.68 + scn.matlib = matlib; 1.69 1.70 - struct SurfPoint sp, sp0; 1.71 - sp0.t = FLT_MAX; 1.72 - sp0.obj = 0; 1.73 - 1.74 - int max_faces = min(rinf->num_faces, rinf->dbg); 1.75 + struct Ray ray = primrays[idx]; 1.76 + transform_ray(&ray, xform, invtrans); 1.77 1.78 - for(int i=0; i<max_faces; i++) { 1.79 - if(intersect(ray, faces + i, &sp) && sp.t < sp0.t) { 1.80 - sp0 = sp; 1.81 - } 1.82 - } 1.83 - 1.84 - if(sp0.obj) { 1.85 - sp0.mat = matlib + sp0.obj->matid; 1.86 - fb[idx] = shade(ray, sp0, lights, rinf->num_lights); 1.87 - } else { 1.88 - fb[idx] = (float4)(0, 0, 0, 0); 1.89 - } 1.90 + fb[idx] = trace(ray, &scn); 1.91 } 1.92 1.93 -float4 shade(struct Ray ray, struct SurfPoint sp, 1.94 - global const struct Light *lights, int num_lights) 1.95 +float4 trace(struct Ray ray, struct Scene *scn) 1.96 { 1.97 - float4 norm = sp.norm; 1.98 + float4 color; 1.99 + struct SurfPoint sp; 1.100 + 1.101 + if(find_intersection(ray, scn, &sp)) { 1.102 + color = shade(ray, scn, &sp); 1.103 + } else { 1.104 + color = (float4)(0, 0, 0, 0); 1.105 + } 1.106 + return color; 1.107 +} 1.108 + 1.109 +float4 shade(struct Ray ray, struct Scene *scn, const struct SurfPoint *sp) 1.110 +{ 1.111 + float4 norm = sp->norm; 1.112 bool entering = true; 1.113 + struct Material mat = *sp->mat; 1.114 1.115 if(dot(ray.dir, norm) >= 0.0) { 1.116 norm = -norm; 1.117 entering = false; 1.118 } 1.119 1.120 - float4 dcol = (float4)(0.07, 0.07, 0.07, 0); 1.121 + float4 dcol = scn->ambient * mat.kd; 1.122 float4 scol = (float4)(0, 0, 0, 0); 1.123 1.124 - for(int i=0; i<num_lights; i++) { 1.125 - float4 ldir = normalize(lights[i].pos - sp.pos); 1.126 - float4 vdir = -normalize(ray.dir); 1.127 - float4 vref = reflect(vdir, norm); 1.128 + for(int i=0; i<scn->num_lights; i++) { 1.129 + float4 ldir = scn->lights[i].pos - sp->pos; 1.130 1.131 - float diff = fmax(dot(ldir, norm), 0.0f); 1.132 - float spec = powr(fmax(dot(ldir, vref), 0.0f), sp.mat->spow); 1.133 + struct Ray shadowray; 1.134 + shadowray.origin = sp->pos; 1.135 + shadowray.dir = ldir; 1.136 1.137 - dcol += sp.mat->kd * diff * lights[i].color; 1.138 - //scol += sp.mat->ks * spec * lights[i].color; 1.139 + if(!find_intersection(shadowray, scn, 0)) { 1.140 + ldir = normalize(ldir); 1.141 + float4 vdir = -normalize(ray.dir); 1.142 + float4 vref = reflect(vdir, norm); 1.143 + 1.144 + float diff = fmax(dot(ldir, norm), 0.0f); 1.145 + dcol += mat.kd * diff * scn->lights[i].color; 1.146 + 1.147 + //float spec = powr(fmax(dot(ldir, vref), 0.0f), mat.spow); 1.148 + //scol += mat.ks * spec * scn->lights[i].color; 1.149 + } 1.150 + } 1.151 + 1.152 + float4 refl_col = mat.ks * mat.kr; 1.153 + float refl_coeff = (refl_col.x + refl_col.y + refl_col.z) / 3.0; 1.154 + 1.155 + if(refl_coeff > MIN_ENERGY) { 1.156 + struct Ray refl_ray; 1.157 + refl_ray.origin = sp->pos; 1.158 + refl_ray.dir = reflect(-ray.dir, norm); 1.159 + refl_ray.energy *= refl_coeff; 1.160 + 1.161 + scol += trace(refl_ray, scn) * refl_col; 1.162 } 1.163 1.164 return dcol + scol; 1.165 } 1.166 1.167 -float dot3(float4 a, float4 b) 1.168 + 1.169 +bool find_intersection(struct Ray ray, const struct Scene *scn, struct SurfPoint *spres) 1.170 { 1.171 - return a.x * b.x + a.y * b.y + a.z * b.z; 1.172 + struct SurfPoint sp, sp0; 1.173 + sp0.t = 1.0; 1.174 + sp0.obj = 0; 1.175 + 1.176 + for(int i=0; i<scn->num_faces; i++) { 1.177 + if(intersect(ray, scn->faces + i, &sp) && sp.t < sp0.t) { 1.178 + sp0 = sp; 1.179 + } 1.180 + } 1.181 + 1.182 + if(!sp0.obj) { 1.183 + return false; 1.184 + } 1.185 + 1.186 + if(spres) { 1.187 + *spres = sp0; 1.188 + spres->mat = scn->matlib + sp0.obj->matid; 1.189 + } 1.190 + return true; 1.191 } 1.192 1.193 - 1.194 -bool intersect(struct Ray ray, 1.195 - global const struct Face *face, 1.196 - struct SurfPoint *sp) 1.197 +bool intersect(struct Ray ray, global const struct Face *face, struct SurfPoint *sp) 1.198 { 1.199 float4 origin = ray.origin; 1.200 float4 dir = ray.dir; 1.201 float4 norm = face->normal; 1.202 1.203 - float ndotdir = dot3(dir, norm); 1.204 + float ndotdir = dot(dir, norm); 1.205 1.206 if(fabs(ndotdir) <= EPSILON) { 1.207 return false; 1.208 @@ -145,7 +194,7 @@ 1.209 float4 pt = face->v[0].pos; 1.210 float4 vec = pt - origin; 1.211 1.212 - float ndotvec = dot3(norm, vec); 1.213 + float ndotvec = dot(norm, vec); 1.214 float t = ndotvec / ndotdir; 1.215 1.216 if(t < EPSILON || t > 1.0) { 1.217 @@ -153,8 +202,6 @@ 1.218 } 1.219 pt = origin + dir * t; 1.220 1.221 - if(pt.w < 0.0) return false; 1.222 - 1.223 1.224 float4 bc = calc_bary(pt, face, norm); 1.225 float bc_sum = bc.x + bc.y + bc.z; 1.226 @@ -188,12 +235,10 @@ 1.227 return res; 1.228 } 1.229 1.230 -struct Ray transform_ray(global const struct Ray *ray, global const float *xform, global const float *invtrans) 1.231 +void transform_ray(struct Ray *ray, global const float *xform, global const float *invtrans) 1.232 { 1.233 - struct Ray res; 1.234 - res.origin = transform(ray->origin, xform); 1.235 - res.dir = transform(ray->dir, invtrans); 1.236 - return res; 1.237 + ray->origin = transform(ray->origin, xform); 1.238 + ray->dir = transform(ray->dir, invtrans); 1.239 } 1.240 1.241 float4 calc_bary(float4 pt, global const struct Face *face, float4 norm) 1.242 @@ -205,7 +250,7 @@ 1.243 float4 v2 = face->v[2].pos - face->v[0].pos; 1.244 float4 xv1v2 = cross(v1, v2); 1.245 1.246 - float area = fabs(dot3(xv1v2, norm)) * 0.5; 1.247 + float area = fabs(dot(xv1v2, norm)) * 0.5; 1.248 if(area < EPSILON) { 1.249 return bc; 1.250 } 1.251 @@ -219,9 +264,9 @@ 1.252 float4 x20 = cross(pv2, pv0); 1.253 float4 x01 = cross(pv0, pv1); 1.254 1.255 - float a0 = fabs(dot3(x12, norm)) * 0.5; 1.256 - float a1 = fabs(dot3(x20, norm)) * 0.5; 1.257 - float a2 = fabs(dot3(x01, norm)) * 0.5; 1.258 + float a0 = fabs(dot(x12, norm)) * 0.5; 1.259 + float a1 = fabs(dot(x20, norm)) * 0.5; 1.260 + float a2 = fabs(dot(x01, norm)) * 0.5; 1.261 1.262 bc.x = a0 / area; 1.263 bc.y = a1 / area;