Exemplo n.º 1
0
void VisIntegrator::integrate()
{
	const size_t samp_dim = 8;

	RNG rng;
	ImageSampler image_sampler(spp, image->width, image->height);

	// Sample array
	Array<float> samps;
	samps.resize(RAYS_AT_A_TIME * samp_dim);

	// Sample pixel coordinate array
	Array<uint16_t> coords;
	coords.resize(RAYS_AT_A_TIME * 2);

	// Light path array
	Array<VisPath> paths;
	paths.resize(RAYS_AT_A_TIME);

	// Ray and Intersection arrays
	Array<Ray> rays(RAYS_AT_A_TIME);
	Array<Intersection> intersections(RAYS_AT_A_TIME);

	// ids corresponding to the rays
	Array<uint32_t> ids(RAYS_AT_A_TIME);

	bool last = false;
	while (true) {
		// Generate a bunch of samples
		std::cout << "\t--------\n\tGenerating samples" << std::endl;
		std::cout.flush();
		for (int i = 0; i < RAYS_AT_A_TIME; i++) {
			if (!image_sampler.get_next_sample(samp_dim, &(samps[i*samp_dim]), &(coords[i*2]))) {
				samps.resize(i*samp_dim);
				paths.resize(i);
				last = true;
				break;
			} else {
				paths[i].done = false;
			}
		}
		uint32_t ssize = samps.size() / samp_dim;


		// Size the ray buffer appropriately
		rays.resize(ssize);

		// Generate a bunch of camera rays
		std::cout << "\tGenerating camera rays" << std::endl;
		std::cout.flush();
		for (uint32_t i = 0; i < ssize; i++) {
			float rx = (samps[i*samp_dim] - 0.5) * (image->max_x - image->min_x);
			float ry = (0.5 - samps[i*samp_dim+1]) * (image->max_y - image->min_y);
			float dx = (image->max_x - image->min_x) / image->width;
			float dy = (image->max_y - image->min_y) / image->height;
			rays[i] = scene->camera->generate_ray(rx, ry, dx, dy, samps[i*samp_dim+4], samps[i*samp_dim+2], samps[i*samp_dim+3]);
			rays[i].finalize();
			ids[i] = i;
		}


		// Trace the camera rays
		std::cout << "\tTracing camera rays" << std::endl;
		std::cout.flush();
		tracer->trace(rays, &intersections);


		// Update paths
		std::cout << "\tUpdating paths" << std::endl;
		std::cout.flush();
		uint32_t rsize = rays.size();
		for (uint32_t i = 0; i < rsize; i++) {
			if (intersections[i].hit) {
				// Ray hit something!  Store intersection data
				paths[ids[i]].done = true;
				paths[ids[i]].col = intersections[i].col;
			} else {
				// Ray didn't hit anything, done and black background
				paths[ids[i]].done = true;
				paths[ids[i]].col = Color(0.0, 0.0, 0.0);
			}
		}


		// Accumulate the samples
		std::cout << "\tAccumulating samples" << std::endl;
		std::cout.flush();
		for (size_t i = 0; i < ssize; i++) {
			image->add_sample(paths[i].col, coords[i*2], coords[i*2+1]);
		}

		// Print percentage complete
		static int32_t last_perc = -1;
		int32_t perc = image_sampler.percentage() * 100;
		if (perc > last_perc) {
			std::cout << perc << "%" << std::endl;
			last_perc = perc;
		}

		if (callback)
			callback();

		if (last)
			break;
	}
}
void DirectLightingIntegrator::integrate()
{
	const size_t samp_dim = 8;

	RNG rng;
	ImageSampler image_sampler(spp, image->width, image->height);

	// Sample array
	Array<float> samps(RAYS_AT_A_TIME * samp_dim);

	// Sample pixel coordinate array
	Array<uint16_t> coords(RAYS_AT_A_TIME * 2);

	// Light path array
	Array<DLPath> paths(RAYS_AT_A_TIME);

	// Ray and Intersection arrays
	Array<Ray> rays(RAYS_AT_A_TIME);
	Array<Intersection> intersections(RAYS_AT_A_TIME);

	// ids corresponding to the rays
	Array<uint32_t> ids(RAYS_AT_A_TIME);

	bool last = false;
	while (true) {
		// Generate a bunch of samples
		std::cout << "\t--------\n\tGenerating samples" << std::endl;
		std::cout.flush();
		for (int i = 0; i < RAYS_AT_A_TIME; i++) {
			if (!image_sampler.get_next_sample(samp_dim, &(samps[i*samp_dim]), &(coords[i*2]))) {
				samps.resize(i*samp_dim);
				paths.resize(i);
				last = true;
				break;
			} else {
				paths[i].done = false;
			}
		}
		uint32_t ssize = samps.size() / samp_dim;


		// Size the ray buffer appropriately
		rays.resize(ssize);


		// Generate a bunch of camera rays
		std::cout << "\tGenerating camera rays" << std::endl;
		std::cout.flush();
		for (uint32_t i = 0; i < ssize; i++) {
			float rx = (samps[i*samp_dim] - 0.5) * (image->max_x - image->min_x);
			float ry = (0.5 - samps[i*samp_dim+1]) * (image->max_y - image->min_y);
			float dx = (image->max_x - image->min_x) / image->width;
			float dy = (image->max_y - image->min_y) / image->height;
			rays[i] = scene->camera->generate_ray(rx, ry, dx, dy, samps[i*samp_dim+4], samps[i*samp_dim+2], samps[i*samp_dim+3]);
			rays[i].finalize();
			ids[i] = i;
		}


		// Trace the camera rays
		std::cout << "\tTracing camera rays" << std::endl;
		std::cout.flush();
		tracer->trace(rays, &intersections);


		// Update paths
		std::cout << "\tUpdating paths" << std::endl;
		std::cout.flush();
		uint32_t rsize = rays.size();
		for (uint32_t i = 0; i < rsize; i++) {
			if (intersections[i].hit) {
				// Ray hit something!  Store intersection data
				paths[ids[i]].inter = intersections[i];
			} else {
				// Ray didn't hit anything, done and black background
				paths[ids[i]].done = true;
				paths[ids[i]].col = Color(0.0, 0.0, 0.0);
			}
		}


		// Generate a bunch of shadow rays
		std::cout << "\tGenerating shadow rays" << std::endl;
		std::cout.flush();
		uint32_t sri = 0; // Shadow ray index
		for (uint32_t i = 0; i < ssize; i++) {
			if (!paths[i].done) {
				// Select a light and store the normalization factor for it's output
				Light *lighty = scene->finite_lights[(uint32_t)(samps[i*samp_dim+5] * scene->finite_lights.size()) % scene->finite_lights.size()];

				// Sample the light source
				Vec3 ld;
				paths[i].lcol = lighty->sample(intersections[i].p, samps[i*samp_dim+6], samps[i*samp_dim+7], rays[i].time, &ld)
				                * (float)(scene->finite_lights.size());

				// Create a shadow ray for this path
				float d = ld.length();
				ld.normalize();
				rays[sri].o = paths[i].inter.p + paths[i].inter.offset;
				rays[sri].d = ld;
				rays[sri].time = samps[i*samp_dim+4];
				rays[sri].is_shadow_ray = true;
				rays[sri].ow = paths[i].inter.owp();
				rays[sri].dw = 0.0f;
				//rays[sri].has_differentials = false;
				rays[sri].max_t = d;
				rays[sri].finalize();

				ids[sri] = i;

				// Increment shadow ray index
				sri++;
			}
		}
		rays.resize(sri);


		// Trace the shadow rays
		std::cout << "\tTracing shadow rays" << std::endl;
		std::cout.flush();
		tracer->trace(rays, &intersections);


		// Calculate sample colors
		std::cout << "\tCalculating sample colors" << std::endl;
		std::cout.flush();
		rsize = rays.size();
		for (uint32_t i = 0; i < rsize; i++) {
			uint32_t id = ids[i];
			if (intersections[i].hit) {
				// Sample was shadowed
				paths[id].done = true;
				paths[id].col = Color(0.0, 0.0, 0.0);
			} else {
				// Sample was lit
				paths[id].inter.n.normalize();
				float lambert = dot(rays[i].d, paths[id].inter.n);
				if (lambert < 0.0) lambert = 0.0;

				paths[id].col = paths[id].lcol * lambert;
			}
		}


		// Print percentage complete
		static int32_t last_perc = -1;
		int32_t perc = image_sampler.percentage() * 100;
		if (perc > last_perc) {
			std::cout << perc << "%" << std::endl;
			last_perc = perc;
		}

		if (!Config::no_output) {
			// Accumulate the samples
			std::cout << "\tAccumulating samples" << std::endl;
			std::cout.flush();
			for (size_t i = 0; i < ssize; i++) {
				image->add_sample(paths[i].col, coords[i*2], coords[i*2+1]);
			}

			if (callback)
				callback();
		}

		if (last)
			break;
	}
}