src/raytracer.cc
branchpyrit
changeset 95 ca7d4c665531
parent 93 96d65f841791
child 100 c005054bf4c1
equal deleted inserted replaced
94:4c8abb8977dc 95:ca7d4c665531
   150 		}
   150 		}
   151 
   151 
   152 	// ambient
   152 	// ambient
   153 	acc = colour * ambient;
   153 	acc = colour * ambient;
   154 
   154 
   155 	Shape *shadow_shapes[4];
   155 	const Shape *shadow_shapes[4];
   156 	vector<Light*>::iterator light;
   156 	vector<Light*>::iterator light;
   157 	for (light = lights.begin(); light != lights.end(); light++)
   157 	for (light = lights.begin(); light != lights.end(); light++)
   158 	{
   158 	{
   159 		 // direction vector to light
   159 		 // direction vector to light
   160 		VectorPacket L = VectorPacket((*light)->pos) - P;
   160 		VectorPacket L = VectorPacket((*light)->pos) - P;
   197 	{
   197 	{
   198 		Colour trans_col, refl_col;
   198 		Colour trans_col, refl_col;
   199 		Float trans = shape->material->transmissivity;
   199 		Float trans = shape->material->transmissivity;
   200 		Float refl = shape->material->reflectivity;
   200 		Float refl = shape->material->reflectivity;
   201 		const Float cos_i = - dot(normal, ray.dir);
   201 		const Float cos_i = - dot(normal, ray.dir);
   202 
       
   203 		// reflection
       
   204 		if (refl > 0.01)
       
   205 		{
       
   206 			Vector newdir = ray.dir + 2.0f * cos_i * normal;
       
   207 			Ray newray = Ray(P, newdir);
       
   208 			refl_col = raytrace(newray, depth + 1, shape);
       
   209 		}
       
   210 
   202 
   211 		// refraction
   203 		// refraction
   212 		if (trans > 0.01)
   204 		if (trans > 0.01)
   213 		{
   205 		{
   214 			Float n, n1, n2;
   206 			Float n, n1, n2;
   243 				Vector newdir = n * ray.dir + (n*cos_i - cos_t) * normal;
   235 				Vector newdir = n * ray.dir + (n*cos_i - cos_t) * normal;
   244 				Ray newray = Ray(P + 0.001f*newdir, newdir);
   236 				Ray newray = Ray(P + 0.001f*newdir, newdir);
   245 				trans_col = raytrace(newray, depth + 1, NULL);
   237 				trans_col = raytrace(newray, depth + 1, NULL);
   246 			}
   238 			}
   247 		}
   239 		}
       
   240 
       
   241 		// reflection
       
   242 		if (refl > 0.01)
       
   243 		{
       
   244 			Vector newdir = ray.dir + 2.0f * cos_i * normal;
       
   245 			Ray newray = Ray(P, newdir);
       
   246 			refl_col = raytrace(newray, depth + 1, shape);
       
   247 		}
       
   248 
   248 		col = (1-refl-trans)*col + refl*refl_col + trans*trans_col;
   249 		col = (1-refl-trans)*col + refl*refl_col + trans*trans_col;
   249 	}
   250 	}
   250 
   251 
   251 	// ambient occlusion
   252 	// ambient occlusion
   252 	if (ao_samples && !from_inside)
   253 	if (ao_samples && !from_inside)
   255 		for (int i = 0; i < ao_samples; i++)
   256 		for (int i = 0; i < ao_samples; i++)
   256 		{
   257 		{
   257 			Vector dir = SphereDistribute(i, ao_samples, ao_angle, normal);
   258 			Vector dir = SphereDistribute(i, ao_samples, ao_angle, normal);
   258 			Ray ao_ray = Ray(P, dir);
   259 			Ray ao_ray = Ray(P, dir);
   259 			Float dist = ao_distance;
   260 			Float dist = ao_distance;
   260 			Shape *shape_in_way = top->nearest_intersection(shape, ao_ray, dist);
   261 			const Shape *shape_in_way = top->nearest_intersection(shape, ao_ray, dist);
   261 			if (shape_in_way == NULL)
   262 			if (shape_in_way == NULL)
   262 				miss += 1.0;
   263 				miss += 1.0;
   263 			else
   264 			else
   264 				miss += dist / ao_distance;
   265 				miss += dist / ao_distance;
   265 		}
   266 		}
   269 }
   270 }
   270 
   271 
   271 Colour Raytracer::raytrace(Ray &ray, int depth, const Shape *origin_shape)
   272 Colour Raytracer::raytrace(Ray &ray, int depth, const Shape *origin_shape)
   272 {
   273 {
   273 	Float nearest_distance = Inf;
   274 	Float nearest_distance = Inf;
   274 	Shape *nearest_shape = top->nearest_intersection(origin_shape, ray, nearest_distance);
   275 	const Shape *nearest_shape = top->nearest_intersection(origin_shape, ray, nearest_distance);
   275 
   276 
   276 	if (nearest_shape == NULL)
   277 	if (nearest_shape == NULL)
   277 		return bg_colour;
   278 		return bg_colour;
   278 	else
   279 	else
   279 	{
   280 	{
   301 	union {
   302 	union {
   302 		float nearest_distances[4];
   303 		float nearest_distances[4];
   303 		mfloat4 m_nearest_distances;
   304 		mfloat4 m_nearest_distances;
   304 	};
   305 	};
   305 	mfloat4 mask;
   306 	mfloat4 mask;
   306 	Shape *nearest_shapes[4];
   307 	const Shape *nearest_shapes[4];
   307 	static const Shape *origin_shapes[4] = {NULL, NULL, NULL, NULL};
   308 	static const Shape *origin_shapes[4] = {NULL, NULL, NULL, NULL};
   308 	m_nearest_distances = mInf;
   309 	m_nearest_distances = mInf;
   309 
   310 
   310 	top->packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes);
   311 	top->packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes);
   311 
   312 
   349 		else
   350 		else
   350 			results[i] = bg_colour;
   351 			results[i] = bg_colour;
   351 }
   352 }
   352 #endif
   353 #endif
   353 
   354 
   354 #ifdef MSVC
   355 NORETURN void *Raytracer::raytrace_worker(void *d)
   355 __declspec(noreturn)
       
   356 #else
       
   357 __attribute__((noreturn))
       
   358 #endif
       
   359 void *Raytracer::raytrace_worker(void *d)
       
   360 {
   356 {
   361 	static const int my_queue_size = 256;
   357 	static const int my_queue_size = 256;
   362 	Raytracer *rt = (Raytracer*)d;
   358 	Raytracer *rt = (Raytracer*)d;
   363 	Sample my_queue[my_queue_size];
   359 	Sample my_queue[my_queue_size];
   364 	Colour my_colours[my_queue_size];
   360 	Colour my_colours[my_queue_size];