void CaptureParticleWorker::handleMediumInteraction(int depth, int nullInteractions, bool caustic,
		const MediumSamplingRecord &mRec, const Medium *medium, const Vector &wi,
		const Spectrum &weight) {

	if (m_bruteForce || (depth >= m_maxPathDepth && m_maxPathDepth > 0))
		return;

	DirectSamplingRecord dRec(mRec);

	int maxInteractions = m_maxPathDepth - depth - 1;

	Spectrum value = weight * m_scene->sampleAttenuatedSensorDirect(
		dRec, medium, maxInteractions, m_sampler->next2D(), m_sampler);

	if (value.isZero())
		return;

	/* Evaluate the phase function */
	const PhaseFunction *phase = medium->getPhaseFunction();
	PhaseFunctionSamplingRecord pRec(mRec, wi, dRec.d, EImportance);
	value *= phase->eval(pRec);

	if (value.isZero())
		return;

	/* Splat onto the accumulation buffer */
	m_workResult->put(dRec.uv, (Float *) &value[0]);
}
Пример #2
0
void Test2(IDbSystem* pSystem, LPCTSTR pstrConnection)
{
   //pSystem->Initialize();

   CAutoPtr<IDbDatabase> pDb(pSystem->CreateDatabase());
   BOOL bRes;
   bRes = pDb->Open(NULL, pstrConnection, _T(""), _T(""), DB_OPEN_READ_ONLY);
   if( !bRes ) {
      TCHAR szMsg[256];
      pDb->GetErrors()->GetError(0)->GetMessage(szMsg, 256);
      ::MessageBox( NULL, szMsg, _T("Database Test"), MB_OK|MB_ICONERROR);
      return;
   }

   CAutoPtr<IDbCommand> pCmd(pSystem->CreateCommand(pDb));
   pCmd->Create(_T("SELECT ProductID,ProductName FROM Products WHERE ProductID=? AND ProductName=?"));
   long lVal = 2L;
   pCmd->SetParam(0, &lVal);
   pCmd->SetParam(1, _T("Chang"));
   CAutoPtr<IDbRecordset> pRec(pSystem->CreateRecordset(pDb));
   pCmd->Execute(pRec);
   while( !pRec->IsEOF() ) {
      long lID;
      TCHAR szTitle[128];
      pRec->GetField(0, lID);
      pRec->GetField(1, szTitle, 128);
      pRec->MoveNext();
   }
   pRec->Close();
   pCmd->Close();

   pDb->Close();

   //pSystem->Terminate();
}
Пример #3
0
	Spectrum sampleRay(Ray &ray,
			const Point2 &spatialSample,
			const Point2 &directionalSample,
			Float time) const {
		PositionSamplingRecord pRec(time);
		m_shape->samplePosition(pRec, spatialSample);
		Vector local = warp::squareToCosineHemisphere(directionalSample);
		ray.setTime(time);
		ray.setOrigin(pRec.p);
		ray.setDirection(Frame(pRec.n).toWorld(local));
		return m_power;
	}
	Spectrum sampleRay(Ray &ray, const Point2 &pixelSample,
			const Point2 &otherSample, Float timeSample) const {
		ray.time = sampleTime(timeSample);
		ray.mint = Epsilon;
		ray.maxt = std::numeric_limits<Float>::infinity();

		PositionSamplingRecord pRec(ray.time);
			m_shape->samplePosition(pRec, Point2(
			pixelSample.x * m_invResolution.x,
			pixelSample.y * m_invResolution.y));

		ray.setOrigin(pRec.p);
		ray.setDirection(Frame(pRec.n).toWorld(
			warp::squareToCosineHemisphere(otherSample)));

		return Spectrum(M_PI);
	}
