本文整理汇总了C++中Intersection::toLocal方法的典型用法代码示例。如果您正苦于以下问题:C++ Intersection::toLocal方法的具体用法?C++ Intersection::toLocal怎么用?C++ Intersection::toLocal使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Intersection
的用法示例。
在下文中一共展示了Intersection::toLocal方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: handleSurfaceInteraction
void CaptureParticleWorker::handleSurfaceInteraction(int depth, int nullInteractions,
bool caustic, const Intersection &its, const Medium *medium,
const Spectrum &weight) {
if (its.isSensor()) {
if (!m_bruteForce && !caustic)
return;
const Sensor *sensor = its.shape->getSensor();
if (sensor != m_sensor)
return;
Vector wi = its.toWorld(its.wi);
Point2 uv;
Spectrum value = sensor->eval(its, wi, uv) * weight;
if (value.isZero())
return;
m_workResult->put(uv, (Float *) &value[0]);
return;
}
if (m_bruteForce || (depth >= m_maxPathDepth && m_maxPathDepth > 0))
return;
int maxInteractions = m_maxPathDepth - depth - 1;
DirectSamplingRecord dRec(its);
Spectrum value = weight * m_scene->sampleAttenuatedSensorDirect(
dRec, its, medium, maxInteractions,
m_sampler->next2D(), m_sampler);
if (value.isZero())
return;
const BSDF *bsdf = its.getBSDF();
Vector wo = dRec.d;
BSDFSamplingRecord bRec(its, its.toLocal(wo), EImportance);
/* Prevent light leaks due to the use of shading normals -- [Veach, p. 158] */
Vector wi = its.toWorld(its.wi);
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));
value *= bsdf->eval(bRec) * correction;
/* Splat onto the accumulation buffer */
m_workResult->put(dRec.uv, (Float *) &value[0]);
}
示例2: Li
Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const {
/* Find the surface that is visible in the requested direction */
Intersection its;
//check if the ray intersects the scene
if (!scene->rayIntersect(ray, its)) {
//check if a distant disk light is set
const Emitter* distantsDisk = scene->getDistantEmitter();
if(distantsDisk == nullptr ) return Color3f(0.0f);
//sample the distant disk light
return distantsDisk->sampleL(ray.d);
}
//get the radiance of hitten object
Color3f Le(0.0f, 0.0f, 0.0f);
if (its.mesh->isEmitter() ) {
const Emitter* areaLightEM = its.mesh->getEmitter();
const areaLight* aEM = static_cast<const areaLight *> (areaLightEM);
Le = aEM->sampleL(-ray.d, its.shFrame.n, its);
}
//get the asigned BSDF
const BSDF* curBSDF = its.mesh->getBSDF();
Color3f Ld(0.0f, 0.0f, 0.0f);
Color3f f(0.0f, 0.0f, 0.0f);
Color3f totalLight(0.0f, 0.0f, 0.0f);
//transform to the local frame
//create a BRDF Query
BSDFQueryRecord query = BSDFQueryRecord(its.toLocal(-ray.d), Vector3f(0.0f), EMeasure::ESolidAngle);
//sample the BRDF
Color3f mats = curBSDF->sample(query, sampler->next2D());
if(mats.maxCoeff() > 0.0f) {
//Check for the light source
Vector3f wo = its.toWorld(query.wo);
Ray3f shadowRay(its.p, wo);
Intersection itsShadow;
if (scene->rayIntersect(shadowRay, itsShadow)) {
//intersection check if mesh is emitter
if(itsShadow.mesh->isEmitter()){
Ld = itsShadow.mesh->getEmitter()->radiance();
}
} else {
//check for distant disk light
const Emitter* distantsDisk = scene->getDistantEmitter();
if(distantsDisk != nullptr ) Ld = distantsDisk->sampleL(wo);
}
totalLight += Ld * mats;
}
return Le + totalLight;
}
示例3: 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);
}
}
示例4: fillIntersectionRecord
void fillIntersectionRecord(const Ray &ray,
const void *temp, Intersection &its) const {
const Float *data = static_cast<const Float *>(temp);
its.shFrame = its.geoFrame = m_frame;
its.shape = this;
its.dpdu = m_dpdu;
its.dpdv = m_dpdv;
its.uv = Point2(0.5f * (data[0]+1), 0.5f * (data[1]+1));
its.p = ray(its.t);
its.wi = its.toLocal(-ray.d);
its.hasUVPartials = false;
its.instance = NULL;
its.time = ray.time;
}
示例5: sample
virtual Vec sample(
Intersection const &isect,
float u1,
float u2,
Vec& WiW,
float& pdfResult,
int &bxdfType) const
{
pdfResult = 1.f; // should be a dirac?
Vec Wi = perfectSpecularReflection(isect.toLocal(isect.WoW));
WiW = isect.toWorld(Wi);
bxdfType = BxDF_SPECULAR;
return isect.texSample * fresnelCoef(Wi, m_R0);
}
示例6: Li
Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const {
/* Find the surface that is visible in the requested direction */
Intersection its;
//check if the ray intersects the scene
if (!scene->rayIntersect(ray, its)) {
//check if a distant disk light is set
const Emitter* distantsDisk = scene->getDistantEmitter();
if(distantsDisk == nullptr ) return Color3f(0.0f);
//sample the distant disk light
Vector3f d = ray.d;
return distantsDisk->sampleL(d);
}
//get the Number of lights from the scene
const std::vector<Emitter *> lights = scene->getEmitters();
uint32_t nLights = lights.size();
Color3f tp(1.0f, 1.0f, 1.0f);
Color3f L(0.0f, 0.0f, 0.0f);
Ray3f pathRay(ray.o, ray.d);
bool deltaFlag = true;
while(true) {
if (its.mesh->isEmitter() && deltaFlag) {
const Emitter* areaLightEM = its.mesh->getEmitter();
const areaLight* aEM = static_cast<const areaLight *> (areaLightEM);
L += tp * aEM->sampleL(-pathRay.d, its.shFrame.n, its);
}
//Light sampling
//randomly select a lightsource
uint32_t var = uint32_t(std::min(sampler->next1D()*nLights, float(nLights) - 1.0f));
//init the light color
Color3f Li(0.0f, 0.0f, 0.0f);
Color3f Ld(1.0f, 1.0f, 1.0f);
//create a sample for the light
const BSDF* curBSDF = its.mesh->getBSDF();
const Point2f lightSample = sampler->next2D();
VisibilityTester vis;
Vector3f wo;
float lightpdf;
float bsdfpdf;
Normal3f n = its.shFrame.n;
deltaFlag = curBSDF->isDeltaBSDF();
//sample the light
{
Li = lights[var]->sampleL(its.p, Epsilon, lightSample , &wo, &lightpdf, &vis);
lightpdf /= float(nLights);
//check if the pdf of the sample is greater than 0 and if the color is not black
if(lightpdf > 0 && Li.maxCoeff() != 0.0f) {
//calculate the cosine term wi in my case the vector to the light
float cosTerm = std::abs(n.dot(wo));
const BSDFQueryRecord queryEM = BSDFQueryRecord(its.toLocal(- pathRay.d), its.toLocal(wo), EMeasure::ESolidAngle, sampler);
Color3f f = curBSDF->eval(queryEM);
if(f.maxCoeff() > 0.0f && f.minCoeff() >= 0.0f && vis.Unoccluded(scene)) {
bsdfpdf = curBSDF->pdf(queryEM);
float weight = BalanceHeuristic(float(1), lightpdf, float(1), bsdfpdf);
if(curBSDF->isDeltaBSDF()) weight = 1.0f;
if(bsdfpdf > 0.0f) {
Ld = (weight * f * Li * cosTerm) / lightpdf;
L += tp * Ld;
} else {
//cout << "bsdfpdf = " << bsdfpdf << endl;
//cout << "f = " << f << endl;
}
}
}
}
//Material part
BSDFQueryRecord queryMats = BSDFQueryRecord(its.toLocal(-pathRay.d), Vector3f(0.0f), EMeasure::ESolidAngle, sampler);
Color3f fi = curBSDF->sample(queryMats, sampler->next2D());
bsdfpdf = curBSDF->pdf(queryMats);
lightpdf = 0.0f;
if(fi.maxCoeff() > 0.0f && fi.minCoeff() >= 0.0f) {
if(bsdfpdf > 0.0f) {
Ray3f shadowRay(its.p, its.toWorld(queryMats.wo));
Intersection lightIsect;
if (scene->rayIntersect(shadowRay, lightIsect)) {
if(lightIsect.mesh->isEmitter()){
const Emitter* areaLightEMcur = lightIsect.mesh->getEmitter();
const areaLight* aEMcur = static_cast<const areaLight *> (areaLightEMcur);
Li = aEMcur->sampleL(-shadowRay.d, lightIsect.shFrame.n, lightIsect);
lightpdf = aEMcur->pdf(its.p, (lightIsect.p - its.p).normalized(), lightIsect.p, Normal3f(lightIsect.shFrame.n));
}
} else {
const Emitter* distantsDisk = scene->getDistantEmitter();
//.........这里部分代码省略.........
示例7: Li
Spectrum MisPathTracer::Li(const Scene* scene, Sampler& sampler, Ray3f& ray) const
{
Spectrum L(0.f);
Intersection its;
Spectrum throughput(1.f);
bool isSpecular = true;
while (true)
{
if (!scene->rayIntersect(ray, its))
break;
if (isSpecular && its.shape->getEmitter())
{
EmitterSample emittanceSample(ray.o, its.p, its.shFrame.n);
L += throughput * its.shape->getEmitter()->eval(emittanceSample);
}
if (its.shape->getBSDF()->getType() != BSDFType::Delta)
{
EmitterSample emSam(its.p);
auto lightSpec = scene->sampleEmitter(its, sampler, emSam);
float cosFactor = its.shFrame.n.dot(emSam.wi);
if (!(cosFactor <= 0.f || lightSpec.isZero() || scene->rayIntersect(emSam.shadowRay)))
{
BSDFSample bsdfSam(its.p, its.toLocal(-ray.d), its.toLocal(emSam.wi));
bsdfSam.measure = Measure::SolidAngle;
auto bsdfSpec = its.shape->getBSDF()->eval(bsdfSam);
float pdfEm = emSam.pdf;
float pdfBsdf = its.shape->getBSDF()->pdf(bsdfSam);
L += throughput * bsdfSpec * lightSpec * cosFactor * miWeight(pdfEm, pdfBsdf);
}
}
BSDFSample bsdfSample(its.p, its.toLocal(-ray.d));
auto bsdf = its.shape->getBSDF()->sample(bsdfSample, sampler);
Intersection bsdfIts;
Ray3f bsdfRay(its.p, its.toWorld(bsdfSample.wo));
if (scene->rayIntersect(bsdfRay, bsdfIts) && bsdfIts.shape->getEmitter())
{
const auto* em = bsdfIts.shape->getEmitter();
EmitterSample emSam(its.p, bsdfIts.p, bsdfIts.shFrame.n);
emSam.wi = bsdfRay.d;
auto lightSpec = em->eval(emSam);
float pdfBsdf = its.shape->getBSDF()->pdf(bsdfSample);
float pdfEm = em->pdf(emSam) * scene->getEmitterPdf();
if (pdfBsdf + pdfEm > 0.f)
L += throughput * bsdf * lightSpec * miWeight(pdfBsdf, pdfEm);
}
isSpecular = its.shape->getBSDF()->getType() == BSDFType::Delta;
throughput *= bsdf;
ray = bsdfRay;
float q = 1.f - std::min(throughput.maxCoeff(), 0.99f);
if (sampler.next1D() > q)
throughput /= (1.f - q);
else
break;
}
return L;
}
示例8: processIncoherent
void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *workResult,
const bool &stop) {
const RectangularWorkUnit *rect = static_cast<const RectangularWorkUnit *>(workUnit);
ImageBlock *block = static_cast<ImageBlock *>(workResult);
block->setOffset(rect->getOffset());
block->setSize(rect->getSize());
const int sx = rect->getOffset().x, sy = block->getOffset().y;
const int ex = sx + rect->getSize().x, ey = sy + rect->getSize().y;
/* Some local variables */
int pos = 0;
Intersection its;
Spectrum value, bsdfVal;
Vector toVPL;
Ray primary, secondary;
int numRays = 0;
float shutterOpen = m_scene->getCamera()->getShutterOpen();
for (int y=sy; y<ey; ++y) {
for (int x=sx; x<ex; ++x) {
/* Generate a camera ray without normalization */
primary = Ray(m_cameraO, m_cameraTL
+ m_cameraDx * (Float) x
+ m_cameraDy * (Float) y, shutterOpen);
++numRays;
if (!m_kdtree->rayIntersect(primary, its)) {
block->setPixel(pos++, m_scene->LeBackground(primary)*m_backgroundScale);
continue;
}
if (its.shape->isLuminaire())
value = its.Le(-primary.d);
else
value = Spectrum(0.0f);
toVPL = m_vpl.its.p - its.p;
secondary = Ray(its.p, toVPL, ShadowEpsilon, 1-ShadowEpsilon, shutterOpen);
++numRays;
if (m_kdtree->rayIntersect(secondary)) {
block->setPixel(pos++, value);
continue;
}
Float length = toVPL.length();
toVPL/=length;
BSDFQueryRecord rr(its, its.toLocal(toVPL));
rr.wi = normalize(rr.wi);
bsdfVal = its.shape->getBSDF()->eval(rr);
length = std::max(length, m_minDist);
if (m_vpl.type == ESurfaceVPL) {
BSDFQueryRecord bRec(m_vpl.its, -m_vpl.its.toLocal(toVPL));
bRec.quantity = EImportance;
value += m_vpl.P * bsdfVal * m_vpl.its.shape->getBSDF()->eval(bRec) / (length*length);
} else {
EmissionRecord eRec(m_vpl.luminaire,
ShapeSamplingRecord(m_vpl.its.p, m_vpl.its.shFrame.n), -toVPL);
eRec.type = EmissionRecord::EPreview;
value += m_vpl.P * bsdfVal * m_vpl.luminaire->evalDirection(eRec)
* ((m_vpl.luminaire->getType() & Luminaire::EOnSurface ?
dot(m_vpl.its.shFrame.n, -toVPL) : (Float) 1)
/ (length*length));
}
block->setPixel(pos++, value);
}
}
block->setExtra(numRays);
}
示例9: processCoherent
//.........这里部分代码省略.........
Vector(primRay4.d[0].f[idx], primRay4.d[1].f[idx], primRay4.d[2].f[idx]),
0.0f
);
its.t = its4.t.f[idx];
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its);
bsdf = its.shape->getBSDF();
}
wo.x = nSecD[0].f[idx]; wo.y = nSecD[1].f[idx]; wo.z = nSecD[2].f[idx];
if (EXPECT_TAKEN(!shape->isLuminaire())) {
memset(&emitted[idx], 0, sizeof(Spectrum));
} else {
Vector d(-primRay4.d[0].f[idx], -primRay4.d[1].f[idx], -primRay4.d[2].f[idx]);
emitted[idx] = shape->getLuminaire()->Le(ShapeSamplingRecord(its.p, its.shFrame.n), d);
}
if (EXPECT_TAKEN(bsdf->getType() == BSDF::EDiffuseReflection && diffuseVPL)) {
/* Fast path */
direct[idx] = (bsdf->getDiffuseReflectance(its) * vplWeight)
* (std::max((Float) 0.0f, dot(wo, its.shFrame.n))
* (vplOnSurface ? (std::max(cosThetaLight.f[idx], (Float) 0.0f) * INV_PI) : INV_PI)
* invLengthSquared.f[idx]);
} else {
wi.x = -primRay4.d[0].f[idx];
wi.y = -primRay4.d[1].f[idx];
wi.z = -primRay4.d[2].f[idx];
its.p.x = secRay4.o[0].f[idx];
its.p.y = secRay4.o[1].f[idx];
its.p.z = secRay4.o[2].f[idx];
if (EXPECT_NOT_TAKEN(bsdf->getType() & BSDF::EAnisotropic)) {
its.shFrame.s = normalize(its.dpdu - its.shFrame.n
* dot(its.shFrame.n, its.dpdu));
its.shFrame.t = cross(its.shFrame.n, its.shFrame.s);
} else {
coordinateSystem(its.shFrame.n, its.shFrame.s, its.shFrame.t);
}
const Float ctLight = cosThetaLight.f[idx];
wi = normalize(wi);
its.wi = its.toLocal(wi);
wo = its.toLocal(wo);
if (!diffuseVPL) {
if (m_vpl.type == ESurfaceVPL) {
BSDFQueryRecord bRec(m_vpl.its, m_vpl.its.toLocal(wi));
bRec.quantity = EImportance;
vplWeight = m_vpl.its.shape->getBSDF()->eval(bRec) * m_vpl.P;
} else {
EmissionRecord eRec(m_vpl.luminaire,
ShapeSamplingRecord(m_vpl.its.p, m_vpl.its.shFrame.n), wi);
eRec.type = EmissionRecord::EPreview;
vplWeight = m_vpl.luminaire->evalDirection(eRec) * m_vpl.P;
}
}
if (EXPECT_TAKEN(ctLight >= 0)) {
direct[idx] = (bsdf->eval(BSDFQueryRecord(its, wo)) * vplWeight
* ((vplOnSurface ? std::max(ctLight, (Float) 0.0f) : 1.0f) * invLengthSquared.f[idx]));
} else {
memset(&direct[idx], 0, sizeof(Spectrum));
}
}
++numRays;
}
/* Shoot the secondary rays */
const int secSignsX = _mm_movemask_ps(secRay4.d[0].ps);
const int secSignsY = _mm_movemask_ps(secRay4.d[1].ps);
const int secSignsZ = _mm_movemask_ps(secRay4.d[2].ps);
const bool secCoherent =
(secSignsX == 0 || secSignsX == 0xF)
&& (secSignsY == 0 || secSignsY == 0xF)
&& (secSignsZ == 0 || secSignsZ == 0xF);
/* Shoot the secondary rays */
secIts4.t = SSEConstants::p_inf;
if (EXPECT_TAKEN(secCoherent)) {
secRay4.signs[0][0] = secSignsX ? 1 : 0;
secRay4.signs[1][0] = secSignsY ? 1 : 0;
secRay4.signs[2][0] = secSignsZ ? 1 : 0;
m_kdtree->rayIntersectPacket(secRay4, secItv4, secIts4, temp);
} else {
m_kdtree->rayIntersectPacketIncoherent(secRay4, secItv4, secIts4, temp);
}
for (int idx=0; idx<4; ++idx) {
if (EXPECT_TAKEN(secIts4.t.f[idx] == std::numeric_limits<float>::infinity()))
block->setPixel(pos+pixelOffset[idx], direct[idx]+emitted[idx]);
else
block->setPixel(pos+pixelOffset[idx], emitted[idx]);
}
}
}
block->setExtra(numRays);
#else
Log(EError, "Coherent raytracing support was not compiled into this binary!");
#endif
}
示例10: preprocess
void preprocess(const Scene *scene) {
/* Create a sample generator for the preprocess step */
Sampler *sampler = static_cast<Sampler *>(
NoriObjectFactory::createInstance("independent", PropertyList()));
Emitter* distantsDisk = scene->getDistantEmitter();
if(distantsDisk != nullptr ) {
float lngstDir = scene->getBoundingBox().getLongestDirection();
distantsDisk->setMaxRadius(lngstDir);
}
/* Allocate memory for the photon map */
m_photonMap = std::unique_ptr<PhotonMap>(new PhotonMap());
m_photonMap->reserve(m_photonCount);
/* Estimate a default photon radius */
if (m_photonRadius == 0)
m_photonRadius = scene->getBoundingBox().getExtents().norm() / 500.0f;
int storedPhotons = 0;
const std::vector<Emitter *> lights = scene->getEmitters();
int nLights = lights.size();
Color3f tp(1.0f, 1.0f, 1.0f);
cout << "Starting to create "<< m_photonCount << " photons!" << endl;
int percentDone= 0;
int onePercent = int(floor(m_photonCount / 100.0));
// create the expected number of photons
while(storedPhotons < m_photonCount) {
//uniformly sample 1 light (assuming that we only have area lights)
int var = int(std::min(sampler->next1D()*nLights, float(nLights) - 1.0f));
const areaLight* curLight = static_cast<const areaLight *> (lights[var]);
//sample a photon
Photon curPhoton;
Vector3f unQuantDir(0.0f,0.0f,0.0f);
curLight->samplePhoton(sampler, curPhoton, 1, nLights, unQuantDir);
Color3f alpha = curPhoton.getPower();
Color3f tp(1.0f, 1.0f, 1.0f);
//trace the photon
Intersection its;
Ray3f photonRay(curPhoton.getPosition(), unQuantDir);
m_shootedRays++;
if (scene->rayIntersect(photonRay, its)) {
while(true) {
const BSDF* curBSDF = its.mesh->getBSDF();
if (curBSDF->isDiffuse()) {
//store the photon
m_photonMap->push_back(Photon(
its.p /* Position */,
-photonRay.d /* Direction*/,
tp * alpha /* Power */
));
storedPhotons++;
}
if(!(storedPhotons < m_photonCount)) break;
BSDFQueryRecord query = BSDFQueryRecord(its.toLocal(-photonRay.d), Vector3f(0.0f), EMeasure::ESolidAngle);
Color3f fi = curBSDF->sample(query, sampler->next2D());
if(fi.maxCoeff() == 0.0f) break;
tp *= fi;
Vector3f wo = its.toWorld(query.wo);
photonRay = Ray3f(its.p, wo);
//ray escapes the scene
if (!scene->rayIntersect(photonRay, its)) break;
//stop critirium russian roulette
float q = tp.maxCoeff();
if(q < sampler->next1D()) break;
tp /= q;
}
}
if(onePercent != 0) {
if(storedPhotons % onePercent == 0){
int percent = int(floor(storedPhotons / onePercent));
if(percent % 10 == 0 && percentDone != percent){
percentDone = percent;
cout << percent << "%" << endl;
}
}
}
}
/* Build the photon map */
m_photonMap->build();
}
示例11: Li
Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const {
/* Find the surface that is visible in the requested direction */
Intersection its;
//check if the ray intersects the scene
if (!scene->rayIntersect(ray, its)) {
return Color3f(0.0f);
}
Color3f tp(1.0f, 1.0f, 1.0f);
Color3f L(0.0f, 0.0f, 0.0f);
Ray3f pathRay(ray.o, ray.d);
while(true) {
//get the radiance of hitten object
if (its.mesh->isEmitter() ) {
const Emitter* areaLightEM = its.mesh->getEmitter();
const areaLight* aEM = static_cast<const areaLight *> (areaLightEM);
L += tp * aEM->sampleL(-pathRay.d, its.shFrame.n, its);
}
//get the asigned BSDF
const BSDF* curBSDF = its.mesh->getBSDF();
//transform to the local frame
BSDFQueryRecord query = BSDFQueryRecord(its.toLocal(-pathRay.d), Vector3f(0.0f), EMeasure::ESolidAngle);
//Normal3f n = its.shFrame.n;
if(curBSDF->isDiffuse()) {
std::vector<uint32_t> results;
m_photonMap->search(its.p, m_photonRadius, results);
Color3f Li(0.0f, 0.0f, 0.0f);
int k = results.size();
//cout << k << endl;
if(k > 0) {
//cout << results.size() << " Photons found!" << endl;
//get the power from all photons
//for (uint32_t i : results)
//const Photon &photonk = (*m_photonMap)[k-1];
Color3f Lindir(0.0f, 0.0f, 0.0f);
for (int i = 0; i < k; ++i)
{
const Photon &photon = (*m_photonMap)[results[i]];
Vector3f wi = its.toLocal(photon.getDirection());
Vector3f wo = its.toLocal(its.shFrame.n);
BSDFQueryRecord dummy = BSDFQueryRecord(wi, wo, EMeasure::ESolidAngle);
Color3f f = curBSDF->eval(dummy);
Lindir += (tp * f) * photon.getPower() / (M_PI * m_photonRadius * m_photonRadius);
}
Li += Lindir;
//cout << "Li = " << Li.toString() << endl;
if(Li.maxCoeff() > 0.0f)
L += Li / m_shootedRays;
}
break;
}
//sample the BRDF
Color3f fi = curBSDF->sample(query, sampler->next2D());
//check for black brdf
if(fi.maxCoeff() > 0.0f) {
tp *= fi;
} else {
//stop
// hit a black brdf
break;
}
Vector3f wo = its.toWorld(query.wo);
pathRay = Ray3f(its.p, wo);
//ray escapes the scene
if (!scene->rayIntersect(pathRay, its)) break;
//stop critirium russian roulette
float maxCoeff = tp.maxCoeff();
float q = std::min(0.99f, maxCoeff);
if(q < sampler->next1D()) break;
tp /= q;
}
return L;
}
示例12: 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) {
//.........这里部分代码省略.........
示例13: 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)
//.........这里部分代码省略.........
示例14: Li
Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const {
/* Find the surface that is visible in the requested direction */
Intersection its;
if (!scene->rayIntersect(ray, its))
return Color3f(0.0f);
//get the Normal at the intersection point
Vector3f n = Vector3f(its.shFrame.n);
//get the Number of lights from the scene
const std::vector<Emitter *> lights = scene->getEmitters();
uint32_t nLights = lights.size();
//check for lights
if(nLights > 0) {
//get the asigned BSDF
const BSDF* curBSDF = its.mesh->getBSDF();
if(curBSDF) {
Color3f totalLight(0.0f);
//uterated over all lights
//std::cout << "start light comp" << std::endl;
for (uint32_t var = 0; var < nLights; ++var) {
VisibilityTester vis;
Vector3f wi;
float pdf;
const Point2f ls;
//sample the light
Color3f Ld =lights[var]->sampleL(its.p, Epsilon, ls, &wi, &pdf, &vis);
//check if the light is visible
if(vis.Unoccluded(scene)) {
//create a query for the brdf
Vector3f wo = - ray.d;
//calculate the abs value of n dot wi
float costerm = n.dot(wi);
//transform to the local frame
wo = its.toLocal(wo);
wi = its.toLocal(wi);
const BSDFQueryRecord query = BSDFQueryRecord(wi, wo, EMeasure::ESolidAngle);
//calculate the BSDF
Color3f f = curBSDF->eval(query);
//add the light up
totalLight += (Ld * f * std::abs(costerm));
}
}
return totalLight;
}
}
return Color3f(0.0f);
}
示例15: Li
Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &r) const {
/* Find the surface that is visible in the requested direction */
Intersection its;
Ray3f ray(r);
if (!scene->rayIntersect(ray, its))
return Color3f(0.0f);
Color3f radiance(0.0f);
bool specularBounce = false;
Color3f pathThroughput(1.0f);
for ( int bounces = 0; ; ++bounces ) {
const Luminaire* luminaire = its.mesh->getLuminaire();
if ((bounces == 0 || specularBounce) && luminaire != NULL) {
Vector3f wo = (-ray.d).normalized();
Color3f emission = luminaire->le(its.p, its.shFrame.n, wo);
radiance += pathThroughput*emission;
}
const Texture* texture = its.mesh->getTexture();
Color3f texel(1.0f);
if ( texture ) {
texel = texture->lookUp(its.uv.x(), its.uv.y());
}
const BSDF* bsdf = its.mesh->getBSDF();
// sample illumination from lights, add to path contribution
if (!bsdf->isSpecular()){
radiance += pathThroughput*UniformSampleAllLights(scene, ray, its, sampler, m_samplePolicy)*texel;
}
// sample bsdf to get new path direction
BSDFQueryRecord bRec(its.toLocal((-ray.d)).normalized());
Color3f f = bsdf->sample(bRec, sampler->next2D() );
if (f.isZero() ) { // farther path no contribution
break;
}
specularBounce = bsdf->isSpecular();
Vector3f d = its.toWorld(bRec.wo);
f *= texel;
pathThroughput *= f;
ray = Ray3f(its.p, d );
// possibly termination
if (bounces > kSampleDepth) {
#if 0
float continueProbability = std::min( 0.5f, pathThroughput.y() );
if ( sampler->next1D() > continueProbability ) {
break;
}
#else
float continueProbability = std::max(f.x(),
std::max(f.y(), f.z()));
if ( sampler->next1D() > continueProbability ) {
break;
}
#endif
pathThroughput /= continueProbability;
}
if (bounces == m_maxDepth) {
break;
}
// find next vertex of path
if ( !scene->rayIntersect(ray, its) ) {
break;
}
}
return radiance;
}