Example #1
0
Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n, Float time,
		const Medium *medium, Sampler *sampler, int nSamples, bool handleIndirect) const {
	Spectrum E(0.0f);
	LuminaireSamplingRecord lRec;
	RadianceQueryRecord rRec(scene, sampler);
	Frame frame(n);

	sampler->generate();
	for (int i=0; i<nSamples; i++) {
		rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission, medium);

		/* Direct */
		if (scene->sampleAttenuatedLuminaire(p, time, medium, lRec, rRec.nextSample2D())) {
			Float dp = dot(lRec.d, n);
			if (dp < 0) 
				E -= lRec.value * dp;
		}

		/* Indirect */
		if (handleIndirect) {
			Vector d = frame.toWorld(squareToHemispherePSA(rRec.nextSample2D()));
			++rRec.depth;
			E += Li(RayDifferential(p, d, time), rRec) * M_PI;
		}
		sampler->advance();
	}
	return E / (Float) nSamples;
}
	Spectrum E(const Scene *scene, const Intersection &its, const Medium *medium,
			Sampler *sampler, int nSamples, bool handleIndirect) const {
		Spectrum EDir(0.0f), EIndir(0.0f);
		DirectSamplingRecord dRec(its);

		/* Sample the direct illumination component */
		for (int i=0; i<nSamples; i++) {
			int maxIntermediateInteractions = -1;
			Spectrum directRadiance = scene->sampleAttenuatedEmitterDirect(
				dRec, its, medium, maxIntermediateInteractions, sampler->next2D());

			if (!directRadiance.isZero()) {
				Float dp = dot(dRec.d, its.shFrame.n);
				if (dp > 0)
					EDir += directRadiance * dp;
			}
		}

		if (handleIndirect) {
			RadianceQueryRecord rRec(scene, sampler);
			rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission, medium);
			rRec.its = its;
			if (!m_irrCache->get(rRec.its, EIndir))
				handleMiss(RayDifferential(), rRec, EIndir);
		}

		return (EDir / (Float) nSamples) + EIndir;
	}
Example #3
0
	void process(const WorkUnit *workUnit, WorkResult *workResult,
		const bool &stop) {
		const RectangularWorkUnit *rect = static_cast<const RectangularWorkUnit *>(workUnit);
		IrradianceRecordVector *result = static_cast<IrradianceRecordVector *>(workResult);
		const SamplingIntegrator *integrator = m_subIntegrator.get();

		Intersection its;
		RadianceQueryRecord rRec(m_scene, m_sampler);

		const int sx = rect->getOffset().x,
				sy = rect->getOffset().y,
				ex = sx + rect->getSize().x,
				ey = sy + rect->getSize().y;
		result->clear();

		for (int y = sy; y < ey; y++) {
			for (int x = sx; x < ex; x++) {
				if (stop)
					break;
				Point2 pixelSample(x + .5f, y + .5f);
				RayDifferential ray;
				if (m_sensor->sampleRayDifferential(ray, pixelSample, Point2(0.5f), 0.5f).isZero())
					continue;
				if (m_scene->rayIntersect(ray, its)) {
					const BSDF *bsdf = its.getBSDF();
					if ((bsdf->getType() & BSDF::EAll) != BSDF::EDiffuseReflection)
						continue;

					Spectrum E;
					if (m_irrCache->get(its, E))
						continue;

					/* Irradiance cache miss - create a record. The following
					   generates stratified cosine-weighted samples and computes
					   rotational + translational gradients */
					m_hs->generateDirections(its);
					m_sampler->generate(Point2i(0));

					for (unsigned int j=0; j<m_hs->getM(); j++) {
						for (unsigned int k=0; k<m_hs->getN(); k++) {
							HemisphereSampler::SampleEntry &entry = (*m_hs)(j, k);
							entry.dist = std::numeric_limits<Float>::infinity();
							rRec.newQuery(RadianceQueryRecord::ERadianceNoEmission
								| RadianceQueryRecord::EDistance, m_sensor->getMedium());
							rRec.extra = RadianceQueryRecord::ECacheQuery;
							rRec.depth = 2;
							entry.L = integrator->Li(RayDifferential(its.p, entry.d, 0.0f), rRec);
							entry.dist = rRec.dist;
							m_sampler->advance();
						}
					}

					m_hs->process(its);
					result->put(m_irrCache->put(ray, its, *m_hs));
				}
			}
		}
	}
Example #4
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();
		}
	}
}
Example #5
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;
	}