Ejemplo n.º 1
0
void SamplingIntegrator::renderBlock(const Scene *scene,
		const Sensor *sensor, Sampler *sampler, ImageBlock *block,
		const bool &stop, const std::vector< TPoint2<uint8_t> > &points) const {

	Float diffScaleFactor = 1.0f /
		std::sqrt((Float) sampler->getSampleCount());

	bool needsApertureSample = sensor->needsApertureSample();
	bool needsTimeSample = sensor->needsTimeSample();

	RadianceQueryRecord rRec(scene, sampler);
	Point2 apertureSample(0.5f);
	Float timeSample = 0.5f;
	RayDifferential sensorRay;

	block->clear();

	uint32_t queryType = RadianceQueryRecord::ESensorRay;

	if (!sensor->getFilm()->hasAlpha()) /* Don't compute an alpha channel if we don't have to */
		queryType &= ~RadianceQueryRecord::EOpacity;

	for (size_t i = 0; i<points.size(); ++i) {
		Point2i offset = Point2i(points[i]) + Vector2i(block->getOffset());
		if (stop)
			break;

		sampler->generate(offset);

		for (size_t j = 0; j<sampler->getSampleCount(); j++) {
			rRec.newQuery(queryType, sensor->getMedium());
			Point2 samplePos(Point2(offset) + Vector2(rRec.nextSample2D()));

			if (needsApertureSample)
				apertureSample = rRec.nextSample2D();
			if (needsTimeSample)
				timeSample = rRec.nextSample1D();

			Spectrum spec = sensor->sampleRayDifferential(
				sensorRay, samplePos, apertureSample, timeSample);

			sensorRay.scaleDifferential(diffScaleFactor);

			spec *= Li(sensorRay, rRec);
			block->put(samplePos, spec, rRec.alpha);
			sampler->advance();
		}
	}
}
Ejemplo n.º 2
0
	void handleMiss(RayDifferential ray, const RadianceQueryRecord &rRec,
			Spectrum &E) const {
		/* Handle an irradiance cache miss */
		HemisphereSampler *hs = m_hemisphereSampler.get();
		Sampler *sampler = m_sampleGenerator.get();
		RadianceQueryRecord rRec2;
		if (hs == NULL) {
			Properties props("independent");
			sampler = static_cast<Sampler *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(Sampler), props));
			hs = new HemisphereSampler(m_resolution, 2 * m_resolution);
			m_hemisphereSampler.set(hs);
			m_sampleGenerator.set(sampler);
		}

		/* Generate stratified cosine-weighted samples and compute
		   rotational + translational gradients */
		hs->generateDirections(rRec.its);
		sampler->generate(Point2i(0));

		for (unsigned int j=0; j<hs->getM(); j++) {
			for (unsigned int k=0; k<hs->getN(); k++) {
				HemisphereSampler::SampleEntry &entry = (*hs)(j, k);
					entry.dist = std::numeric_limits<Float>::infinity();
				rRec2.recursiveQuery(rRec,
					RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance);
				rRec2.extra = 1;
				rRec2.sampler = sampler;
				entry.L = m_subIntegrator->Li(RayDifferential(rRec.its.p, entry.d, ray.time), rRec2);
				entry.dist = rRec2.dist;
				sampler->advance();
			}
		}

		hs->process(rRec.its);
		/* Undo ray differential scaling done by the integrator */
		if (ray.hasDifferentials)
			ray.scaleDifferential(m_diffScaleFactor);
		m_irrCache->put(ray, rRec.its, *hs);
		E = hs->getIrradiance();
	}
