107 Vector3 jo, L = (*light)->pos - P; // direction vector to light |
107 Vector3 jo, L = (*light)->pos - P; // direction vector to light |
108 L.normalize(); |
108 L.normalize(); |
109 float L_dot_N = dot(L, normal); |
109 float L_dot_N = dot(L, normal); |
110 if (L_dot_N > 0) { |
110 if (L_dot_N > 0) { |
111 // test if this light is occluded (sharp shadows) |
111 // test if this light is occluded (sharp shadows) |
112 if ((*light)->shadows) { |
112 if ((*light)->cast_shadows) { |
113 Ray shadow_ray = Ray(P, L); |
113 Ray shadow_ray = Ray(P, L); |
114 float dist = FLT_MAX; |
114 float dist = FLT_MAX; |
115 if (top->nearest_intersection(nearest_shape, shadow_ray, dist)) |
115 if (top->nearest_intersection(nearest_shape, shadow_ray, dist)) |
116 continue; |
116 continue; |
117 } |
117 } |
122 P, normal, R, ray.dir, **light); |
122 P, normal, R, ray.dir, **light); |
123 } |
123 } |
124 } |
124 } |
125 |
125 |
126 // reflection |
126 // reflection |
127 int trace_max_depth = 4; |
|
128 Vector3 newdir = ray.dir - 2.0 * dot(ray.dir, normal) * normal; |
127 Vector3 newdir = ray.dir - 2.0 * dot(ray.dir, normal) * normal; |
129 if (depth < trace_max_depth && nearest_shape->material->reflection > 0.01) { |
128 if (depth < max_depth && nearest_shape->material->reflection > 0.01) { |
130 Ray newray = Ray(P, newdir); |
129 Ray newray = Ray(P, newdir); |
131 Colour refl_col = raytrace(newray, depth + 1, nearest_shape); |
130 Colour refl_col = raytrace(newray, depth + 1, nearest_shape); |
132 acc += nearest_shape->material->reflection * refl_col; |
131 acc += nearest_shape->material->reflection * refl_col; |
133 } |
132 } |
134 |
133 |
180 #else |
182 #else |
181 // no oversampling |
183 // no oversampling |
182 dir.normalize(); |
184 dir.normalize(); |
183 Ray ray(d->eye, dir); |
185 Ray ray(d->eye, dir); |
184 Colour c = d->rt->raytrace(ray, 0, NULL); |
186 Colour c = d->rt->raytrace(ray, 0, NULL); |
185 #endif |
187 if (subsample > 1) |
186 *(d->iter++) = c.r; |
188 { |
187 *d->iter++ = c.g; |
189 Colour ic; |
188 *d->iter++ = c.b; |
190 // top-left is 'c' |
189 dir += d->dx; |
191 // top-right |
|
192 Vector3 tmpdir = dir + (subsample-1)*d->dx; |
|
193 tmpdir.normalize(); |
|
194 Ray ray(d->eye, tmpdir); |
|
195 Colour c2 = d->rt->raytrace(ray, 0, NULL); |
|
196 // bottom right |
|
197 tmpdir += (subsample-1)*d->dy; |
|
198 tmpdir.normalize(); |
|
199 ray.dir = tmpdir; |
|
200 Colour c4 = d->rt->raytrace(ray, 0, NULL); |
|
201 // bottom left |
|
202 tmpdir = dir + (subsample-1)*d->dy; |
|
203 tmpdir.normalize(); |
|
204 ray.dir = tmpdir; |
|
205 Colour c3 = d->rt->raytrace(ray, 0, NULL); |
|
206 // are the colors similar? |
|
207 float m = (c-c2).mag2(); |
|
208 m = max(m, (c2-c3).mag2()); |
|
209 m = max(m, (c3-c4).mag2()); |
|
210 m = max(m, (c4-c).mag2()); |
|
211 if (m < 0.001) |
|
212 { |
|
213 // interpolate |
|
214 float *i = d->iter; |
|
215 for (int x = 0; x < subsample; x++) |
|
216 { |
|
217 for (int y = 0; y < subsample; y++) |
|
218 { |
|
219 ic = c*(subsample-x)*(subsample-y)*subsample2 |
|
220 + c2*(x)*(subsample-y)*subsample2 |
|
221 + c3*(subsample-x)*(y)*subsample2 |
|
222 + c4*(x)*(y)*subsample2; |
|
223 *(i + ww*y) = ic.r; |
|
224 *(i + ww*y + 1) = ic.g; |
|
225 *(i + ww*y + 2) = ic.b; |
|
226 } |
|
227 i += 3; |
|
228 } |
|
229 d->iter = i; |
|
230 } |
|
231 else |
|
232 { |
|
233 // render |
|
234 Vector3 tmpdir = dir; |
|
235 // first column |
|
236 *(d->iter) = c.r; |
|
237 *(d->iter + 1) = c.g; |
|
238 *(d->iter + 2) = c.b; |
|
239 for (int y = 1; y < subsample-1; y++) |
|
240 { |
|
241 Vector3 tmp2dir = tmpdir + y*d->dy; |
|
242 tmp2dir.normalize(); |
|
243 ray.dir = tmp2dir; |
|
244 ic = d->rt->raytrace(ray, 0, NULL); |
|
245 *(d->iter + ww*y) = ic.r; |
|
246 *(d->iter + ww*y + 1) = ic.g; |
|
247 *(d->iter + ww*y + 2) = ic.b; |
|
248 } |
|
249 *(d->iter + ww*(subsample-1)) = c3.r; |
|
250 *(d->iter + ww*(subsample-1) + 1) = c3.g; |
|
251 *(d->iter + ww*(subsample-1) + 2) = c3.b; |
|
252 d->iter += 3; |
|
253 tmpdir += d->dx; |
|
254 // middle |
|
255 for (int x = 1; x < subsample-1; x++) |
|
256 { |
|
257 for (int y = 0; y < subsample; y++) |
|
258 { |
|
259 Vector3 tmp2dir = tmpdir + y*d->dy; |
|
260 tmp2dir.normalize(); |
|
261 ray.dir = tmp2dir; |
|
262 ic = d->rt->raytrace(ray, 0, NULL); |
|
263 *(d->iter + ww*y) = ic.r; |
|
264 *(d->iter + ww*y + 1) = ic.g; |
|
265 *(d->iter + ww*y + 2) = ic.b; |
|
266 } |
|
267 d->iter += 3; |
|
268 tmpdir += d->dx; |
|
269 } |
|
270 // last column |
|
271 *(d->iter) = c2.r; |
|
272 *(d->iter + 1) = c2.g; |
|
273 *(d->iter + 2) = c2.b; |
|
274 for (int y = 1; y < subsample-1; y++) |
|
275 { |
|
276 Vector3 tmp2dir = tmpdir + y*d->dy; |
|
277 tmp2dir.normalize(); |
|
278 ray.dir = tmp2dir; |
|
279 ic = d->rt->raytrace(ray, 0, NULL); |
|
280 *(d->iter + ww*y) = ic.r; |
|
281 *(d->iter + ww*y + 1) = ic.g; |
|
282 *(d->iter + ww*y + 2) = ic.b; |
|
283 } |
|
284 *(d->iter + ww*(subsample-1)) = c4.r; |
|
285 *(d->iter + ww*(subsample-1) + 1) = c4.g; |
|
286 *(d->iter + ww*(subsample-1) + 2) = c4.b; |
|
287 d->iter += 3; |
|
288 } |
|
289 } |
|
290 #endif |
|
291 if (subsample <= 1) |
|
292 { |
|
293 *d->iter++ = c.r; |
|
294 *d->iter++ = c.g; |
|
295 *d->iter++ = c.b; |
|
296 } |
|
297 dir += d->dx*subsample; |
190 } |
298 } |
191 #ifdef PTHREADS |
299 #ifdef PTHREADS |
192 pthread_exit((void *)d); |
300 pthread_exit((void *)d); |
193 #endif |
301 #endif |
194 return (void *)d; |
302 return (void *)d; |
215 int t = 0; |
323 int t = 0; |
216 #endif |
324 #endif |
217 |
325 |
218 /* for each pixel... */ |
326 /* for each pixel... */ |
219 infomsg("* rendering row 0 ( 0%% done)"); |
327 infomsg("* rendering row 0 ( 0%% done)"); |
220 for (int y = 0; y < h; y++) |
328 for (int y = 0; y < h; y += subsample) |
221 { |
329 { |
222 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
330 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
223 d->rt = this; |
331 d->rt = this; |
224 d->w = w; |
332 d->w = w; |
225 d->eye = camera->eye; |
333 d->eye = camera->eye; |
226 d->dfix = dfix; |
334 d->dfix = dfix; |
227 d->dx = dx; |
335 d->dx = dx; |
228 #if OVERSAMPLING |
|
229 d->dy = dy; |
336 d->dy = dy; |
230 #endif |
|
231 d->iter = buffer + y*3*w; |
337 d->iter = buffer + y*3*w; |
232 #ifdef PTHREADS |
338 #ifdef PTHREADS |
233 /* create new thread and increase 't' */ |
339 /* create new thread and increase 't' */ |
234 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
340 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
235 if (rc) { |
341 if (rc) { |