Exemplo n.º 1
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();
	}
Exemplo n.º 2
0
	void distributedRTPass(Scene *scene, std::vector<SerializableObject *> &samplers) {
		ref<Camera> camera = scene->getCamera();
		bool needsLensSample = camera->needsLensSample();
		bool needsTimeSample = camera->needsTimeSample();
		ref<Film> film = camera->getFilm();
		Vector2i cropSize = film->getCropSize();
		Point2i cropOffset = film->getCropOffset();

		/* Process the image in parallel using blocks for better memory locality */
		Log(EInfo, "Creating %i gather points", cropSize.x*cropSize.y);
		#pragma omp parallel for schedule(dynamic)
		for (int i=-1; i<(int) m_gatherBlocks.size(); ++i) {
			std::vector<GatherPoint> &gatherPoints = m_gatherBlocks[i];
#if !defined(__OSX__) && defined(_OPENMP)
			Sampler *sampler = static_cast<Sampler *>(samplers[omp_get_thread_num()]);
#else
			Sampler *sampler = static_cast<Sampler *>(samplers[0]);
#endif
			int xofs = m_offset[i].x, yofs = m_offset[i].y;
			int index = 0;
			for (int yofsInt = 0; yofsInt < m_blockSize; ++yofsInt) {
				if (yofsInt + yofs - cropOffset.y >= cropSize.y)
					continue;
				for (int xofsInt = 0; xofsInt < m_blockSize; ++xofsInt) {
					if (xofsInt + xofs - cropOffset.x >= cropSize.x)
						continue;
					Point2 lensSample, sample;
					Float timeSample = 0.0f;
					GatherPoint &gatherPoint = gatherPoints[index++];
					sampler->generate();
					if (needsLensSample)
						lensSample = sampler->next2D();
					if (needsTimeSample)
						timeSample = sampler->next1D();
					gatherPoint.pos = Point2i(xofs + xofsInt, yofs + yofsInt);
					sample = sampler->next2D();
					sample += Vector2((Float) gatherPoint.pos.x, (Float) gatherPoint.pos.y);
					RayDifferential ray;
					camera->generateRayDifferential(sample, lensSample, timeSample, ray);
					Spectrum weight(1.0f);
					int depth = 1;

					while (true) {
						if (depth > m_maxDepth) {
							gatherPoint.depth = -1;
							break;
						}
						if (scene->rayIntersect(ray, gatherPoint.its)) {
							const BSDF *bsdf = gatherPoint.its.shape->getBSDF();
							/* Create hit point if this is a diffuse material or a glossy
							   one, and there has been a previous interaction with
							   a glossy material */
							if (bsdf->getType() == BSDF::EDiffuseReflection || 
								bsdf->getType() == BSDF::EDiffuseTransmission) {
								gatherPoint.weight = weight;
								gatherPoint.depth = depth;
								if (gatherPoint.its.isLuminaire())
									gatherPoint.emission = gatherPoint.its.Le(-ray.d);
								else
									gatherPoint.emission = Spectrum(0.0f);
								break;
							} else {
								/* Recurse for dielectric materials and (specific to SPPM):
								   recursive "final gathering" for glossy materials */
								BSDFQueryRecord bRec(gatherPoint.its);
								weight *= bsdf->sampleCos(bRec, sampler->next2D());
								if (weight.isZero()) {
									gatherPoint.depth = -1;
									break;
								}
								ray = RayDifferential(gatherPoint.its.p, 
									gatherPoint.its.toWorld(bRec.wo), ray.time);
								++depth;
							}
						} else {
							/* Generate an invalid sample */
							gatherPoint.depth = -1;
							break;
						}
					}
					sampler->advance();
				}
			}
		}
	}