Пример #5
0
	Float pdf(const BSDFQueryRecord &bRec, EMeasure measure) const {
		bool hasSingleScattering = (bRec.typeMask & EGlossy)
			&& (bRec.component == -1 || bRec.component == 0 || bRec.component == 1);
		bool hasSpecularTransmission = (bRec.typeMask & EDeltaTransmission)
			&& (bRec.component == -1 || bRec.component == 2);

		const Spectrum sigmaA = m_sigmaA->getValue(bRec.its),
				 sigmaS = m_sigmaS->getValue(bRec.its),
				 sigmaT = sigmaA + sigmaS,
				 tauD = sigmaT * m_thickness;

		Float probSpecularTransmission = (-tauD/std::abs(Frame::cosTheta(bRec.wi))).exp().average();

		if (measure == EDiscrete) {
			bool hasSpecularTransmission = (bRec.typeMask & EDeltaTransmission)
				&& (bRec.component == -1 || bRec.component == 2);
			/* Return the attenuated light if requested */
			if (hasSpecularTransmission &&
				std::abs(1+dot(bRec.wi, bRec.wo)) < Epsilon)
				return hasSingleScattering ? probSpecularTransmission : 1.0f;
		} else if (hasSingleScattering && measure == ESolidAngle) {
			bool hasGlossyReflection = (bRec.typeMask & EGlossyReflection)
				&& (bRec.component == -1 || bRec.component == 0);
			bool hasGlossyTransmission = (bRec.typeMask & EGlossyTransmission)
				&& (bRec.component == -1 || bRec.component == 1);
			bool reflection = Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0;

			if ((!hasGlossyReflection && reflection) ||
				(!hasGlossyTransmission && !reflection))
				return 0.0f;

			/* Sampled according to the phase function lobe(s) */
			MediumSamplingRecord dummy;
			PhaseFunctionQueryRecord pRec(dummy, bRec.wi, bRec.wo);
			Float pdf = m_phase->pdf(pRec);
			if (hasSpecularTransmission)
				pdf *= 1-probSpecularTransmission;
			return pdf;
		}
		return 0.0f;
	}
