Spectrum ExPhotonIntegrator::LPhoton(
		KdTree<Photon, PhotonProcess> *map,
		int nPaths, int nLookup, BSDF *bsdf,
		const Intersection &isect, const Vector &wo,
		float maxDistSquared) {
	Spectrum L(0.);
	if (!map) return L;
	BxDFType nonSpecular = BxDFType(BSDF_REFLECTION |
		BSDF_TRANSMISSION | BSDF_DIFFUSE | BSDF_GLOSSY);
	if (bsdf->NumComponents(nonSpecular) == 0)
		return L;
	static StatsCounter lookups("Photon Map", "Total lookups"); // NOBOOK
	// Initialize _PhotonProcess_ object, _proc_, for photon map lookups
	PhotonProcess proc(nLookup, isect.dg.p);
	proc.photons =
		(ClosePhoton *)alloca(nLookup * sizeof(ClosePhoton));
	// Do photon map lookup
	++lookups;  // NOBOOK
	map->Lookup(isect.dg.p, proc, maxDistSquared);
	// Accumulate light from nearby photons
	static StatsRatio foundRate("Photon Map", "Photons found per lookup"); // NOBOOK
	foundRate.Add(proc.foundPhotons, 1); // NOBOOK
	// Estimate reflected light from photons
	ClosePhoton *photons = proc.photons;
	int nFound = proc.foundPhotons;
	Normal Nf = Dot(wo, bsdf->dgShading.nn) < 0 ? -bsdf->dgShading.nn :
		bsdf->dgShading.nn;

	if (bsdf->NumComponents(BxDFType(BSDF_REFLECTION |
			BSDF_TRANSMISSION | BSDF_GLOSSY)) > 0) {
		// Compute exitant radiance from photons for glossy surface
		for (int i = 0; i < nFound; ++i) {
			const Photon *p = photons[i].photon;
			BxDFType flag = Dot(Nf, p->wi) > 0.f ?
				BSDF_ALL_REFLECTION : BSDF_ALL_TRANSMISSION;
			float k = kernel(p, isect.dg.p, maxDistSquared);
			L += (k / nPaths) * bsdf->f(wo, p->wi, flag) * p->alpha;
		}
	}
	else {
		// Compute exitant radiance from photons for diffuse surface
		Spectrum Lr(0.), Lt(0.);
		for (int i = 0; i < nFound; ++i) {
			if (Dot(Nf, photons[i].photon->wi) > 0.f) {
				float k = kernel(photons[i].photon, isect.dg.p,
					maxDistSquared);
				Lr += (k / nPaths) * photons[i].photon->alpha;
			}
			else {
				float k = kernel(photons[i].photon, isect.dg.p,
					maxDistSquared);
				Lt += (k / nPaths) * photons[i].photon->alpha;
			}
		}
		L += Lr * bsdf->rho(wo, BSDF_ALL_REFLECTION) * INV_PI +
			Lt * bsdf->rho(wo, BSDF_ALL_TRANSMISSION) * INV_PI;
	}
	return L;
}
Exemple #2
0
Spectrum LPhoton(KdTree<Photon> *map, int nPaths, int nLookup,
      MemoryArena &arena, BSDF *bsdf, RNG &rng, const Intersection &isect,
      const Vector &wo, float maxDistSquared) {
    Spectrum L(0.);
    BxDFType nonSpecular = BxDFType(BSDF_REFLECTION |
        BSDF_TRANSMISSION | BSDF_DIFFUSE | BSDF_GLOSSY);
    if (map && bsdf->NumComponents(nonSpecular) > 0) {
        PBRT_PHOTON_MAP_STARTED_LOOKUP(const_cast<DifferentialGeometry *>(&isect.dg));
        // Do photon map lookup at intersection point
        PhotonProcess proc(nLookup, arena.Alloc<ClosePhoton>(nLookup));
        map->Lookup(isect.dg.p, proc, maxDistSquared);

        // Estimate reflected radiance due to incident photons
        ClosePhoton *photons = proc.photons;
        int nFound = proc.nFound;
        Normal Nf = Faceforward(bsdf->dgShading.nn, wo);
        if (bsdf->NumComponents(BxDFType(BSDF_REFLECTION |
                BSDF_TRANSMISSION | BSDF_GLOSSY)) > 0) {
            // Compute exitant radiance from photons for glossy surface
            for (int i = 0; i < nFound; ++i) {
                const Photon *p = photons[i].photon;
                float k = kernel(p, isect.dg.p, maxDistSquared);
                L += (k / (nPaths * maxDistSquared)) * bsdf->f(wo, p->wi) *
                     p->alpha;
            }
        }
        else {
            // Compute exitant radiance from photons for diffuse surface
            Spectrum Lr(0.), Lt(0.);
            for (int i = 0; i < nFound; ++i) {
                if (Dot(Nf, photons[i].photon->wi) > 0.f) {
                    float k = kernel(photons[i].photon, isect.dg.p,
                        maxDistSquared);
                    Lr += (k / (nPaths * maxDistSquared)) * photons[i].photon->alpha;
                }
                else {
                    float k = kernel(photons[i].photon, isect.dg.p,
                        maxDistSquared);
                    Lt += (k / (nPaths * maxDistSquared)) * photons[i].photon->alpha;
                }
            }
            const int sqrtRhoSamples = 4;
            float rhoRSamples[2*sqrtRhoSamples*sqrtRhoSamples];
            StratifiedSample2D(rhoRSamples, sqrtRhoSamples, sqrtRhoSamples, rng);
            float rhoTSamples[2*sqrtRhoSamples*sqrtRhoSamples];
            StratifiedSample2D(rhoTSamples, sqrtRhoSamples, sqrtRhoSamples, rng);
            L += Lr * bsdf->rho(wo, sqrtRhoSamples*sqrtRhoSamples, rhoRSamples,
                                BSDF_ALL_REFLECTION) * INV_PI +
                 Lt * bsdf->rho(wo, sqrtRhoSamples*sqrtRhoSamples, rhoTSamples,
                                BSDF_ALL_TRANSMISSION) * INV_PI;
        }
        PBRT_PHOTON_MAP_FINISHED_LOOKUP(const_cast<DifferentialGeometry *>(&isect.dg),
            proc.nFound, proc.nLookup, &L);
    }
    return L;
}
void RowChecksumMatrixTest::testMatrix() {
	RowChecksumMatrix<double>& Lr = *this->Lr;
	RowChecksumMatrix<double>& L2r = *this->L2r;
	RowChecksumMatrix<double>& Ur = *this->Ur;

    // getM(), getN()
	CPPUNIT_ASSERT(Lr.getM() == 2);
	CPPUNIT_ASSERT(Lr.getN() == 3);

	// getData()
	CPPUNIT_ASSERT(Ur.getData() == UData);

	// getDataAllocation()
	CPPUNIT_ASSERT(!Lr.getDataAllocation());
	CPPUNIT_ASSERT(!L2r.getDataAllocation());
	CPPUNIT_ASSERT(!Ur.getDataAllocation());

	// operator==
	CPPUNIT_ASSERT(Lr == Lr);
	CPPUNIT_ASSERT(Lr == L2r);
	CPPUNIT_ASSERT(!(Lr == Ur));

	// operator=
	(IMatrix<double>&) L2r = Ur;
	CPPUNIT_ASSERT(L2r == Ur);
	CPPUNIT_ASSERT(*L2 == *U);
	CPPUNIT_ASSERT(!(Lr == L2r));

	// operator()
	CPPUNIT_ASSERT(Lr(1,1) == 1.);
	CPPUNIT_ASSERT(Lr(1,2) == 0.);
	CPPUNIT_ASSERT(Lr(1,3) == 1.);
	CPPUNIT_ASSERT(Lr(2,1) == 1.5);
	CPPUNIT_ASSERT(Lr(2,2) == 1.);
	CPPUNIT_ASSERT(Lr(2,3) == 2.5);
	L2r(1,1) = 1.;
	L2r(1,2) = 0.;
	L2r(1,3) = 1.;
	L2r(2,1) = 1.5;
	L2r(2,2) = 1.;
	L2r(2,3) = 2.5;
	CPPUNIT_ASSERT(L2r(1,1) == 1.);
	CPPUNIT_ASSERT(L2r(1,2) == 0.);
	CPPUNIT_ASSERT(L2r(1,3) == 1.);
	CPPUNIT_ASSERT(L2r(2,1) == 1.5);
	CPPUNIT_ASSERT(L2r(2,2) == 1.);
	CPPUNIT_ASSERT(L2r(2,3) == 2.5);
	CPPUNIT_ASSERT(Lr == L2r);

	// distance()
	CPPUNIT_ASSERT(Lr.distance(Lr) == 0);
	CPPUNIT_ASSERT(Lr.distance(L2r) == 0); CPPUNIT_ASSERT(L2r.distance(Lr) == 0);
	CPPUNIT_ASSERT(Lr.distance(Ur) == 6); CPPUNIT_ASSERT(Ur.distance(Lr) == 6);
	L2r(2,2) = 0.;
	CPPUNIT_ASSERT(Lr.distance(L2r) == 1); CPPUNIT_ASSERT(L2r.distance(Lr) == 1);

	// weight()
	CPPUNIT_ASSERT(Lr.weight() == 5);
	CPPUNIT_ASSERT(L2r.weight() == 4);
	CPPUNIT_ASSERT(Ur.weight() == 5);

	// toString()
	CPPUNIT_ASSERT(Lr.toString().compare("[\n1 0 1 \n1.5 1 2.5 \n]\n") == 0);

	// locationId()
	for(int i = 1; i <= Lr.getM(); i++){
		for(int j = 1; j <= Lr.getN(); j++){
			for(int k = 1; k <= Lr.getM(); k++){
					for(int l = 1; l <= Lr.getN(); l++){
						if(!(i == k && j == l)) CPPUNIT_ASSERT(Lr.locationId(i, j) != Lr.locationId(k, l));
					}
			}
		}
	}
}