本文整理汇总了C++中PathSampleGenerator::advancePath方法的典型用法代码示例。如果您正苦于以下问题:C++ PathSampleGenerator::advancePath方法的具体用法?C++ PathSampleGenerator::advancePath怎么用?C++ PathSampleGenerator::advancePath使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PathSampleGenerator
的用法示例。
在下文中一共展示了PathSampleGenerator::advancePath方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: tracePhoton
void PhotonTracer::tracePhoton(SurfacePhotonRange &surfaceRange, VolumePhotonRange &volumeRange,
PathSampleGenerator &sampler)
{
float lightPdf;
const Primitive *light = chooseLightAdjoint(sampler, lightPdf);
PositionSample point;
if (!light->samplePosition(sampler, point))
return;
DirectionSample direction;
if (!light->sampleDirection(sampler, point, direction))
return;
sampler.advancePath();
Ray ray(point.p, direction.d);
Vec3f throughput(point.weight*direction.weight/lightPdf);
SurfaceScatterEvent event;
IntersectionTemporary data;
IntersectionInfo info;
Medium::MediumState state;
state.reset();
Vec3f emission(0.0f);
const Medium *medium = nullptr; // TODO: Media
int bounce = 0;
bool wasSpecular = true;
bool hitSurface = true;
bool didHit = _scene->intersect(ray, data, info);
while ((didHit || medium) && bounce < _settings.maxBounces - 1) {
if (medium) {
MediumSample mediumSample;
if (!medium->sampleDistance(sampler, ray, state, mediumSample))
break;
throughput *= mediumSample.weight;
hitSurface = mediumSample.exited;
if (!hitSurface) {
if (!volumeRange.full()) {
VolumePhoton &p = volumeRange.addPhoton();
p.pos = mediumSample.p;
p.dir = ray.dir();
p.power = throughput;
}
PhaseSample phaseSample;
if (!mediumSample.phase->sample(sampler, ray.dir(), phaseSample))
break;
ray = ray.scatter(mediumSample.p, phaseSample.w, 0.0f);
ray.setPrimaryRay(false);
throughput *= phaseSample.weight;
}
}
if (hitSurface) {
if (!info.bsdf->lobes().isPureSpecular() && !surfaceRange.full()) {
Photon &p = surfaceRange.addPhoton();
p.pos = info.p;
p.dir = ray.dir();
p.power = throughput*std::abs(info.Ns.dot(ray.dir())/info.Ng.dot(ray.dir()));
}
}
if (volumeRange.full() && surfaceRange.full())
break;
if (hitSurface) {
event = makeLocalScatterEvent(data, info, ray, &sampler);
if (!handleSurface(event, data, info, medium, bounce,
true, false, ray, throughput, emission, wasSpecular, state))
break;
}
if (throughput.max() == 0.0f)
break;
if (std::isnan(ray.dir().sum() + ray.pos().sum()))
break;
if (std::isnan(throughput.sum()))
break;
sampler.advancePath();
bounce++;
if (bounce < _settings.maxBounces)
didHit = _scene->intersect(ray, data, info);
}
}
示例2: traceSample
void LightTracer::traceSample(PathSampleGenerator &sampler)
{
float lightPdf;
const Primitive *light = chooseLightAdjoint(sampler, lightPdf);
const Medium *medium = light->extMedium().get();
PositionSample point;
if (!light->samplePosition(sampler, point))
return;
DirectionSample direction;
if (!light->sampleDirection(sampler, point, direction))
return;
sampler.advancePath();
Vec3f throughput(point.weight/lightPdf);
LensSample splat;
if (_settings.minBounces == 0 && !light->isInfinite() && _scene->cam().sampleDirect(point.p, sampler, splat)) {
Ray shadowRay(point.p, splat.d);
shadowRay.setFarT(splat.dist);
Vec3f transmission = generalizedShadowRay(shadowRay, medium, nullptr, 0);
if (transmission != 0.0f) {
Vec3f value = throughput*transmission*splat.weight
*light->evalDirectionalEmission(point, DirectionSample(splat.d));
_splatBuffer->splatFiltered(splat.pixel, value);
}
}
sampler.advancePath();
Ray ray(point.p, direction.d);
throughput *= direction.weight;
VolumeScatterEvent volumeEvent;
SurfaceScatterEvent surfaceEvent;
IntersectionTemporary data;
IntersectionInfo info;
Medium::MediumState state;
state.reset();
Vec3f emission(0.0f);
int bounce = 0;
bool wasSpecular = true;
bool didHit = _scene->intersect(ray, data, info);
while ((didHit || medium) && bounce < _settings.maxBounces - 1) {
bool hitSurface = true;
if (medium) {
volumeEvent = VolumeScatterEvent(&sampler, throughput, ray.pos(), ray.dir(), ray.farT());
if (!medium->sampleDistance(volumeEvent, state))
break;
throughput *= volumeEvent.weight;
volumeEvent.weight = Vec3f(1.0f);
hitSurface = volumeEvent.t == volumeEvent.maxT;
if (hitSurface && !didHit)
break;
}
if (hitSurface) {
surfaceEvent = makeLocalScatterEvent(data, info, ray, &sampler);
Vec3f weight;
Vec2f pixel;
if (surfaceLensSample(_scene->cam(), surfaceEvent, medium, bounce + 1, ray, weight, pixel))
_splatBuffer->splatFiltered(pixel, weight*throughput);
if (!handleSurface(surfaceEvent, data, info, medium, bounce,
true, false, ray, throughput, emission, wasSpecular, state))
break;
} else {
volumeEvent.p += volumeEvent.t*volumeEvent.wi;
Vec3f weight;
Vec2f pixel;
if (volumeLensSample(_scene->cam(), volumeEvent, medium, bounce + 1, ray, weight, pixel))
_splatBuffer->splatFiltered(pixel, weight*throughput);
if (!handleVolume(volumeEvent, medium, bounce,
true, false, ray, throughput, emission, wasSpecular, state))
break;
}
if (throughput.max() == 0.0f)
break;
if (std::isnan(ray.dir().sum() + ray.pos().sum()))
break;
if (std::isnan(throughput.sum()))
break;
sampler.advancePath();
bounce++;
if (bounce < _settings.maxBounces)
didHit = _scene->intersect(ray, data, info);
}
}
示例3: traceSample
Vec3f PhotonTracer::traceSample(Vec2u pixel, const KdTree<Photon> &surfaceTree,
const KdTree<VolumePhoton> *mediumTree, PathSampleGenerator &sampler,
float gatherRadius)
{
PositionSample point;
if (!_scene->cam().samplePosition(sampler, point))
return Vec3f(0.0f);
DirectionSample direction;
if (!_scene->cam().sampleDirection(sampler, point, pixel, direction))
return Vec3f(0.0f);
sampler.advancePath();
Vec3f throughput = point.weight*direction.weight;
Ray ray(point.p, direction.d);
ray.setPrimaryRay(true);
IntersectionTemporary data;
IntersectionInfo info;
const Medium *medium = _scene->cam().medium().get();
Vec3f result(0.0f);
int bounce = 0;
bool didHit = _scene->intersect(ray, data, info);
while ((medium || didHit) && bounce < _settings.maxBounces - 1) {
if (medium) {
if (mediumTree) {
Vec3f beamEstimate(0.0f);
mediumTree->beamQuery(ray.pos(), ray.dir(), ray.farT(), [&](const VolumePhoton &p, float t, float distSq) {
Ray mediumQuery(ray);
mediumQuery.setFarT(t);
beamEstimate += (3.0f*INV_PI*sqr(1.0f - distSq/p.radiusSq))/p.radiusSq
*medium->phaseFunction(p.pos)->eval(ray.dir(), -p.dir)
*medium->transmittance(mediumQuery)*p.power;
});
result += throughput*beamEstimate;
}
throughput *= medium->transmittance(ray);
}
if (!didHit)
break;
const Bsdf &bsdf = *info.bsdf;
SurfaceScatterEvent event = makeLocalScatterEvent(data, info, ray, &sampler);
Vec3f transparency = bsdf.eval(event.makeForwardEvent(), false);
float transparencyScalar = transparency.avg();
Vec3f wo;
if (sampler.nextBoolean(DiscreteTransparencySample, transparencyScalar)) {
wo = ray.dir();
throughput *= transparency/transparencyScalar;
} else {
event.requestedLobe = BsdfLobes::SpecularLobe;
if (!bsdf.sample(event, false))
break;
wo = event.frame.toGlobal(event.wo);
throughput *= event.weight;
}
bool geometricBackside = (wo.dot(info.Ng) < 0.0f);
medium = info.primitive->selectMedium(medium, geometricBackside);
ray = ray.scatter(ray.hitpoint(), wo, info.epsilon);
if (std::isnan(ray.dir().sum() + ray.pos().sum()))
break;
if (std::isnan(throughput.sum()))
break;
sampler.advancePath();
bounce++;
if (bounce < _settings.maxBounces)
didHit = _scene->intersect(ray, data, info);
}
if (!didHit) {
if (!medium && _scene->intersectInfinites(ray, data, info))
result += throughput*info.primitive->evalDirect(data, info);
return result;
}
if (info.primitive->isEmissive())
result += throughput*info.primitive->evalDirect(data, info);
int count = surfaceTree.nearestNeighbours(ray.hitpoint(), _photonQuery.get(), _distanceQuery.get(),
_settings.gatherCount, gatherRadius);
if (count == 0)
return result;
const Bsdf &bsdf = *info.bsdf;
SurfaceScatterEvent event = makeLocalScatterEvent(data, info, ray, &sampler);
Vec3f surfaceEstimate(0.0f);
for (int i = 0; i < count; ++i) {
event.wo = event.frame.toLocal(-_photonQuery[i]->dir);
// Asymmetry due to shading normals already compensated for when storing the photon,
// so we don't use the adjoint BSDF here
surfaceEstimate += _photonQuery[i]->power*bsdf.eval(event, false)/std::abs(event.wo.z());
//.........这里部分代码省略.........