Ejemplo n.º 3
0
void SampleIntegrator::renderBlock(const Scene *scene,
	const Camera *camera, Sampler *sampler, ImageBlock *block, 
	const bool &stop, const std::vector<Point2i> *points) const {
	Point2 sample, lensSample;
	RayDifferential eyeRay;
	Float timeSample = 0;
	Spectrum spec;


	block->clear();
	RadianceQueryRecord rRec(scene, sampler);
	bool needsLensSample = camera->needsLensSample();
	bool needsTimeSample = camera->needsTimeSample();
	const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter();
	Float scaleFactor = 1.0f/std::sqrt((Float) sampler->getSampleCount());

	if (points) {
		/* Use a prescribed traversal order (e.g. using a space-filling curve) */
		if (!block->collectStatistics()) {
			for (size_t i=0; i<points->size(); ++i) {
				Point2i offset = (*points)[i] + Vector2i(block->getOffset());
				if (stop) 
					break;
				sampler->generate();
				for (size_t j = 0; j<sampler->getSampleCount(); j++) {
					rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium());
					if (needsLensSample)
						lensSample = rRec.nextSample2D();
					if (needsTimeSample)
						timeSample = rRec.nextSample1D();
					sample = rRec.nextSample2D();
					sample.x += offset.x; sample.y += offset.y;
					camera->generateRayDifferential(sample, 
						lensSample, timeSample, eyeRay);
					eyeRay.scaleDifferential(scaleFactor);
					spec = Li(eyeRay, rRec);
					block->putSample(sample, spec, rRec.alpha, filter);
					sampler->advance();
				}
			}
		} else {
			Spectrum mean, meanSqr;
			for (size_t i=0; i<points->size(); ++i) {
				Point2i offset = (*points)[i] + Vector2i(block->getOffset());
				if (stop) 
					break;
				sampler->generate();
				mean = meanSqr = Spectrum(0.0f);
				for (size_t j = 0; j<sampler->getSampleCount(); j++) {
					rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium());
					if (needsLensSample)
						lensSample = rRec.nextSample2D();
					if (needsTimeSample)
						timeSample = rRec.nextSample1D();
					sample = rRec.nextSample2D();
					sample.x += offset.x; sample.y += offset.y;
					camera->generateRayDifferential(sample, 
						lensSample, timeSample, eyeRay);
					eyeRay.scaleDifferential(scaleFactor);
					spec = Li(eyeRay, rRec);

					/* Numerically robust online variance estimation using an
						algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */
					const Spectrum delta = spec - mean;
					mean += delta / ((Float) j+1);
					meanSqr += delta * (spec - mean);
					block->putSample(sample, spec, rRec.alpha, filter);
					block->setVariance(offset.x, offset.y,
						meanSqr / (Float) j, (int) j+1);
					sampler->advance();
				}
			}
		}
	} else {
		/* Simple scanline traversal order */
		const int
			sx = block->getOffset().x,
			sy = block->getOffset().y,
			ex = sx + block->getSize().x,
			ey = sy + block->getSize().y;
		if (!block->collectStatistics()) {
			for (int y = sy; y < ey; y++) {
				for (int x = sx; x < ex; x++) {
					if (stop) 
						break;
					sampler->generate();
					for (size_t j = 0; j<sampler->getSampleCount(); j++) {
						rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium());
						if (needsLensSample)
							lensSample = rRec.nextSample2D();
						if (needsTimeSample)
							timeSample = rRec.nextSample1D();
						sample = rRec.nextSample2D();
						sample.x += x; sample.y += y;
						camera->generateRayDifferential(sample, 
							lensSample, timeSample, eyeRay);
						eyeRay.scaleDifferential(scaleFactor);
						spec = Li(eyeRay, rRec);
						block->putSample(sample, spec, rRec.alpha, filter);
						sampler->advance();
					}
				}
			}
		} else {
			Spectrum mean, meanSqr;
			for (int y = sy; y < ey; y++) {
				for (int x = sx; x < ex; x++) {
					if (stop) 
						break;
					sampler->generate();
					mean = meanSqr = Spectrum(0.0f);
					for (size_t j = 0; j<sampler->getSampleCount(); j++) {
						rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium());
						if (needsLensSample)
							lensSample = rRec.nextSample2D();
						if (needsTimeSample)
							timeSample = rRec.nextSample1D();
						sample = rRec.nextSample2D();
						sample.x += x; sample.y += y;
						camera->generateRayDifferential(sample, 
							lensSample, timeSample, eyeRay);
						eyeRay.scaleDifferential(scaleFactor);
						spec = Li(eyeRay, rRec);

						/* Numerically robust online variance estimation using an
						   algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */
						const Spectrum delta = spec - mean;
						mean += delta / ((Float) j+1);
						meanSqr += delta * (spec - mean);
						block->putSample(sample, spec, rRec.alpha, filter);
						block->setVariance(x, y, meanSqr / (Float) j, (int) j+1);
						sampler->advance();
					}
				}
			}
		}
	}
}
	void renderBlock(const Scene *scene,
		const Sensor *sensor, Sampler *sampler, ImageBlock *block,
		const bool &stop, const std::vector< TPoint2<uint8_t> > &points) const {

		Float diffScaleFactor = 1.0f /
			std::sqrt((Float)sampler->getSampleCount());

		bool needsApertureSample = sensor->needsApertureSample();
		bool needsTimeSample = sensor->needsTimeSample();

		RadianceQueryRecord rRec(scene, sampler);
		Point2 apertureSample(0.5f);
		Float timeSample = 0.5f;
		RayDifferential sensorRay;

		block->clear();

		uint32_t queryType = RadianceQueryRecord::ESensorRay;

		if (!sensor->getFilm()->hasAlpha()) /* Don't compute an alpha channel if we don't have to */
			queryType &= ~RadianceQueryRecord::EOpacity;

		for (size_t i = 0; i < points.size(); ++i) {
			Point2i offset = Point2i(points[i]) + Vector2i(block->getOffset());
			int index = offset.x + offset.y * width;

			if (stop)
				break;

			sampler->generate(offset);

			Float cntLdA = 0.f;
			std::vector<Float> cntLdW(m_numLobes, 0.f);

			for (size_t j = 0; j < sampler->getSampleCount(); j++) {
				rRec.newQuery(queryType, sensor->getMedium());
				Point2 samplePos(Point2(offset) + Vector2(rRec.nextSample2D()));

				if (needsApertureSample)
					apertureSample = rRec.nextSample2D();
				if (needsTimeSample)
					timeSample = rRec.nextSample1D();

				Spectrum spec = sensor->sampleRayDifferential(
					sensorRay, samplePos, apertureSample, timeSample);

				sensorRay.scaleDifferential(diffScaleFactor);

				Spectrum oneTdA(0.f);
				Spectrum oneLdA(0.f);
				std::vector<Spectrum> oneTdW(m_numLobes, Spectrum(0.f));
				std::vector<Spectrum> oneLdW(m_numLobes, Spectrum(0.f));
				int albedoSegs = 0;

				spec *= Li(sensorRay, rRec, oneTdA, oneLdA, oneTdW, oneLdW, albedoSegs);

				block->put(samplePos, spec, rRec.alpha);

				bool goodSample = true;
				for (int c = 0; c < 3; c++) {
					if (!std::isfinite(oneLdA[c]) || oneLdA[c] < 0) {
						goodSample = false;
						break;
					}
				}
				
				if (goodSample) {
					LdA[index] += oneLdA;
					cntLdA += 1.f;
				}

				for (int k = 0; k < m_numLobes; k++) {
					goodSample = true;

					for (int c = 0; c < 3; c++) {
						if (!std::isfinite(oneLdW[k][c]) || oneLdW[k][c] < 0) {
							goodSample = false;
							break;
						}
					}

					if (goodSample) {
						LdW[k][index] += oneLdW[k];
						cntLdW[k] += 1.f;
					}
				}

				imageSeg[index] |= albedoSegs;

				sampler->advance();
			}

			if (cntLdA > 0.f) {
				LdA[index] /= cntLdA;
			}
			else {
				LdA[index] = Spectrum(0.f);
			}

			for (int k = 0; k < m_numLobes; k++) {
				if (cntLdW[k] > 0.f) {
					LdW[k][index] /= cntLdW[k];
				}
				else {
					LdW[k][index] = Spectrum(0.f);
				}
			}
		}

		Float *data = new Float[(int)points.size() * 3]; 		
		
		std::string outfile = prefix + formatString("LdA_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y);
		for (int i = 0; i < points.size(); i++) {
			Point2i p = Point2i(points[i]);
			int localIndex = p.x + p.y * block->getWidth();
			Point2i offset = p + Vector2i(block->getOffset());
			int globalIndex = offset.x + offset.y * width;
			Spectrum color(LdA[globalIndex]);
			for (int c = 0; c < 3; c++) {
				data[3 * localIndex + c] = color[c];
			}
		}
		savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight());

		for (int k = 0; k < m_numLobes; k++) {
			outfile = prefix + formatString("LdW_l%02i_%03i_%03i.pfm", k, block->getOffset().x, block->getOffset().y);
			for (int i = 0; i < points.size(); i++) {
				Point2i p = Point2i(points[i]);
				int localIndex = p.x + p.y * block->getWidth();
				Point2i offset = p + Vector2i(block->getOffset());
				int globalIndex = offset.x + offset.y * width;
				Spectrum color(LdW[k][globalIndex]);
				for (int c = 0; c < 3; c++) {
					data[3 * localIndex + c] = color[c];
				}
			}
			savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight());
		}
		
		outfile = prefix + formatString("image_seg_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y);
		for (int i = 0; i < points.size(); i++) {
			Point2i p = Point2i(points[i]);
			int localIndex = p.x + p.y * block->getWidth();
			Point2i offset = p + Vector2i(block->getOffset());
			int globalIndex = offset.x + offset.y * width;
			Spectrum color(imageSeg[globalIndex]);
			for (int c = 0; c < 3; c++) {
				data[3 * localIndex + c] = color[c];
			}
		}
		savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight());

		/*
		outfile = formatString("TdA_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y);
		for (int i = 0; i < points.size(); i++) {
			Point2i p = Point2i(points[i]);
			int localIndex = p.x + p.y * block->getWidth();
			Point2i offset = p + Vector2i(block->getOffset());
			int globalIndex = offset.x + offset.y * width;
			Spectrum color(TdA[globalIndex] / Float(spp));
			for (int c = 0; c < 3; c++) {
				data[3 * localIndex + c] = color[c];
			}
		}
		savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight());		
		*/
		delete[] data;
	}