Пример #6
0
size_t generateVPLs(const Scene *scene, Random *random,
		size_t offset, size_t count, int maxDepth, bool prune, std::deque<VPL> &vpls) {
	if (maxDepth <= 1)
		return 0;

	static Sampler *sampler = NULL;
	if (!sampler) {
		Properties props("halton");
		props.setInteger("scramble", 0);
		sampler = static_cast<Sampler *> (PluginManager::getInstance()->
			createObject(MTS_CLASS(Sampler), props));
		sampler->configure();
	}

	const Sensor *sensor = scene->getSensor();
	Float time = sensor->getShutterOpen()
		+ 0.5f * sensor->getShutterOpenTime();

	const Frame stdFrame(Vector(1,0,0), Vector(0,1,0), Vector(0,0,1));

	while (vpls.size() < count) {
		sampler->setSampleIndex(++offset);

		PositionSamplingRecord pRec(time);
		DirectionSamplingRecord dRec;
		Spectrum weight = scene->sampleEmitterPosition(pRec,
			sampler->next2D());

		size_t start = vpls.size();

		/* Sample an emitted particle */
		const Emitter *emitter = static_cast<const Emitter *>(pRec.object);

		if (!emitter->isEnvironmentEmitter() && emitter->needsDirectionSample()) {
			VPL lumVPL(EPointEmitterVPL, weight);
			lumVPL.its.p = pRec.p;
			lumVPL.its.shFrame = pRec.n.isZero() ? stdFrame : Frame(pRec.n);
			lumVPL.emitter = emitter;
			appendVPL(scene, random, lumVPL, prune, vpls);

			weight *= emitter->sampleDirection(dRec, pRec, sampler->next2D());
		} else {
			/* Hack to get the proper information for directional VPLs */
			DirectSamplingRecord diRec(
				scene->getKDTree()->getAABB().getCenter(), pRec.time);

			Spectrum weight2 = emitter->sampleDirect(diRec, sampler->next2D())
				/ scene->pdfEmitterDiscrete(emitter);

			if (weight2.isZero())
				continue;

			VPL lumVPL(EDirectionalEmitterVPL, weight2);
			lumVPL.its.p = Point(0.0);
			lumVPL.its.shFrame = Frame(-diRec.d);
			lumVPL.emitter = emitter;
			appendVPL(scene, random, lumVPL, false, vpls);
			dRec.d = -diRec.d;

			Point2 offset = Warp::squareToUniformDiskConcentric(sampler->next2D());
			Vector perpOffset = Frame(diRec.d).toWorld(Vector(offset.x, offset.y, 0));
			BSphere geoBSphere = scene->getKDTree()->getAABB().getBSphere();
			pRec.p = geoBSphere.center + (perpOffset - dRec.d) * geoBSphere.radius;
			weight = weight2 * M_PI * geoBSphere.radius * geoBSphere.radius;
		}

		int depth = 2;
		Ray ray(pRec.p, dRec.d, time);
		Intersection its;

		while (!weight.isZero() && (depth < maxDepth || maxDepth == -1)) {
			if (!scene->rayIntersect(ray, its))
				break;

			const BSDF *bsdf = its.getBSDF();
			BSDFSamplingRecord bRec(its, sampler, EImportance);
			Spectrum bsdfVal = bsdf->sample(bRec, sampler->next2D());
			if (bsdfVal.isZero())
				break;

			/* Assuming that BSDF importance sampling is perfect,
				the following should equal the maximum albedo
				over all spectral samples */
			Float approxAlbedo = std::min((Float) 0.95f, bsdfVal.max());
			if (sampler->next1D() > approxAlbedo)
				break;
			else
				weight /= approxAlbedo;

			VPL vpl(ESurfaceVPL, weight);
			vpl.its = its;

			if (BSDF::getMeasure(bRec.sampledType) == ESolidAngle)
				appendVPL(scene, random, vpl, prune, vpls);

			weight *= bsdfVal;

			Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
			ray = Ray(its.p, wo, 0.0f);

			/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
			Float wiDotGeoN = dot(its.geoFrame.n, wi),
				woDotGeoN = dot(its.geoFrame.n, wo);
			if (wiDotGeoN * Frame::cosTheta(bRec.wi) <= 0 ||
				woDotGeoN * Frame::cosTheta(bRec.wo) <= 0)
				break;

			/* Disabled for now -- this increases VPL weights
			   and accuracy is not really a big requirement */
			#if 0
				/* Adjoint BSDF for shading normals -- [Veach, p. 155] */
				weight *= std::abs(
					(Frame::cosTheta(bRec.wi) * woDotGeoN)/
					(Frame::cosTheta(bRec.wo) * wiDotGeoN));
			#endif

			++depth;
		}

		size_t end = vpls.size();
		for (size_t i=start; i<end; ++i)
			vpls[i].emitterScale = 1.0f / (end - start);
	}

	return offset;
}
Пример #7
0
void ParticleTracer::process(const WorkUnit *workUnit, WorkResult *workResult,
		const bool &stop) {
	const RangeWorkUnit *range = static_cast<const RangeWorkUnit *>(workUnit);
	MediumSamplingRecord mRec;
	Intersection its;
	ref<Sensor> sensor    = m_scene->getSensor();
	bool needsTimeSample  = sensor->needsTimeSample();
	PositionSamplingRecord pRec(sensor->getShutterOpen()
		+ 0.5f * sensor->getShutterOpenTime());
	Ray ray;

	m_sampler->generate(Point2i(0));

	for (size_t index = range->getRangeStart(); index <= range->getRangeEnd() && !stop; ++index) {
		m_sampler->setSampleIndex(index);

		/* Sample an emission */
		if (needsTimeSample)
			pRec.time = sensor->sampleTime(m_sampler->next1D());

		const Emitter *emitter = NULL;
		const Medium *medium;

		Spectrum power;
		Ray ray;

		if (m_emissionEvents) {
			/* Sample the position and direction component separately to
			   generate emission events */
			power = m_scene->sampleEmitterPosition(pRec, m_sampler->next2D());
			emitter = static_cast<const Emitter *>(pRec.object);
			medium = emitter->getMedium();

			/* Forward the sampling event to the attached handler */
			handleEmission(pRec, medium, power);

			DirectionSamplingRecord dRec;
			power *= emitter->sampleDirection(dRec, pRec,
					emitter->needsDirectionSample() ? m_sampler->next2D() : Point2(0.5f));
			ray.setTime(pRec.time);
			ray.setOrigin(pRec.p);
			ray.setDirection(dRec.d);
		} else {
			/* Sample both components together, which is potentially
			   faster / uses a better sampling strategy */

			power = m_scene->sampleEmitterRay(ray, emitter,
				m_sampler->next2D(), m_sampler->next2D(), pRec.time);
			medium = emitter->getMedium();
			handleNewParticle();
		}

		int depth = 1, nullInteractions = 0;
		bool delta = false;

		Spectrum throughput(1.0f); // unitless path throughput (used for russian roulette)
		while (!throughput.isZero() && (depth <= m_maxDepth || m_maxDepth < 0)) {
			m_scene->rayIntersectAll(ray, its);

            /* ==================================================================== */
            /*                 Radiative Transfer Equation sampling                 */
            /* ==================================================================== */
			if (medium && medium->sampleDistance(Ray(ray, 0, its.t), mRec, m_sampler)) {
				/* Sample the integral
				  \int_x^y tau(x, x') [ \sigma_s \int_{S^2} \rho(\omega,\omega') L(x,\omega') d\omega' ] dx'
				*/

				throughput *= mRec.sigmaS * mRec.transmittance / mRec.pdfSuccess;

				/* Forward the medium scattering event to the attached handler */
				handleMediumInteraction(depth, nullInteractions,
						delta, mRec, medium, -ray.d, throughput*power);

				PhaseFunctionSamplingRecord pRec(mRec, -ray.d, EImportance);

				throughput *= medium->getPhaseFunction()->sample(pRec, m_sampler);
				delta = false;

				ray = Ray(mRec.p, pRec.wo, ray.time);
				ray.mint = 0;
			} else if (its.t == std::numeric_limits<Float>::infinity()) {
				/* There is no surface in this direction */
				break;
			} else {
				/* Sample
					tau(x, y) (Surface integral). This happens with probability mRec.pdfFailure
					Account for this and multiply by the proper per-color-channel transmittance.
				*/
				if (medium)
					throughput *= mRec.transmittance / mRec.pdfFailure;

				const BSDF *bsdf = its.getBSDF();

				/* Forward the surface scattering event to the attached handler */
				handleSurfaceInteraction(depth, nullInteractions, delta, its, medium, throughput*power);

				BSDFSamplingRecord bRec(its, m_sampler, EImportance);
				Spectrum bsdfWeight = bsdf->sample(bRec, m_sampler->next2D());
				if (bsdfWeight.isZero())
					break;

				/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
				Vector wi = -ray.d, wo = its.toWorld(bRec.wo);
				Float wiDotGeoN = dot(its.geoFrame.n, wi),
				      woDotGeoN = dot(its.geoFrame.n, wo);
				if (wiDotGeoN * Frame::cosTheta(bRec.wi) <= 0 ||
					woDotGeoN * Frame::cosTheta(bRec.wo) <= 0)
					break;

				/* Keep track of the weight, medium and relative
				   refractive index along the path */
				throughput *= bsdfWeight;
				if (its.isMediumTransition())
					medium = its.getTargetMedium(woDotGeoN);

				if (bRec.sampledType & BSDF::ENull)
					++nullInteractions;
				else
					delta = bRec.sampledType & BSDF::EDelta;

#if 0
				/* This is somewhat unfortunate: for accuracy, we'd really want the
				   correction factor below to match the path tracing interpretation
				   of a scene with shading normals. However, this factor can become
				   extremely large, which adds unacceptable variance to output
				   renderings.

				   So for now, it is disabled. The adjoint particle tracer and the
				   photon mapping variants still use this factor for the last
				   bounce -- just not for the intermediate ones, which introduces
				   a small (though in practice not noticeable) amount of error. This
				   is also what the implementation of SPPM by Toshiya Hachisuka does.

				   Ultimately, we'll need better adjoint BSDF sampling strategies
				   that incorporate these extra terms */

				/* Adjoint BSDF for shading normals -- [Veach, p. 155] */
				throughput *= std::abs(
					(Frame::cosTheta(bRec.wi) * woDotGeoN)/
					(Frame::cosTheta(bRec.wo) * wiDotGeoN));
#endif

				ray.setOrigin(its.p);
				ray.setDirection(wo);
				ray.mint = Epsilon;
			}

			if (depth++ >= m_rrDepth) {
				/* Russian roulette: try to keep path weights equal to one,
				   Stop with at least some probability to avoid
				   getting stuck (e.g. due to total internal reflection) */

				Float q = std::min(throughput.max(), (Float) 0.95f);
				if (m_sampler->next1D() >= q)
					break;
				throughput /= q;
			}
		}
	}
}
	Spectrum Li(const RayDifferential &r, RadianceQueryRecord &rRec) const {
		/* Some aliases and local variables */
		const Scene *scene = rRec.scene;
		Intersection &its = rRec.its;
		MediumSamplingRecord mRec;
		RayDifferential ray(r);
		Spectrum Li(0.0f);
		bool nullChain = true, scattered = false;
		Float eta = 1.0f;

		/* Perform the first ray intersection (or ignore if the
		   intersection has already been provided). */
		rRec.rayIntersect(ray);
		Spectrum throughput(1.0f);

		if (m_maxDepth == 1)
			rRec.type &= RadianceQueryRecord::EEmittedRadiance;

		/**
		 * Note: the logic regarding maximum path depth may appear a bit
		 * strange. This is necessary to get this integrator's output to
		 * exactly match the output of other integrators under all settings
		 * of this parameter.
		 */
		while (rRec.depth <= m_maxDepth || m_maxDepth < 0) {
			/* ==================================================================== */
			/*                 Radiative Transfer Equation sampling                 */
			/* ==================================================================== */
			if (rRec.medium && rRec.medium->sampleDistance(Ray(ray, 0, its.t), mRec, rRec.sampler)) {
				/* Sample the integral
				   \int_x^y tau(x, x') [ \sigma_s \int_{S^2} \rho(\omega,\omega') L(x,\omega') d\omega' ] dx'
				*/
				const PhaseFunction *phase = rRec.medium->getPhaseFunction();

				throughput *= mRec.sigmaS * mRec.transmittance / mRec.pdfSuccess;

				/* ==================================================================== */
				/*                     Direct illumination sampling                     */
				/* ==================================================================== */

				/* Estimate the single scattering component if this is requested */
				if (rRec.type & RadianceQueryRecord::EDirectMediumRadiance) {
					DirectSamplingRecord dRec(mRec.p, mRec.time);
					int maxInteractions = m_maxDepth - rRec.depth - 1;

					Spectrum value = scene->sampleAttenuatedEmitterDirect(
							dRec, rRec.medium, maxInteractions,
							rRec.nextSample2D(), rRec.sampler);

					if (!value.isZero())
						Li += throughput * value * phase->eval(
								PhaseFunctionSamplingRecord(mRec, -ray.d, dRec.d));
				}

				/* Stop if multiple scattering was not requested, or if the path gets too long */
				if ((rRec.depth + 1 >= m_maxDepth && m_maxDepth > 0) ||
					!(rRec.type & RadianceQueryRecord::EIndirectMediumRadiance))
					break;

				/* ==================================================================== */
				/*             Phase function sampling / Multiple scattering            */
				/* ==================================================================== */

				PhaseFunctionSamplingRecord pRec(mRec, -ray.d);
				Float phaseVal = phase->sample(pRec, rRec.sampler);
				if (phaseVal == 0)
					break;
				throughput *= phaseVal;

				/* Trace a ray in this direction */
				ray = Ray(mRec.p, pRec.wo, ray.time);
				ray.mint = 0;
				scene->rayIntersect(ray, its);
				nullChain = false;
				scattered = true;
			} else {
				/* Sample
					tau(x, y) * (Surface integral). This happens with probability mRec.pdfFailure
					Account for this and multiply by the proper per-color-channel transmittance.
				*/

				if (rRec.medium)
					throughput *= mRec.transmittance / mRec.pdfFailure;

				if (!its.isValid()) {
					/* If no intersection could be found, possibly return
					   attenuated radiance from a background luminaire */
					if ((rRec.type & RadianceQueryRecord::EEmittedRadiance)
						&& (!m_hideEmitters || scattered)) {
						Spectrum value = throughput * scene->evalEnvironment(ray);
						if (rRec.medium)
							value *= rRec.medium->evalTransmittance(ray);
						Li += value;
					}
					break;
				}

				/* Possibly include emitted radiance if requested */
				if (its.isEmitter() && (rRec.type & RadianceQueryRecord::EEmittedRadiance)
					&& (!m_hideEmitters || scattered))
					Li += throughput * its.Le(-ray.d);

				/* Include radiance from a subsurface integrator if requested */
				if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
					Li += throughput * its.LoSub(scene, rRec.sampler, -ray.d, rRec.depth);

				/* Prevent light leaks due to the use of shading normals */
				Float wiDotGeoN = -dot(its.geoFrame.n, ray.d),
					  wiDotShN  = Frame::cosTheta(its.wi);
				if (m_strictNormals && wiDotGeoN * wiDotShN < 0)
					break;

				/* ==================================================================== */
				/*                     Direct illumination sampling                     */
				/* ==================================================================== */

				const BSDF *bsdf = its.getBSDF(ray);

				/* Estimate the direct illumination if this is requested */
				if (rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance &&
						(bsdf->getType() & BSDF::ESmooth)) {
					DirectSamplingRecord dRec(its);
					int maxInteractions = m_maxDepth - rRec.depth - 1;

					Spectrum value = scene->sampleAttenuatedEmitterDirect(
							dRec, its, rRec.medium, maxInteractions,
							rRec.nextSample2D(), rRec.sampler);

					if (!value.isZero()) {
						/* Allocate a record for querying the BSDF */
						BSDFSamplingRecord bRec(its, its.toLocal(dRec.d));
						bRec.sampler = rRec.sampler;

						Float woDotGeoN = dot(its.geoFrame.n, dRec.d);
						/* Prevent light leaks due to the use of shading normals */
						if (!m_strictNormals ||
							woDotGeoN * Frame::cosTheta(bRec.wo) > 0)
							Li += throughput * value * bsdf->eval(bRec);
					}
				}

				/* ==================================================================== */
				/*                   BSDF sampling / Multiple scattering                */
				/* ==================================================================== */

				/* Sample BSDF * cos(theta) */
				BSDFSamplingRecord bRec(its, rRec.sampler, ERadiance);
				Spectrum bsdfVal = bsdf->sample(bRec, rRec.nextSample2D());
				if (bsdfVal.isZero())
					break;

				/* Recursively gather indirect illumination? */
				int recursiveType = 0;
				if ((rRec.depth + 1 < m_maxDepth || m_maxDepth < 0) &&
					(rRec.type & RadianceQueryRecord::EIndirectSurfaceRadiance))
					recursiveType |= RadianceQueryRecord::ERadianceNoEmission;

				/* Recursively gather direct illumination? This is a bit more
				   complicated by the fact that this integrator can create connection
				   through index-matched medium transitions (ENull scattering events) */
				if ((rRec.depth < m_maxDepth || m_maxDepth < 0) &&
					(rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance) &&
					(bRec.sampledType & BSDF::EDelta) &&
					(!(bRec.sampledType & BSDF::ENull) || nullChain)) {
					recursiveType |= RadianceQueryRecord::EEmittedRadiance;
					nullChain = true;
				} else {
					nullChain &= bRec.sampledType == BSDF::ENull;
				}

				/* Potentially stop the recursion if there is nothing more to do */
				if (recursiveType == 0)
					break;
				rRec.type = recursiveType;

				/* Prevent light leaks due to the use of shading normals */
				const Vector wo = its.toWorld(bRec.wo);
				Float woDotGeoN = dot(its.geoFrame.n, wo);
				if (woDotGeoN * Frame::cosTheta(bRec.wo) <= 0 && m_strictNormals)
					break;

				/* Keep track of the throughput, medium, and relative
				   refractive index along the path */
				throughput *= bsdfVal;
				eta *= bRec.eta;
				if (its.isMediumTransition())
					rRec.medium = its.getTargetMedium(wo);

				/* In the next iteration, trace a ray in this direction */
				ray = Ray(its.p, wo, ray.time);
				scene->rayIntersect(ray, its);
				scattered |= bRec.sampledType != BSDF::ENull;
			}

			if (rRec.depth++ >= m_rrDepth) {
				/* Russian roulette: try to keep path weights equal to one,
				   while accounting for the solid angle compression at refractive
				   index boundaries. Stop with at least some probability to avoid
				   getting stuck (e.g. due to total internal reflection) */

				Float q = std::min(throughput.max() * eta * eta, (Float) 0.95f);
				if (rRec.nextSample1D() >= q)
					break;
				throughput /= q;
			}
		}
		avgPathLength.incrementBase();
		avgPathLength += rRec.depth;
		return Li;
	}