Exemplo n.º 3
0
	bool render(Scene *scene, RenderQueue *queue, 
		const RenderJob *job, int sceneResID, int cameraResID, int samplerResID) {
		ref<Scheduler> sched = Scheduler::getInstance();
		ref<Camera> camera = scene->getCamera();
		ref<Film> film = camera->getFilm();
		size_t nCores = sched->getCoreCount();
		Sampler *cameraSampler = (Sampler *) sched->getResource(samplerResID, 0);
	
		size_t sampleCount = cameraSampler->getSampleCount();
		Log(EInfo, "Starting render job (%ix%i, " SIZE_T_FMT " %s, " SIZE_T_FMT 
			" %s, " SSE_STR ") ..", film->getCropSize().x, film->getCropSize().y, 
			sampleCount, sampleCount == 1 ? "sample" : "samples", nCores, 
			nCores == 1 ? "core" : "cores");

		Vector2i cropSize = film->getCropSize();
		Point2i cropOffset = film->getCropOffset();

		m_gatherPoints.clear();
		m_running = true;
		for (size_t i=0; i<m_blocks.size(); ++i)
			m_blocks[i]->decRef();
		m_blocks.clear();

		m_totalEmitted = 0;
		bool needsLensSample = camera->needsLensSample();
		bool needsTimeSample = camera->needsTimeSample();
		Log(EInfo, "Creating approximately %i gather points", cropSize.x*cropSize.y*sampleCount);
		Point2 lensSample, sample;
		RayDifferential eyeRay;
		Float timeSample = 0;
		m_filter = camera->getFilm()->getTabulatedFilter();
		Vector2 filterSize = m_filter->getFilterSize();
		int borderSize = (int) std::ceil(std::max(filterSize.x, filterSize.y));

		ref<Sampler> independentSampler = static_cast<Sampler *> (PluginManager::getInstance()->
			createObject(MTS_CLASS(Sampler), Properties("independent")));

		/* Create a sampler instance for every core */
		std::vector<SerializableObject *> samplers(sched->getCoreCount());
		for (size_t i=0; i<sched->getCoreCount(); ++i) {
			ref<Sampler> clonedSampler = independentSampler->clone();
			clonedSampler->incRef();
			samplers[i] = clonedSampler.get();
		}

		int independentSamplerResID = sched->registerManifoldResource(samplers); 
		for (size_t i=0; i<sched->getCoreCount(); ++i)
			samplers[i]->decRef();

#ifdef MTS_DEBUG_FP
		enableFPExceptions();
#endif

		/* Create gather points in blocks so that gathering can be parallelized later on */
		for (int yofs=0; yofs<cropSize.y; yofs += m_blockSize) {
			for (int xofs=0; xofs<cropSize.x; xofs += m_blockSize) {
				ImageBlock *block = new ImageBlock(Vector2i(m_blockSize, m_blockSize), borderSize, 
					true, true, false, false);
				block->setSize(Vector2i(m_blockSize, m_blockSize));
				block->setOffset(Point2i(cropOffset.x + xofs, cropOffset.y + yofs));
				block->incRef();
				std::vector<GatherPoint> gatherPoints;
				gatherPoints.reserve(m_blockSize*m_blockSize*sampleCount);
				for (int yofsInt = 0; yofsInt < m_blockSize; ++yofsInt) {
					if (yofsInt + yofs >= cropSize.y)
						continue;
					for (int xofsInt = 0; xofsInt < m_blockSize; ++xofsInt) {
						if (xofsInt + xofs >= cropSize.x)
							continue;
						int y = cropOffset.y + yofs + yofsInt;
						int x = cropOffset.x + xofs + xofsInt;
						cameraSampler->generate();
						for (size_t j = 0; j<sampleCount; j++) {
							if (needsLensSample)
								lensSample = cameraSampler->next2D();
							if (needsTimeSample)
								timeSample = cameraSampler->next1D();
							sample = cameraSampler->next2D();
							sample.x += x; sample.y += y;
							camera->generateRayDifferential(sample, 
								lensSample, timeSample, eyeRay);
							size_t offset = gatherPoints.size();
							Float count = (Float) createGatherPoints(scene, eyeRay, sample, 
									cameraSampler, Spectrum(1.0f),
								gatherPoints, 1);
							if (count > 1) { // necessary because of filter weight computation
								for (int i = 0; i<count; ++i)
									gatherPoints[offset+i].weight *= count;
							}

							cameraSampler->advance();
						}
					}
				}
				m_blocks.push_back(block);
				m_gatherPoints.push_back(gatherPoints);
			}
		}

		int it=0;
		while (m_running) 
			photonMapPass(++it, queue, job, film, sceneResID, cameraResID, independentSamplerResID);

#ifdef MTS_DEBUG_FP
		disableFPExceptions();
#endif

		sched->unregisterResource(independentSamplerResID);
		return true;
	}