本文整理汇总了C++中BSDF::NumComponents方法的典型用法代码示例。如果您正苦于以下问题:C++ BSDF::NumComponents方法的具体用法?C++ BSDF::NumComponents怎么用?C++ BSDF::NumComponents使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BSDF
的用法示例。
在下文中一共展示了BSDF::NumComponents方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GeneratePath
// Metropolis Method Definitions
static uint32_t GeneratePath(const RayDifferential &r,
const Spectrum &a, const Scene *scene, MemoryArena &arena,
const vector<PathSample> &samples, PathVertex *path,
RayDifferential *escapedRay, Spectrum *escapedAlpha) {
PBRT_MLT_STARTED_GENERATE_PATH();
RayDifferential ray = r;
Spectrum alpha = a;
if (escapedAlpha) *escapedAlpha = 0.f;
uint32_t length = 0;
for (; length < samples.size(); ++length) {
// Try to generate next vertex of ray path
PathVertex &v = path[length];
if (!scene->Intersect(ray, &v.isect)) {
// Handle ray that leaves the scene during path generation
if (escapedAlpha) *escapedAlpha = alpha;
if (escapedRay) *escapedRay = ray;
break;
}
// Record information for current path vertex
v.alpha = alpha;
BSDF *bsdf = v.isect.GetBSDF(ray, arena);
v.bsdf = bsdf;
v.wPrev = -ray.d;
// Sample direction for outgoing Metropolis path direction
float pdf;
BxDFType flags;
Spectrum f = bsdf->Sample_f(-ray.d, &v.wNext, samples[length].bsdfSample,
&pdf, BSDF_ALL, &flags);
v.specularBounce = (flags & BSDF_SPECULAR) != 0;
v.nSpecularComponents = bsdf->NumComponents(BxDFType(BSDF_SPECULAR |
BSDF_REFLECTION | BSDF_TRANSMISSION));
if (f.IsBlack() || pdf == 0.f)
{
PBRT_MLT_FINISHED_GENERATE_PATH();
return length+1;
}
// Terminate path with RR or prepare for finding next vertex
const Point &p = bsdf->dgShading.p;
const Normal &n = bsdf->dgShading.nn;
Spectrum pathScale = f * AbsDot(v.wNext, n) / pdf;
float rrSurviveProb = min(1.f, pathScale.y());
if (samples[length].rrSample > rrSurviveProb)
{
PBRT_MLT_FINISHED_GENERATE_PATH();
return length+1;
}
alpha *= pathScale / rrSurviveProb;
//alpha *= renderer->Transmittance(scene, ray, NULL, rng, arena);
ray = RayDifferential(p, v.wNext, ray, v.isect.rayEpsilon);
}
PBRT_MLT_FINISHED_GENERATE_PATH();
return length;
}
示例2: TraceEyePath
//.........这里部分代码省略.........
// Possibly add emitted light at path vertex
Vector wo(-ray.d);
if (specularBounce) {
BSDF *ibsdf;
SWCSpectrum Le(pathThroughput);
if (isect.Le(sample, ray, &ibsdf, NULL, NULL, &Le)) {
L[isect.arealight->group] += Le;
V[isect.arealight->group] += Le.Filter(sw) * VContrib;
}
}
const Point &p = bsdf->dgShading.p;
const Normal &n = bsdf->dgShading.nn;
// Estimate direct lighting
if (renderer->sppmi->directLightSampling && (nLights > 0)) {
for (u_int i = 0; i < lightGroupCount; ++i) {
Ld[i] = 0.f;
Vd[i] = 0.f;
}
renderer->sppmi->hints.SampleLights(scene, sample, p, n,
wo, bsdf, pathLength, pathThroughput, Ld, &Vd);
for (u_int i = 0; i < lightGroupCount; ++i) {
L[i] += Ld[i];
V[i] += Vd[i] * VContrib;
}
}
// Choose between storing or bouncing the hitpoint on the surface
bool const has_store_component = bsdf->NumComponents(store_component) > 0;
bool const has_bounce_component = bsdf->NumComponents(bounce_component) > 0;
float pdf_event;
bool store;
if (has_store_component && has_bounce_component)
{
// There is both bounce and store component, we choose with a
// random number
// TODO: do this by importance
store = data[4] < .5f;
pdf_event = 0.5;
}
else
{
// If there is only bounce/store component, we bounce/store
// accordingly
store = has_store_component;
pdf_event = 1.f;
}
if(store)
{
hp->SetSurface();
hpep->pathThroughput = pathThroughput * rayWeight / pdf_event * invPixelPdf;
hpep->wo = wo;
hpep->bsdf = bsdf;
hpep->single = sw.single;
sample.arena.Commit();
break;
}
示例3: Li
Spectrum ExPhotonIntegrator::Li(const Scene *scene,
const RayDifferential &ray, const Sample *sample,
float *alpha) const {
// Compute reflected radiance with photon map
Spectrum L(0.);
Intersection isect;
if (scene->Intersect(ray, &isect)) {
if (alpha) *alpha = 1.;
Vector wo = -ray.d;
// Compute emitted light if ray hit an area light source
L += isect.Le(wo);
// Evaluate BSDF at hit point
BSDF *bsdf = isect.GetBSDF(ray);
const Point &p = bsdf->dgShading.p;
const Normal &n = bsdf->dgShading.nn;
L += UniformSampleAllLights(scene, p, n,
wo, bsdf, sample,
lightSampleOffset, bsdfSampleOffset,
bsdfComponentOffset);
// Compute indirect lighting for photon map integrator
L += LPhoton(causticMap, nCausticPaths, nLookup, bsdf,
isect, wo, maxDistSquared);
if (finalGather) {
#if 1
// Do one-bounce final gather for photon map
BxDFType nonSpecular = BxDFType(BSDF_REFLECTION |
BSDF_TRANSMISSION | BSDF_DIFFUSE | BSDF_GLOSSY);
if (bsdf->NumComponents(nonSpecular) > 0) {
// Find indirect photons around point for importance sampling
u_int nIndirSamplePhotons = 50;
PhotonProcess proc(nIndirSamplePhotons, p);
proc.photons = (ClosePhoton *)alloca(nIndirSamplePhotons *
sizeof(ClosePhoton));
float searchDist2 = maxDistSquared;
while (proc.foundPhotons < nIndirSamplePhotons) {
float md2 = searchDist2;
proc.foundPhotons = 0;
indirectMap->Lookup(p, proc, md2);
searchDist2 *= 2.f;
}
// Copy photon directions to local array
Vector *photonDirs = (Vector *)alloca(nIndirSamplePhotons *
sizeof(Vector));
for (u_int i = 0; i < nIndirSamplePhotons; ++i)
photonDirs[i] = proc.photons[i].photon->wi;
// Use BSDF to do final gathering
Spectrum Li = 0.;
static StatsCounter gatherRays("Photon Map", // NOBOOK
"Final gather rays traced"); // NOBOOK
for (int i = 0; i < gatherSamples; ++i) {
// Sample random direction from BSDF for final gather ray
Vector wi;
float u1 = sample->twoD[gatherSampleOffset[0]][2*i];
float u2 = sample->twoD[gatherSampleOffset[0]][2*i+1];
float u3 = sample->oneD[gatherComponentOffset[0]][i];
float pdf;
Spectrum fr = bsdf->Sample_f(wo, &wi, u1, u2, u3,
&pdf, BxDFType(BSDF_ALL & (~BSDF_SPECULAR)));
if (fr.Black() || pdf == 0.f) continue;
// Trace BSDF final gather ray and accumulate radiance
RayDifferential bounceRay(p, wi);
++gatherRays; // NOBOOK
Intersection gatherIsect;
if (scene->Intersect(bounceRay, &gatherIsect)) {
// Compute exitant radiance using precomputed irradiance
Spectrum Lindir = 0.f;
Normal n = gatherIsect.dg.nn;
if (Dot(n, bounceRay.d) > 0) n = -n;
RadiancePhotonProcess proc(gatherIsect.dg.p, n);
float md2 = INFINITY;
radianceMap->Lookup(gatherIsect.dg.p, proc, md2);
if (proc.photon)
Lindir = proc.photon->Lo;
Lindir *= scene->Transmittance(bounceRay);
// Compute MIS weight for BSDF-sampled gather ray
// Compute PDF for photon-sampling of direction _wi_
float photonPdf = 0.f;
float conePdf = UniformConePdf(cosGatherAngle);
for (u_int j = 0; j < nIndirSamplePhotons; ++j)
if (Dot(photonDirs[j], wi) > .999f * cosGatherAngle)
photonPdf += conePdf;
photonPdf /= nIndirSamplePhotons;
float wt = PowerHeuristic(gatherSamples, pdf,
gatherSamples, photonPdf);
Li += fr * Lindir * AbsDot(wi, n) * wt / pdf;
}
}
L += Li / gatherSamples;
// Use nearby photons to do final gathering
Li = 0.;
for (int i = 0; i < gatherSamples; ++i) {
// Sample random direction using photons for final gather ray
float u1 = sample->oneD[gatherComponentOffset[1]][i];
float u2 = sample->twoD[gatherSampleOffset[1]][2*i];
float u3 = sample->twoD[gatherSampleOffset[1]][2*i+1];
int photonNum = min((int)nIndirSamplePhotons - 1,
Floor2Int(u1 * nIndirSamplePhotons));
// Sample gather ray direction from _photonNum_
Vector vx, vy;
//.........这里部分代码省略.........
示例4: Preprocess
void ExPhotonIntegrator::Preprocess(const Scene *scene) {
if (scene->lights.size() == 0) return;
ProgressReporter progress(nCausticPhotons+ // NOBOOK
nIndirectPhotons, "Shooting photons"); // NOBOOK
vector<Photon> causticPhotons;
vector<Photon> indirectPhotons;
vector<Photon> directPhotons;
vector<RadiancePhoton> radiancePhotons;
causticPhotons.reserve(nCausticPhotons); // NOBOOK
indirectPhotons.reserve(nIndirectPhotons); // NOBOOK
// Initialize photon shooting statistics
static StatsCounter nshot("Photon Map",
"Number of photons shot from lights");
bool causticDone = (nCausticPhotons == 0);
bool indirectDone = (nIndirectPhotons == 0);
// Compute light power CDF for photon shooting
int nLights = int(scene->lights.size());
float *lightPower = (float *)alloca(nLights * sizeof(float));
float *lightCDF = (float *)alloca((nLights+1) * sizeof(float));
for (int i = 0; i < nLights; ++i)
lightPower[i] = scene->lights[i]->Power(scene).y();
float totalPower;
ComputeStep1dCDF(lightPower, nLights, &totalPower, lightCDF);
// Declare radiance photon reflectance arrays
vector<Spectrum> rpReflectances, rpTransmittances;
while (!causticDone || !indirectDone) {
++nshot;
// Give up if we're not storing enough photons
if (nshot > 500000 &&
(unsuccessful(nCausticPhotons,
causticPhotons.size(),
nshot) ||
unsuccessful(nIndirectPhotons,
indirectPhotons.size(),
nshot))) {
Error("Unable to store enough photons. Giving up.\n");
return;
}
// Trace a photon path and store contribution
// Choose 4D sample values for photon
float u[4];
u[0] = RadicalInverse((int)nshot+1, 2);
u[1] = RadicalInverse((int)nshot+1, 3);
u[2] = RadicalInverse((int)nshot+1, 5);
u[3] = RadicalInverse((int)nshot+1, 7);
// Choose light to shoot photon from
float lightPdf;
float uln = RadicalInverse((int)nshot+1, 11);
int lightNum = Floor2Int(SampleStep1d(lightPower, lightCDF,
totalPower, nLights, uln, &lightPdf) * nLights);
lightNum = min(lightNum, nLights-1);
const Light *light = scene->lights[lightNum];
// Generate _photonRay_ from light source and initialize _alpha_
RayDifferential photonRay;
float pdf;
Spectrum alpha = light->Sample_L(scene, u[0], u[1], u[2], u[3],
&photonRay, &pdf);
if (pdf == 0.f || alpha.Black()) continue;
alpha /= pdf * lightPdf;
if (!alpha.Black()) {
// Follow photon path through scene and record intersections
bool specularPath = false;
Intersection photonIsect;
int nIntersections = 0;
while (scene->Intersect(photonRay, &photonIsect)) {
++nIntersections;
// Handle photon/surface intersection
alpha *= scene->Transmittance(photonRay);
Vector wo = -photonRay.d;
BSDF *photonBSDF = photonIsect.GetBSDF(photonRay);
BxDFType specularType = BxDFType(BSDF_REFLECTION |
BSDF_TRANSMISSION | BSDF_SPECULAR);
bool hasNonSpecular = (photonBSDF->NumComponents() >
photonBSDF->NumComponents(specularType));
if (hasNonSpecular) {
// Deposit photon at surface
Photon photon(photonIsect.dg.p, alpha, wo);
if (nIntersections == 1) {
// Deposit direct photon
directPhotons.push_back(photon);
}
else {
// Deposit either caustic or indirect photon
if (specularPath) {
// Process caustic photon intersection
if (!causticDone) {
causticPhotons.push_back(photon);
if (causticPhotons.size() == nCausticPhotons) {
causticDone = true;
nCausticPaths = (int)nshot;
causticMap = new KdTree<Photon, PhotonProcess>(causticPhotons);
}
progress.Update();
}
}
else {
//.........这里部分代码省略.........
示例5: Preprocess
void PhotonIntegrator::Preprocess(const Scene *scene) {
if (scene->lights.size() == 0) return;
ProgressReporter progress(nCausticPhotons+nDirectPhotons+ // NOBOOK
nIndirectPhotons, "Shooting photons"); // NOBOOK
vector<Photon> causticPhotons;
vector<Photon> directPhotons;
vector<Photon> indirectPhotons;
causticPhotons.reserve(nCausticPhotons); // NOBOOK
directPhotons.reserve(nDirectPhotons); // NOBOOK
indirectPhotons.reserve(nIndirectPhotons); // NOBOOK
// Initialize photon shooting statistics
static StatsCounter nshot("Photon Map",
"Number of photons shot from lights");
bool causticDone = (nCausticPhotons == 0);
bool directDone = (nDirectPhotons == 0);
bool indirectDone = (nIndirectPhotons == 0);
while (!causticDone || !directDone || !indirectDone) {
++nshot;
// Give up if we're not storing enough photons
if (nshot > 500000 &&
(unsuccessful(nCausticPhotons,
causticPhotons.size(),
nshot) ||
unsuccessful(nDirectPhotons,
directPhotons.size(),
nshot) ||
unsuccessful(nIndirectPhotons,
indirectPhotons.size(),
nshot))) {
Error("Unable to store enough photons. Giving up.\n");
return;
}
// Trace a photon path and store contribution
// Choose 4D sample values for photon
float u[4];
u[0] = (float)RadicalInverse((int)nshot+1, 2);
u[1] = (float)RadicalInverse((int)nshot+1, 3);
u[2] = (float)RadicalInverse((int)nshot+1, 5);
u[3] = (float)RadicalInverse((int)nshot+1, 7);
// Choose light to shoot photon from
int nLights = int(scene->lights.size());
int lightNum =
min(Floor2Int(nLights * (float)RadicalInverse((int)nshot+1, 11)),
nLights-1);
Light *light = scene->lights[lightNum];
float lightPdf = 1.f / nLights;
// Generate _photonRay_ from light source and initialize _alpha_
RayDifferential photonRay;
float pdf;
Spectrum alpha =
light->Sample_L(scene, u[0], u[1], u[2], u[3],
&photonRay, &pdf);
if (pdf == 0.f || alpha.Black()) continue;
alpha /= pdf * lightPdf;
if (!alpha.Black()) {
// Follow photon path through scene and record intersections
bool specularPath = false;
Intersection photonIsect;
int nIntersections = 0;
while (scene->Intersect(photonRay, &photonIsect)) {
++nIntersections;
// Handle photon/surface intersection
alpha *= scene->Transmittance(photonRay);
Vector wo = -photonRay.d;
BSDF *photonBSDF = photonIsect.GetBSDF(photonRay);
BxDFType specularType = BxDFType(BSDF_REFLECTION |
BSDF_TRANSMISSION | BSDF_SPECULAR);
bool hasNonSpecular = (photonBSDF->NumComponents() >
photonBSDF->NumComponents(specularType));
if (hasNonSpecular) {
// Deposit photon at surface
Photon photon(photonIsect.dg.p, alpha, wo);
if (nIntersections == 1) {
// Process direct lighting photon intersection
if (!directDone) {
directPhotons.push_back(photon);
if (directPhotons.size() == nDirectPhotons) {
directDone = true;
nDirectPaths = (int)nshot;
directMap =
new KdTree<Photon,
PhotonProcess>(directPhotons);
}
progress.Update(); // NOBOOK
}
}
else if (specularPath) {
// Process caustic photon intersection
if (!causticDone) {
causticPhotons.push_back(photon);
if (causticPhotons.size() == nCausticPhotons) {
causticDone = true;
nCausticPaths = (int)nshot;
causticMap =
new KdTree<Photon,
PhotonProcess>(causticPhotons);
}
progress.Update();
}
}
//.........这里部分代码省略.........