Пример #9
0
	inline Spectrum sample(BSDFQueryRecord &bRec, Float &_pdf, const Point2 &_sample) const {
		AssertEx(bRec.sampler != NULL, "The BSDFQueryRecord needs to have a sampler!");

		bool hasSpecularTransmission = (bRec.typeMask & EDeltaTransmission)
			&& (bRec.component == -1 || bRec.component == 2);
		bool hasSingleScattering = (bRec.typeMask & EGlossy)
			&& (bRec.component == -1 || bRec.component == 0 || bRec.component == 1);

		const Spectrum sigmaA = m_sigmaA->getValue(bRec.its),
				 sigmaS = m_sigmaS->getValue(bRec.its),
				 sigmaT = sigmaA + sigmaS,
				 tauD = sigmaT * m_thickness;

		/* Probability for a specular transmission is approximated by the average (per wavelength) 
		 * probability of a photon exiting without a scattering event or an absorption event */
		Float probSpecularTransmission = (-tauD/std::abs(Frame::cosTheta(bRec.wi))).exp().average();

		bool choseSpecularTransmission = hasSpecularTransmission;

		Point2 sample(_sample);
		if (hasSpecularTransmission && hasSingleScattering) {
			if (sample.x > probSpecularTransmission) {
				sample.x = (sample.x - probSpecularTransmission) / (1 - probSpecularTransmission);
				choseSpecularTransmission = false;
			}
		}

		if (choseSpecularTransmission) {
			/* The specular transmission component was sampled */
			bRec.sampledComponent = 2;
			bRec.sampledType = EDeltaTransmission;

			bRec.wo = -bRec.wi;

			_pdf = hasSingleScattering ? probSpecularTransmission : 1.0f;
			return eval(bRec, EDiscrete) / _pdf;
		} else {
			/* The glossy transmission/scattering component should be sampled */
			bool hasGlossyReflection = (bRec.typeMask & EGlossyReflection)
				&& (bRec.component == -1 || bRec.component == 0);
			bool hasGlossyTransmission = (bRec.typeMask & EGlossyTransmission)
				&& (bRec.component == -1 || bRec.component == 1);

			/* Sample According to the phase function lobes */
			PhaseFunctionQueryRecord pRec(MediumSamplingRecord(), bRec.wi, bRec.wo);
			m_phase->sample(pRec, _pdf, bRec.sampler);

			/* Store the sampled direction */
			bRec.wo = pRec.wo;
			
			bool reflection = Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0;
			if ((!hasGlossyReflection && reflection) ||
				(!hasGlossyTransmission && !reflection))
				return Spectrum(0.0f);

			/* Notify that the scattering component was sampled */
			bRec.sampledComponent = reflection ? 0 : 1;
			bRec.sampledType = EGlossy;

			_pdf *= (hasSpecularTransmission ? (1 - probSpecularTransmission) : 1.0f);

			/* Guard against numerical imprecisions */
			if (_pdf == 0) 
				return Spectrum(0.0f);
			else
				return eval(bRec, ESolidAngle) / _pdf;

		}
	}
