本文整理汇总了C++中Intersection::getTargetMedium方法的典型用法代码示例。如果您正苦于以下问题:C++ Intersection::getTargetMedium方法的具体用法?C++ Intersection::getTargetMedium怎么用?C++ Intersection::getTargetMedium使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Intersection
的用法示例。
在下文中一共展示了Intersection::getTargetMedium方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: handleSurfaceInteraction
void CaptureParticleWorker::handleSurfaceInteraction(int depth,
bool caustic, const Intersection &its, const Medium *medium,
const Spectrum &weight) {
const ProjectiveCamera *camera = static_cast<const ProjectiveCamera *>(m_camera.get());
Point2 screenSample;
if (camera->positionToSample(its.p, screenSample)) {
Point cameraPosition = camera->getPosition(screenSample);
Float t = dot(camera->getImagePlaneNormal(), its.p-cameraPosition);
if (t < camera->getNearClip() || t > camera->getFarClip())
return;
if (its.isMediumTransition())
medium = its.getTargetMedium(cameraPosition - its.p);
Spectrum transmittance = m_scene->getTransmittance(its.p,
cameraPosition, its.time, medium);
if (transmittance.isZero())
return;
const BSDF *bsdf = its.shape->getBSDF();
Vector wo = cameraPosition - its.p;
Float dist = wo.length(); wo /= dist;
BSDFQueryRecord bRec(its, its.toLocal(wo));
bRec.quantity = EImportance;
Float importance;
if (m_isPerspectiveCamera)
importance = ((const PerspectiveCamera *) camera)->importance(screenSample) / (dist * dist);
else
importance = 1/camera->areaDensity(screenSample);
Vector wi = its.toWorld(its.wi);
/* 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)
return;
/* Adjoint BSDF for shading normals -- [Veach, p. 155] */
Float correction = std::abs(
(Frame::cosTheta(bRec.wi) * woDotGeoN)/
(Frame::cosTheta(bRec.wo) * wiDotGeoN));
/* Splat onto the accumulation buffer */
Ray ray(its.p, wo, 0, dist, its.time);
Spectrum sampleVal = weight * bsdf->fCos(bRec)
* transmittance * (importance * correction);
m_workResult->splat(screenSample, sampleVal, m_filter);
}
}
示例2: process
//.........这里部分代码省略.........
/* 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;
}
}
}
}
示例3: pathConnectAndCollapse
bool PathEdge::pathConnectAndCollapse(const Scene *scene, const PathEdge *predEdge,
const PathVertex *vs, const PathVertex *vt,
const PathEdge *succEdge, int &interactions) {
if (vs->isEmitterSupernode() || vt->isSensorSupernode()) {
Float radianceTransport = vt->isSensorSupernode() ? 1.0f : 0.0f,
importanceTransport = 1-radianceTransport;
medium = NULL;
length = 0.0f;
d = Vector(0.0f);
pdf[ERadiance] = radianceTransport;
pdf[EImportance] = importanceTransport;
weight[ERadiance] = Spectrum(radianceTransport);
weight[EImportance] = Spectrum(importanceTransport);
interactions = 0;
} else {
Point vsp = vs->getPosition(), vtp = vt->getPosition();
d = vsp-vtp;
length = d.length();
int maxInteractions = interactions;
interactions = 0;
if (length == 0) {
#if defined(MTS_BD_DEBUG)
SLog(EWarn, "Tried to connect %s and %s, which are located at exactly the same position!",
vs->toString().c_str(), vt->toString().c_str());
#endif
return false;
}
d /= length;
Float lengthFactor = vs->isOnSurface() ? (1-ShadowEpsilon) : 1;
Ray ray(vtp, d, vt->isOnSurface() ? Epsilon : 0, length * lengthFactor, vs->getTime());
weight[ERadiance] = Spectrum(1.0f);
weight[EImportance] = Spectrum(1.0f);
pdf[ERadiance] = 1.0f;
pdf[EImportance] = 1.0f;
Intersection its;
Float remaining = length;
medium = vt->getTargetMedium(succEdge, d);
while (true) {
bool surface = scene->rayIntersectAll(ray, its);
if (surface && (interactions == maxInteractions ||
!(its.getBSDF()->getType() & BSDF::ENull))) {
/* Encountered an occluder -- zero transmittance. */
return false;
}
if (medium) {
Float segmentLength = std::min(its.t, remaining);
MediumSamplingRecord mRec;
medium->eval(Ray(ray, 0, segmentLength), mRec);
Float pdfRadiance = (surface || !vs->isMediumInteraction())
? mRec.pdfFailure : mRec.pdfSuccess;
Float pdfImportance = (interactions > 0 || !vt->isMediumInteraction())
? mRec.pdfFailure : mRec.pdfSuccessRev;
if (pdfRadiance == 0 || pdfImportance == 0 || mRec.transmittance.isZero()) {
/* Zero transmittance */
return false;
}
weight[EImportance] *= mRec.transmittance / pdfImportance;
weight[ERadiance] *= mRec.transmittance / pdfRadiance;
pdf[EImportance] *= pdfImportance;
pdf[ERadiance] *= pdfRadiance;
}
if (!surface || remaining - its.t < 0)
break;
/* Advance the ray */
ray.o = ray(its.t);
remaining -= its.t;
ray.mint = Epsilon;
ray.maxt = remaining * lengthFactor;
/* Account for the ENull interaction */
const BSDF *bsdf = its.getBSDF();
Vector wo = its.toLocal(ray.d);
BSDFSamplingRecord bRec(its, -wo, wo, ERadiance);
bRec.component = BSDF::ENull;
Float nullPdf = bsdf->pdf(bRec, EDiscrete);
if (nullPdf == 0)
return false;
Spectrum nullWeight = bsdf->eval(bRec, EDiscrete) / nullPdf;
weight[EImportance] *= nullWeight;
weight[ERadiance] *= nullWeight;
pdf[EImportance] *= nullPdf;
pdf[ERadiance] *= nullPdf;
if (its.isMediumTransition()) {
const Medium *expected = its.getTargetMedium(-ray.d);
if (medium != expected) {
//.........这里部分代码省略.........
示例4: pathConnect
bool PathEdge::pathConnect(const Scene *scene, const PathEdge *predEdge,
const PathVertex *vs, Path &result, const PathVertex *vt,
const PathEdge *succEdge, int maxInteractions, MemoryPool &pool) {
BDAssert(result.edgeCount() == 0 && result.vertexCount() == 0);
if (vs->isEmitterSupernode() || vt->isSensorSupernode()) {
Float radianceTransport = vt->isSensorSupernode() ? 1.0f : 0.0f,
importanceTransport = 1-radianceTransport;
PathEdge *edge = pool.allocEdge();
edge->medium = NULL;
edge->length = 0.0f;
edge->d = Vector(0.0f);
edge->pdf[ERadiance] = radianceTransport;
edge->pdf[EImportance] = importanceTransport;
edge->weight[ERadiance] = Spectrum(radianceTransport);
edge->weight[EImportance] = Spectrum(importanceTransport);
result.append(edge);
} else {
Point vsp = vs->getPosition(), vtp = vt->getPosition();
Vector d(vsp-vtp);
Float remaining = d.length();
d /= remaining;
if (remaining == 0) {
#if defined(MTS_BD_DEBUG)
SLog(EWarn, "Tried to connect %s and %s, which are located at exactly the same position!",
vs->toString().c_str(), vt->toString().c_str());
#endif
return false;
}
Float lengthFactor = vs->isOnSurface() ? (1-ShadowEpsilon) : 1;
Ray ray(vtp, d, vt->isOnSurface() ? Epsilon : 0,
remaining * lengthFactor, vs->getTime());
const Medium *medium = vt->getTargetMedium(succEdge, d);
int interactions = 0;
Intersection its;
while (true) {
bool surface = scene->rayIntersectAll(ray, its);
if (surface && (interactions == maxInteractions ||
!(its.getBSDF()->getType() & BSDF::ENull))) {
/* Encountered an occluder -- zero transmittance. */
result.release(pool);
return false;
}
/* Construct an edge */
PathEdge *edge = pool.allocEdge();
result.append(edge);
edge->length = std::min(its.t, remaining);
edge->medium = medium;
edge->d = d;
if (medium) {
MediumSamplingRecord mRec;
medium->eval(Ray(ray, 0, edge->length), mRec);
edge->pdf[ERadiance] = (surface || !vs->isMediumInteraction())
? mRec.pdfFailure : mRec.pdfSuccess;
edge->pdf[EImportance] = (interactions > 0 || !vt->isMediumInteraction())
? mRec.pdfFailure : mRec.pdfSuccessRev;
if (edge->pdf[ERadiance] == 0 || edge->pdf[EImportance] == 0
|| mRec.transmittance.isZero()) {
/* Zero transmittance */
result.release(pool);
return false;
}
edge->weight[EImportance] = mRec.transmittance / edge->pdf[EImportance];
edge->weight[ERadiance] = mRec.transmittance / edge->pdf[ERadiance];
} else {
edge->weight[ERadiance] = edge->weight[EImportance] = Spectrum(1.0f);
edge->pdf[ERadiance] = edge->pdf[EImportance] = 1.0f;
}
if (!surface || remaining - its.t < 0)
break;
/* Advance the ray */
ray.o = ray(its.t);
remaining -= its.t;
ray.mint = Epsilon;
ray.maxt = remaining * lengthFactor;
const BSDF *bsdf = its.getBSDF();
/* Account for the ENull interaction */
Vector wo = its.toLocal(ray.d);
BSDFSamplingRecord bRec(its, -wo, wo, ERadiance);
bRec.component = BSDF::ENull;
Float nullPdf = bsdf->pdf(bRec, EDiscrete);
if (nullPdf == 0) {
result.release(pool);
return false;
}
PathVertex *vertex = pool.allocVertex();
vertex->type = PathVertex::ESurfaceInteraction;
vertex->degenerate = !(bsdf->hasComponent(BSDF::ESmooth)
//.........这里部分代码省略.........