本文整理汇总了C++中BSDF::sample方法的典型用法代码示例。如果您正苦于以下问题:C++ BSDF::sample方法的具体用法?C++ BSDF::sample怎么用?C++ BSDF::sample使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BSDF
的用法示例。
在下文中一共展示了BSDF::sample方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sampleScattering
bool BidirPathTracing::sampleScattering(BSDF& bsdf ,
const Vector3& hitPos , BidirPathState& pathState)
{
Real bsdfDirPdf , cosWo;
int sampledBSDFType;
Color3 bsdfFactor = bsdf.sample(scene , rng.randVector3() ,
pathState.dir , bsdfDirPdf , cosWo , &sampledBSDFType);
if (bsdfFactor.isBlack())
return 0;
Real bsdfRevPdf = bsdfDirPdf;
if ((sampledBSDFType & BSDF_SPECULAR) == 0)
bsdfRevPdf = bsdf.pdf(scene , pathState.dir , 1);
Real contProb = bsdf.continueProb;
if (rng.randFloat() > contProb)
return 0;
bsdfDirPdf *= contProb;
bsdfRevPdf *= contProb;
// Partial sub-path MIS quantities
// the evaluation is completed when the actual hit point is known!
// i.e. after tracing the ray, out of the procedure
if (sampledBSDFType & BSDF_SPECULAR)
{
pathState.specularVertexNum++;
pathState.dVCM = 0.f;
pathState.dVC *= mis(cosWo);
}
else
{
pathState.specularPath &= 0;
pathState.dVC = mis(1.f / bsdfDirPdf) * (pathState.dVCM +
pathState.dVC * mis(bsdfRevPdf));
pathState.dVCM = mis(1.f / bsdfDirPdf);
}
pathState.origin = hitPos;
pathState.throughput = (pathState.throughput | bsdfFactor) *
(cosWo / bsdfDirPdf);
return 1;
}
示例2: compute_ibl_bsdf_sampling
void compute_ibl_bsdf_sampling(
SamplingContext& sampling_context,
const ShadingContext& shading_context,
const EnvironmentEDF& environment_edf,
const ShadingPoint& shading_point,
const Vector3d& outgoing,
const BSDF& bsdf,
const void* bsdf_data,
const int bsdf_sampling_modes,
const size_t bsdf_sample_count,
const size_t env_sample_count,
Spectrum& radiance)
{
assert(is_normalized(outgoing));
const Vector3d& geometric_normal = shading_point.get_geometric_normal();
const Basis3d& shading_basis = shading_point.get_shading_basis();
radiance.set(0.0f);
for (size_t i = 0; i < bsdf_sample_count; ++i)
{
// Sample the BSDF.
// todo: rendering will be incorrect if the BSDF value returned by the sample() method
// includes the contribution of a specular component since these are explicitly rejected
// afterward. We need a mechanism to indicate that we want the contribution of some of
// the components only.
Vector3d incoming;
Spectrum bsdf_value;
double bsdf_prob;
const BSDF::Mode bsdf_mode =
bsdf.sample(
sampling_context,
bsdf_data,
false, // not adjoint
true, // multiply by |cos(incoming, normal)|
geometric_normal,
shading_basis,
outgoing,
incoming,
bsdf_value,
bsdf_prob);
// Filter scattering modes.
if (!(bsdf_sampling_modes & bsdf_mode))
return;
// Discard occluded samples.
const double transmission =
shading_context.get_tracer().trace(
shading_point,
incoming,
ShadingRay::ShadowRay);
if (transmission == 0.0)
continue;
// Evaluate the environment's EDF.
InputEvaluator input_evaluator(shading_context.get_texture_cache());
Spectrum env_value;
double env_prob;
environment_edf.evaluate(
input_evaluator,
incoming,
env_value,
env_prob);
// Apply all weights, including MIS weight.
if (bsdf_mode == BSDF::Specular)
env_value *= static_cast<float>(transmission);
else
{
const double mis_weight =
mis_power2(
bsdf_sample_count * bsdf_prob,
env_sample_count * env_prob);
env_value *= static_cast<float>(transmission / bsdf_prob * mis_weight);
}
// Add the contribution of this sample to the illumination.
env_value *= bsdf_value;
radiance += env_value;
}
if (bsdf_sample_count > 1)
radiance /= static_cast<float>(bsdf_sample_count);
}
示例3: extend
bool extend(BDPTPathVertex& next,
const Scene& scene,
uint32_t pathCount,
bool sampleAdjoint, // Number of paths sampled with the strategies s/t = m_nDepth + 1, t/s = *
RandomGenerator&& rng,
MisFunctor&& mis) {
if(!m_Intersection) {
return false; // Can't sample from infinity
}
Sample3f woSample;
float cosThetaOutDir;
uint32_t sampledEvent;
auto fs = m_BSDF.sample(Vec3f(getFloat(rng), getFloat2(rng)), woSample, cosThetaOutDir, &sampledEvent, sampleAdjoint);
if(woSample.pdf == 0.f || fs == zero<Vec3f>()) {
return false;
}
float reversePdf = m_BSDF.pdf(woSample.value, true);
auto nextI = scene.intersect(Ray(m_Intersection, woSample.value));
if(!nextI) {
next.m_Intersection = nextI;
next.m_BSDF.init(-woSample.value, scene);
next.m_fPdfWrtArea = woSample.pdf;
next.m_fPathPdf = m_fPathPdf * woSample.pdf;
next.m_Power = m_Power * abs(cosThetaOutDir) * fs / woSample.pdf;
next.m_nDepth = m_nDepth + 1;
auto previousPointToIncidentDirectionJacobian = abs(cosThetaOutDir); // No division by squared distance since the point is at infinity
if((sampledEvent & ScatteringEvent::Specular) && m_BSDF.isDelta()) {
next.m_fdVC = mis(previousPointToIncidentDirectionJacobian) * m_fdVC;
next.m_fdVCM = 0.f;
} else {
// We set dVC first in case next == *this, so that the dVCM is unchanged until next line
next.m_fdVC = mis(previousPointToIncidentDirectionJacobian / next.m_fPdfWrtArea) * (m_fdVCM + mis(reversePdf) * m_fdVC);
next.m_fdVCM = mis(pathCount / next.m_fPdfWrtArea);
}
} else {
auto incidentDirection = -woSample.value;
auto sqrLength = sqr(nextI.distance);
if(sqrLength == 0.f) {
return false;
}
auto pdfWrtArea = woSample.pdf * abs(dot(nextI.Ns, incidentDirection)) / sqrLength;
if(pdfWrtArea == 0.f) {
return false;
}
next.m_Intersection = nextI;
next.m_BSDF.init(incidentDirection, nextI, scene);
next.m_fPdfWrtArea = pdfWrtArea;
next.m_fPathPdf = m_fPathPdf * pdfWrtArea;
next.m_Power = m_Power * abs(cosThetaOutDir) * fs / woSample.pdf;
next.m_nDepth = m_nDepth + 1;
auto previousPointToIncidentDirectionJacobian = abs(cosThetaOutDir) / sqrLength;
if((sampledEvent & ScatteringEvent::Specular) && m_BSDF.isDelta()) {
next.m_fdVC = mis(previousPointToIncidentDirectionJacobian) * m_fdVC;
next.m_fdVCM = 0.f;
} else {
// We set dVC first in case next == *this, so that the dVCM is unchanged until next line
next.m_fdVC = mis(previousPointToIncidentDirectionJacobian / next.m_fPdfWrtArea) * (m_fdVCM + mis(reversePdf) * m_fdVC);
next.m_fdVCM = mis(pathCount / next.m_fPdfWrtArea);
}
}
return true;
}
示例4: sp
SampledSpectrum PathTracingRenderer::Job::contribution(const Scene &scene, const WavelengthSamples &initWLs, const Ray &initRay, IndependentLightPathSampler &pathSampler, ArenaAllocator &mem) const {
WavelengthSamples wls = initWLs;
Ray ray = initRay;
SurfacePoint surfPt;
SampledSpectrum alpha = SampledSpectrum::One;
float initY = alpha.importance(wls.selectedLambda);
SampledSpectrumSum sp(SampledSpectrum::Zero);
uint32_t pathLength = 0;
Intersection isect;
if (!scene.intersect(ray, &isect))
return SampledSpectrum::Zero;
isect.getSurfacePoint(&surfPt);
Vector3D dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir);
if (surfPt.isEmitting()) {
EDF* edf = surfPt.createEDF(wls, mem);
SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn);
sp += alpha * Le;
}
if (surfPt.atInfinity)
return sp;
while (true) {
++pathLength;
if (pathLength >= 100)
break;
Normal3D gNorm_sn = surfPt.shadingFrame.toLocal(surfPt.gNormal);
BSDF* bsdf = surfPt.createBSDF(wls, mem);
BSDFQuery fsQuery(dirOut_sn, gNorm_sn, wls.selectedLambda);
// Next Event Estimation (explicit light sampling)
if (bsdf->hasNonDelta()) {
float lightProb;
Light light;
scene.selectLight(pathSampler.getLightSelectionSample(), &light, &lightProb);
SLRAssert(!std::isnan(lightProb) && !std::isinf(lightProb), "lightProb: unexpected value detected: %f", lightProb);
LightPosQuery lpQuery(ray.time, wls);
LightPosQueryResult lpResult;
SampledSpectrum M = light.sample(lpQuery, pathSampler.getLightPosSample(), &lpResult);
SLRAssert(!std::isnan(lpResult.areaPDF)/* && !std::isinf(xpResult.areaPDF)*/, "areaPDF: unexpected value detected: %f", lpResult.areaPDF);
if (scene.testVisibility(surfPt, lpResult.surfPt, ray.time)) {
float dist2;
Vector3D shadowDir = lpResult.surfPt.getDirectionFrom(surfPt.p, &dist2);
Vector3D shadowDir_l = lpResult.surfPt.shadingFrame.toLocal(-shadowDir);
Vector3D shadowDir_sn = surfPt.shadingFrame.toLocal(shadowDir);
EDF* edf = lpResult.surfPt.createEDF(wls, mem);
SampledSpectrum Le = M * edf->evaluate(EDFQuery(), shadowDir_l);
float lightPDF = lightProb * lpResult.areaPDF;
SLRAssert(!Le.hasNaN() && !Le.hasInf(), "Le: unexpected value detected: %s", Le.toString().c_str());
SampledSpectrum fs = bsdf->evaluate(fsQuery, shadowDir_sn);
float cosLight = absDot(-shadowDir, lpResult.surfPt.gNormal);
float bsdfPDF = bsdf->evaluatePDF(fsQuery, shadowDir_sn) * cosLight / dist2;
float MISWeight = 1.0f;
if (!lpResult.posType.isDelta() && !std::isinf(lpResult.areaPDF))
MISWeight = (lightPDF * lightPDF) / (lightPDF * lightPDF + bsdfPDF * bsdfPDF);
SLRAssert(MISWeight <= 1.0f, "Invalid MIS weight: %g", MISWeight);
float G = absDot(shadowDir_sn, gNorm_sn) * cosLight / dist2;
sp += alpha * Le * fs * (G * MISWeight / lightPDF);
SLRAssert(!std::isnan(G) && !std::isinf(G), "G: unexpected value detected: %f", G);
}
}
// get a next direction by sampling BSDF.
BSDFQueryResult fsResult;
SampledSpectrum fs = bsdf->sample(fsQuery, pathSampler.getBSDFSample(), &fsResult);
if (fs == SampledSpectrum::Zero || fsResult.dirPDF == 0.0f)
break;
if (fsResult.dirType.isDispersive()) {
fsResult.dirPDF /= WavelengthSamples::NumComponents;
wls.flags |= WavelengthSamples::LambdaIsSelected;
}
alpha *= fs * absDot(fsResult.dir_sn, gNorm_sn) / fsResult.dirPDF;
SLRAssert(!alpha.hasInf() && !alpha.hasNaN(),
"alpha: %s\nlength: %u, cos: %g, dirPDF: %g",
alpha.toString().c_str(), pathLength, absDot(fsResult.dir_sn, gNorm_sn), fsResult.dirPDF);
Vector3D dirIn = surfPt.shadingFrame.fromLocal(fsResult.dir_sn);
ray = Ray(surfPt.p, dirIn, ray.time, Ray::Epsilon);
// find a next intersection point.
isect = Intersection();
if (!scene.intersect(ray, &isect))
break;
isect.getSurfacePoint(&surfPt);
dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir);
// implicit light sampling
if (surfPt.isEmitting()) {
float bsdfPDF = fsResult.dirPDF;
EDF* edf = surfPt.createEDF(wls, mem);
SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn);
//.........这里部分代码省略.........
示例5: getDirectIllumination
Color3 BidirPathTracing::getDirectIllumination(BidirPathState& cameraState ,
const Vector3& hitPos , BSDF& bsdf)
{
Color3 res(0);
Real weight = 0.f;
int lightCount = scene.lights.size();
Real lightPickProb = 1.f / lightCount;
int lightId = (int)(rng.randFloat() * lightCount);
AbstractLight *light = scene.lights[lightId];
Vector3 dirToLight;
Real dist , directPdf , emissionPdf , cosAtLight , cosAtSurface;
int sampledBSDFType;
Color3 illu = light->illuminance(scene.sceneSphere ,
hitPos , rng.randVector3() , dirToLight , dist ,
directPdf , &emissionPdf , &cosAtLight);
Real bsdfDirPdf , bsdfRevPdf , cosToLight;
if (!illu.isBlack() && directPdf > 0)
{
Color3 bsdfFactor = bsdf.f(scene , dirToLight ,
cosToLight , &bsdfDirPdf , &bsdfRevPdf);
Color3 tmp;
if (!bsdfFactor.isBlack())
{
Real contProb = bsdf.continueProb;
bsdfDirPdf *= light->isDelta() ? 0.f : contProb;
bsdfRevPdf *= contProb;
tmp = (illu | bsdfFactor) * cosToLight / (directPdf * lightPickProb);
if (!tmp.isBlack() && !scene.occluded(hitPos , dirToLight ,
hitPos + dirToLight * dist))
{
Real wLight = mis(bsdfDirPdf) / mis(directPdf * lightPickProb);
Real wCamera = mis(emissionPdf * cosToLight / (directPdf * cosAtLight)) *
(cameraState.dVCM + mis(bsdfRevPdf) * cameraState.dVC);
weight = 1.f / (wLight + 1.f + wCamera);
//fprintf(fp , "weight = %.6f\n" , weight);
if (light->isDelta())
{
res = res + tmp;
}
else
{
Real _weight = mis(directPdf) /
(mis(directPdf) + mis(bsdfDirPdf));
res = res + tmp * _weight;
}
}
}
}
if (!light->isDelta())
{
Color3 bsdfFactor = bsdf.sample(scene , rng.randVector3() ,
dirToLight , directPdf , cosAtSurface , &sampledBSDFType);
if (!bsdfFactor.isBlack() && directPdf > 0)
{
Real weight = 1.f;
Real lightPdf;
if (!(sampledBSDFType & BSDF_SPECULAR))
{
illu = light->getRadiance(scene.sceneSphere , dirToLight , hitPos ,
&lightPdf , &emissionPdf);
if (cmp(lightPdf) == 0)
return res;
weight = mis(directPdf) /
(mis(directPdf) + mis(lightPdf));
}
Intersection lightInter;
Color3 tmp(0.f);
Ray ray(hitPos + dirToLight * EPS , dirToLight);
if (scene.intersect(ray , lightInter) != NULL)
{
if (lightInter.matId < 0)
{
if (light != scene.lights[-lightInter.matId - 1])
{
illu = Color3(0.f);
}
}
else
//.........这里部分代码省略.........