Пример #10
0
	Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
		Spectrum sigmaA = m_sigmaA->getValue(bRec.its),
				 sigmaS = m_sigmaS->getValue(bRec.its),
				 sigmaT = sigmaA + sigmaS,
				 tauD = sigmaT * m_thickness,
				 result(0.0f);

		if (measure == EDiscrete) {
			/* Figure out if the specular transmission is specifically requested */
			bool hasSpecularTransmission = (bRec.typeMask & EDeltaTransmission)
				&& (bRec.component == -1 || bRec.component == 2);

			/* Return the attenuated light if requested */
			if (hasSpecularTransmission &&
				std::abs(1+dot(bRec.wi, bRec.wo)) < Epsilon)
				result = (-tauD/std::abs(Frame::cosTheta(bRec.wi))).exp();
		} else if (measure == ESolidAngle) {
			/* Sample single scattering events */
			bool hasGlossyReflection = (bRec.typeMask & EGlossyReflection)
				&& (bRec.component == -1 || bRec.component == 0);
			bool hasGlossyTransmission = (bRec.typeMask & EGlossyTransmission)
				&& (bRec.component == -1 || bRec.component == 1);
		
			Spectrum albedo;
			for (int i = 0; i < SPECTRUM_SAMPLES; i++)
				albedo[i] = sigmaT[i] > 0 ? (sigmaS[i]/sigmaT[i]) : (Float) 0;

			const Float cosThetaI = Frame::cosTheta(bRec.wi),
				        cosThetaO = Frame::cosTheta(bRec.wo),
				        dp = cosThetaI*cosThetaO;
		
			bool reflection = dp > 0, transmission = dp < 0;

			/* ==================================================================== */
			/*                        Reflection component                          */
			/* ==================================================================== */

			if (hasGlossyReflection && reflection) {
				MediumSamplingRecord dummy;
				PhaseFunctionQueryRecord pRec(dummy,bRec.wi,bRec.wo); 
				const Float phaseVal = m_phase->eval(pRec);

				result = albedo * (phaseVal*cosThetaI/(cosThetaI+cosThetaO)) *
					(Spectrum(1.0f)-((-1.0f/std::abs(cosThetaI)-1.0f/std::abs(cosThetaO)) * tauD).exp());
			}

			/* ==================================================================== */
			/*                       Transmission component                         */
			/* ==================================================================== */

			if (hasGlossyTransmission && transmission
					&& m_thickness < std::numeric_limits<Float>::infinity()) {
				MediumSamplingRecord dummy;
				PhaseFunctionQueryRecord pRec(dummy,bRec.wi,bRec.wo);
				const Float phaseVal = m_phase->eval(pRec);

				/* Hanrahan etal 93 Single Scattering transmission term */
				if (std::abs(cosThetaI + cosThetaO) < Epsilon) {
					/* avoid division by zero */
					result += albedo * phaseVal*tauD/std::abs(cosThetaO) * 
								((-tauD/std::abs(cosThetaO)).exp());
				} else {
					/* Guaranteed to be positive even if |cosThetaO| > |cosThetaI| */
					result += albedo * phaseVal*std::abs(cosThetaI)/(std::abs(cosThetaI)-std::abs(cosThetaO)) * 
						((-tauD/std::abs(cosThetaI)).exp() - (-tauD/std::abs(cosThetaO)).exp());
				}
			}
			return result * std::abs(cosThetaO);
		}
		return result;
	}
