示例#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;
}
示例#2
0
	void sampleEmission(EmissionRecord &eRec,
		const Point2 &sample1, const Point2 &sample2) const {
		eRec.pdfArea = m_shape->sampleArea(eRec.sRec, sample1);
		Vector wo = squareToHemispherePSA(sample2);
		eRec.pdfDir = Frame::cosTheta(wo) * INV_PI;
		eRec.d = Frame(eRec.sRec.n).toWorld(wo);
		eRec.value = m_intensity;
	}
 Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
     if (!(bRec.typeMask & EDiffuseTransmission))
         return Spectrum(0.0f);
     bRec.wo = squareToHemispherePSA(sample);
     if (Frame::cosTheta(bRec.wi) > 0)
         bRec.wo.z *= -1;
     bRec.sampledComponent = 0;
     bRec.sampledType = EDiffuseTransmission;
     return m_transmittance->getValue(bRec.its);
 }
示例#4
0
void VPLShaderManager::setVPL(const VPL &vpl) {
	Point p = vpl.its.p + vpl.its.shFrame.n * 0.01;
	Intersection its;

	/* Estimate good near and far plane locations by tracing some rays */
	Float nearClip =  std::numeric_limits<Float>::infinity(),
		  farClip  = -std::numeric_limits<Float>::infinity();
	Ray ray;
	ray.o = p;

	if (m_shadowMap == NULL || m_shadowMapResolution != m_shadowMap->getSize().x) {
		m_shadowMap = m_renderer->createGPUTexture("Shadow cube map", NULL);
		m_shadowMap->setSize(Point3i(m_shadowMapResolution, m_shadowMapResolution, 1));
		m_shadowMap->setFrameBufferType(GPUTexture::EDepthBuffer);
		m_shadowMap->setType(GPUTexture::ETextureCubeMap);
		m_shadowMap->setWrapType(GPUTexture::EClampToEdge);
		m_shadowMap->setFilterType(GPUTexture::ENearest);
		m_shadowMap->setDepthMode(GPUTexture::ENormal);
		m_shadowMap->init();
	}

	const int sampleCount = 200;
	const Float invSampleCount = 1.0f/sampleCount;

	for (int i=1; i<=sampleCount; ++i) {
		Vector dir;
		Point2 seed(i*invSampleCount, radicalInverse(2, i)); // Hammersley seq.
		if (vpl.type == ESurfaceVPL || vpl.luminaire->getType() & Luminaire::EOnSurface)
			dir = vpl.its.shFrame.toWorld(squareToHemispherePSA(seed));
		else
			dir = squareToSphere(seed);
		ray.setDirection(dir);
		if (m_scene->rayIntersect(ray, its)) {
			nearClip = std::min(nearClip, its.t);
			farClip = std::max(farClip, its.t);
		}
	}

	m_minDist = nearClip + (farClip - nearClip) * m_clamping;

	nearClip = std::min(nearClip, (Float) 0.001f);
	farClip = std::min(farClip * 1.5f, m_maxClipDist);

	if (farClip < 0 || nearClip >= farClip) {
		/* Unable to find any surface - just default values based on the scene size */
		nearClip = 1e-3f * m_scene->getBSphere().radius;
		farClip = 2 * m_scene->getBSphere().radius;
		m_minDist = 0;
	}
	farClip = std::min(farClip, 5.0f*m_scene->getBSphere().radius);

	m_nearClip = nearClip;
	m_invClipRange = 1/(farClip-nearClip);
	Transform lightViewTrafo, lightProjTrafo = Transform::glPerspective(90.0f, nearClip, farClip);
	Matrix4x4 identity;
	identity.setIdentity();
	m_renderer->setCamera(identity, identity);

	m_shadowMap->activateTarget();
	if (m_singlePass && m_shadowProgram != NULL) {
		/* "Fancy": render the whole cube map in a single pass using 
		   a geometry program. On anything but brand-new hardware, this 
		   is actually slower. */

		m_shadowMap->activateSide(-1);
		m_shadowMap->clear();
		m_shadowProgram->bind();
		try {
			for (int i=0; i<6; ++i) {
				switch (i) {
					case 0: lightViewTrafo = Transform::lookAt(p, p + Vector(1, 0, 0), Vector(0, 1, 0)).inverse(); break;
					case 1: lightViewTrafo = Transform::lookAt(p, p + Vector(-1, 0, 0), Vector(0, 1, 0)).inverse(); break;
					case 2: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 1, 0), Vector(0, 0, -1)).inverse(); break;
					case 3: lightViewTrafo = Transform::lookAt(p, p + Vector(0, -1, 0), Vector(0, 0, 1)).inverse(); break;
					case 4: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 0, 1), Vector(0, 1, 0)).inverse(); break;
					case 5: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 0, -1), Vector(0, 1, 0)).inverse(); break;
				}
				lightViewTrafo = Transform::scale(Vector(-1, 1, 1)) * lightViewTrafo;
				const Matrix4x4 &viewMatrix = lightViewTrafo.getMatrix();
				m_shadowProgram->setParameter(m_shadowProgramParam_cubeMapTransform[i], lightProjTrafo * lightViewTrafo);
				m_shadowProgram->setParameter(m_shadowProgramParam_depthVec[i], Vector4(
					-viewMatrix.m[2][0] * m_invClipRange,
					-viewMatrix.m[2][1] * m_invClipRange,
					-viewMatrix.m[2][2] * m_invClipRange,
					(-viewMatrix.m[2][3] - m_nearClip) * m_invClipRange
				));
			}
			m_renderer->drawAll(m_drawList);
		} catch (const std::exception &ex) {
			m_shadowProgram->unbind();
			throw ex;
		}
		m_shadowProgram->unbind();
	} else {
		/* Old-fashioned: render 6 times, once for each cube map face */
		m_altShadowProgram->bind();
		try {
			for (int i=0; i<6; ++i) {
				switch (i) {
					case 0: lightViewTrafo = Transform::lookAt(p, p + Vector(1, 0, 0), Vector(0, 1, 0)).inverse(); break;
					case 1: lightViewTrafo = Transform::lookAt(p, p + Vector(-1, 0, 0), Vector(0, 1, 0)).inverse(); break;
					case 2: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 1, 0), Vector(0, 0, -1)).inverse(); break;
					case 3: lightViewTrafo = Transform::lookAt(p, p + Vector(0, -1, 0), Vector(0, 0, 1)).inverse(); break;
					case 4: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 0, 1), Vector(0, 1, 0)).inverse(); break;
					case 5: lightViewTrafo = Transform::lookAt(p, p + Vector(0, 0, -1), Vector(0, 1, 0)).inverse(); break;
				}
				lightViewTrafo = Transform::scale(Vector(-1, 1, 1)) * lightViewTrafo;
				const Matrix4x4 &viewMatrix = lightViewTrafo.getMatrix();

				m_altShadowProgram->setParameter(m_altShadowProgramParam_cubeMapTransform, lightProjTrafo * lightViewTrafo);
				m_altShadowProgram->setParameter(m_altShadowProgramParam_depthVec, Vector4(
					-viewMatrix.m[2][0] * m_invClipRange,
					-viewMatrix.m[2][1] * m_invClipRange,
					-viewMatrix.m[2][2] * m_invClipRange,
					(-viewMatrix.m[2][3] - m_nearClip) * m_invClipRange
				));

				m_shadowMap->activateSide(i);
				m_shadowMap->clear();
				m_renderer->drawAll(m_drawList);
			}
		} catch (std::exception &ex) {
			m_altShadowProgram->unbind();
			throw ex;
		}

		m_altShadowProgram->unbind();
	}
	m_shadowMap->releaseTarget();
}
示例#5
0
	Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const {
		Vector wo = squareToHemispherePSA(sample);
		eRec.d = Frame(eRec.sRec.n).toWorld(wo);
		eRec.pdfDir = Frame::cosTheta(wo) * INV_PI;
		return Spectrum(INV_PI);
	}