src/raytracer.cc
branchpyrit
changeset 21 79b516a3803d
parent 20 f22952603f29
child 22 76b7bd51d64a
equal deleted inserted replaced
20:f22952603f29 21:79b516a3803d
   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 
   158 }
   157 }
   159 
   158 
   160 static void *renderrow(void *data)
   159 static void *renderrow(void *data)
   161 {
   160 {
   162 	RenderrowData *d = (RenderrowData*) data;
   161 	RenderrowData *d = (RenderrowData*) data;
       
   162 	int subsample = d->rt->getSubsample();
       
   163 	float subsample2 = 1.0/(subsample*subsample);
       
   164 	int ww = d->w*3;
   163 	Vector3 dir = d->dfix;
   165 	Vector3 dir = d->dfix;
   164 	for (int x = 0; x < d->w; x++) {
   166 	for (int x = 0; x < d->w; x += subsample) {
   165 		// generate a ray from eye passing through this pixel
   167 		// generate a ray from eye passing through this pixel
   166 #if OVERSAMPLING
   168 #if OVERSAMPLING
   167 		// 5x oversampling
   169 		// 5x oversampling
   168 		Colour c = Colour();
   170 		Colour c = Colour();
   169 
   171 
   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) {
   246 				free(d);
   352 				free(d);
   247 #else
   353 #else
   248 		renderrow((void *)d);
   354 		renderrow((void *)d);
   249 		free(d);
   355 		free(d);
   250 #endif
   356 #endif
   251 		dfix += dy;
   357 		dfix += dy*subsample;
   252 		infomsg("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1));
   358 		infomsg("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1));
   253 	}
   359 	}
   254 	infomsg("\n");
   360 	infomsg("\n");
   255 
   361 
   256 #ifdef PTHREADS
   362 #ifdef PTHREADS