Пример #11
0
void Test1(IDbSystem* pSystem, LPCTSTR pstrConnection)
{
   //pSystem->Initialize();

   CAutoPtr<IDbDatabase> pDb(pSystem->CreateDatabase());
   BOOL bRes;
   bRes = pDb->Open(NULL, pstrConnection, _T(""), _T(""), DB_OPEN_READ_ONLY);
   if( !bRes ) {
      TCHAR szMsg[256];
      pDb->GetErrors()->GetError(0)->GetMessage(szMsg, 256);
      ::MessageBox( NULL, szMsg, _T("Database Test"), MB_OK|MB_ICONERROR);
      return;
   }

   CAutoPtr<IDbRecordset> pRec(pSystem->CreateRecordset(pDb));
   bRes = pRec->Open(_T("SELECT * FROM [dbo].[tbStudy]"), DB_OPEN_TYPE_DYNASET);
   
   DWORD dwCnt = pRec->GetRowCount();
   dwCnt;

   while( !pRec->IsEOF() ) {
      long lID;
      TCHAR szTitle[128];
      float fUnitPrice;
      double dblUnitPrice;
      bool bDiscontinued;
      pRec->GetField(0, lID);
      pRec->GetField(1, szTitle, 128);
      pRec->GetField(2, fUnitPrice);
      pRec->GetField(2, dblUnitPrice);
      pRec->GetField(3, bDiscontinued);
      pRec->MoveNext();
      //DWORD dwRow = pRec->GetRowNumber();
   }

   {
     CAutoPtr<IDbCommand> pCmd(pSystem->CreateCommand(pDb));
     bRes = pCmd->Create(_T("EXEC [dcmqrdb].[dbo].[spRegisterDcmSeries] @studyUiid = ?, @seriesUiid = ?;"));

     bRes = pCmd->SetParam(0, _T("8888"));
     bRes = pCmd->SetParam(1, _T("9999"));


     CAutoPtr<IDbRecordset> pRec(pSystem->CreateRecordset(pDb));
     bRes = pCmd->Execute(pRec);
     while( !pRec->IsEOF() ) {
       long lID;
       TCHAR szTitle[128];
       pRec->GetField(0, lID);
       pRec->GetField(1, szTitle, 128);
       pRec->MoveNext();
     }
   }

   DWORD nFields = pRec->GetColumnCount();
   nFields;
   long iIndex = pRec->GetColumnIndex(_T("UnitPrice"));
   iIndex;

   pRec->Close();

   pDb->Close();

   //pSystem->Terminate();
}