本文整理汇总了C++中Spectrum类的典型用法代码示例。如果您正苦于以下问题:C++ Spectrum类的具体用法?C++ Spectrum怎么用?C++ Spectrum使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Spectrum类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: compute_ibl_environment_sampling
void compute_ibl_environment_sampling(
SamplingContext& sampling_context,
const ShadingContext& shading_context,
const EnvironmentEDF& environment_edf,
const BSSRDF& bssrdf,
const void* bssrdf_data,
const ShadingPoint& incoming_point,
const ShadingPoint& outgoing_point,
const Dual3d& outgoing,
const size_t bssrdf_sample_count,
const size_t env_sample_count,
Spectrum& radiance)
{
assert(is_normalized(outgoing.get_value()));
const Basis3d& shading_basis = incoming_point.get_shading_basis();
radiance.set(0.0f);
sampling_context.split_in_place(2, env_sample_count);
for (size_t i = 0; i < env_sample_count; ++i)
{
// Generate a uniform sample in [0,1)^2.
const Vector2d s = sampling_context.next_vector2<2>();
// Sample the environment.
InputEvaluator input_evaluator(shading_context.get_texture_cache());
Vector3d incoming;
Spectrum env_value;
double env_prob;
environment_edf.sample(
shading_context,
input_evaluator,
s,
incoming,
env_value,
env_prob);
// Cull samples behind the shading surface.
assert(is_normalized(incoming));
const double cos_in = dot(incoming, shading_basis.get_normal());
if (cos_in <= 0.0)
continue;
// Discard occluded samples.
const double transmission =
shading_context.get_tracer().trace(
incoming_point,
incoming,
VisibilityFlags::ShadowRay);
if (transmission == 0.0)
continue;
// Evaluate the BSSRDF.
Spectrum bssrdf_value;
bssrdf.evaluate(
bssrdf_data,
outgoing_point,
outgoing.get_value(),
incoming_point,
incoming,
bssrdf_value);
// Compute MIS weight.
const double bssrdf_prob = cos_in * RcpPi;
const double mis_weight =
mis_power2(
env_sample_count * env_prob,
bssrdf_sample_count * bssrdf_prob);
// Add the contribution of this sample to the illumination.
env_value *= static_cast<float>(transmission * cos_in / env_prob * mis_weight);
env_value *= bssrdf_value;
radiance += env_value;
}
if (env_sample_count > 1)
radiance /= static_cast<float>(env_sample_count);
}
示例2: Li
Spectrum Li(const RayDifferential &r, RadianceQueryRecord &rRec) const {
/* Some aliases and local variables */
const Scene *scene = rRec.scene;
Intersection &its = rRec.its;
RayDifferential ray(r);
Spectrum Li(0.0f);
bool scattered = false;
/* Perform the first ray intersection (or ignore if the
intersection has already been provided). */
rRec.rayIntersect(ray);
ray.mint = Epsilon;
Spectrum throughput(1.0f);
Float eta = 1.0f;
while (rRec.depth <= m_maxDepth || m_maxDepth < 0) {
if (!its.isValid()) {
/* If no intersection could be found, potentially return
radiance from a environment luminaire if it exists */
if ((rRec.type & RadianceQueryRecord::EEmittedRadiance)
&& (!m_hideEmitters || scattered))
Li += throughput * scene->evalEnvironment(ray);
break;
}
const BSDF *bsdf = its.getBSDF(ray);
/* Possibly include emitted radiance if requested */
if (its.isEmitter() && (rRec.type & RadianceQueryRecord::EEmittedRadiance)
&& (!m_hideEmitters || scattered))
Li += throughput * its.Le(-ray.d);
/* Include radiance from a subsurface scattering model if requested */
if (its.hasSubsurface() && (rRec.type & RadianceQueryRecord::ESubsurfaceRadiance))
Li += throughput * its.LoSub(scene, rRec.sampler, -ray.d, rRec.depth);
if ((rRec.depth >= m_maxDepth && m_maxDepth > 0)
|| (m_strictNormals && dot(ray.d, its.geoFrame.n)
* Frame::cosTheta(its.wi) >= 0)) {
/* Only continue if:
1. The current path length is below the specifed maximum
2. If 'strictNormals'=true, when the geometric and shading
normals classify the incident direction to the same side */
break;
}
/* ==================================================================== */
/* Direct illumination sampling */
/* ==================================================================== */
/* Estimate the direct illumination if this is requested */
DirectSamplingRecord dRec(its);
if (rRec.type & RadianceQueryRecord::EDirectSurfaceRadiance &&
(bsdf->getType() & BSDF::ESmooth)) {
Spectrum value = scene->sampleEmitterDirect(dRec, rRec.nextSample2D());
if (!value.isZero()) {
const Emitter *emitter = static_cast<const Emitter *>(dRec.object);
/* Allocate a record for querying the BSDF */
BSDFSamplingRecord bRec(its, its.toLocal(dRec.d), ERadiance);
/* Evaluate BSDF * cos(theta) */
const Spectrum bsdfVal = bsdf->eval(bRec);
/* Prevent light leaks due to the use of shading normals */
if (!bsdfVal.isZero() && (!m_strictNormals
|| dot(its.geoFrame.n, dRec.d) * Frame::cosTheta(bRec.wo) > 0)) {
/* Calculate prob. of having generated that direction
using BSDF sampling */
Float bsdfPdf = (emitter->isOnSurface() && dRec.measure == ESolidAngle)
? bsdf->pdf(bRec) : 0;
/* Weight using the power heuristic */
Float weight = miWeight(dRec.pdf, bsdfPdf);
Li += throughput * value * bsdfVal * weight;
}
}
}
/* ==================================================================== */
/* BSDF sampling */
/* ==================================================================== */
/* Sample BSDF * cos(theta) */
Float bsdfPdf;
BSDFSamplingRecord bRec(its, rRec.sampler, ERadiance);
Spectrum bsdfWeight = bsdf->sample(bRec, bsdfPdf, rRec.nextSample2D());
if (bsdfWeight.isZero())
break;
scattered |= bRec.sampledType != BSDF::ENull;
/* Prevent light leaks due to the use of shading normals */
const Vector wo = its.toWorld(bRec.wo);
Float woDotGeoN = dot(its.geoFrame.n, wo);
if (m_strictNormals && woDotGeoN * Frame::cosTheta(bRec.wo) <= 0)
//.........这里部分代码省略.........
示例3: I
inline float I(const Spectrum &L) {
return L.y();
}
示例4: physics_error
// refl: [0, 1] value.
UniformLambertMaterial::UniformLambertMaterial(const Spectrum& refl) :
refl(refl) {
if(refl.minCoeff() < 0 || refl.maxCoeff() > 1) {
throw physics_error("Don't create non energy conserving lambertian BSDF.");
}
}
示例5: L
Spectrum PhotonIntegrator::Li(const Scene &scene, const Renderer *renderer,
const RayDifferential &ray, const Intersection &isect,
const Sample *sample, RNG &rng, MemoryArena &arena) const {
Spectrum L(0.);
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, arena);
const Point &p = bsdf->dgShading.p;
const Normal &n = bsdf->dgShading.nn;
L += UniformSampleAllLights(scene, renderer, arena, p, n,
wo, isect.rayEpsilon, ray.time, bsdf, sample, rng,
lightSampleOffsets, bsdfSampleOffsets);
// Compute caustic lighting for photon map integrator
ClosePhoton *lookupBuf = arena.Alloc<ClosePhoton>(nLookup);
L += LPhoton(causticMap, nCausticPaths, nLookup, lookupBuf, bsdf,
rng, isect, wo, maxDistSquared);
// Compute indirect lighting for photon map integrator
if (finalGather && indirectMap != NULL) {
#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
const uint32_t nIndirSamplePhotons = 50;
PhotonProcess proc(nIndirSamplePhotons,
arena.Alloc<ClosePhoton>(nIndirSamplePhotons));
float searchDist2 = maxDistSquared;
while (proc.nFound < nIndirSamplePhotons) {
float md2 = searchDist2;
proc.nFound = 0;
indirectMap->Lookup(p, proc, md2);
searchDist2 *= 2.f;
}
// Copy photon directions to local array
Vector *photonDirs = arena.Alloc<Vector>(nIndirSamplePhotons);
for (uint32_t i = 0; i < nIndirSamplePhotons; ++i)
photonDirs[i] = proc.photons[i].photon->wi;
// Use BSDF to do final gathering
Spectrum Li = 0.;
for (int i = 0; i < gatherSamples; ++i) {
// Sample random direction from BSDF for final gather ray
Vector wi;
float pdf;
BSDFSample bsdfSample(sample, bsdfGatherSampleOffsets, i);
Spectrum fr = bsdf->Sample_f(wo, &wi, bsdfSample,
&pdf, BxDFType(BSDF_ALL & ~BSDF_SPECULAR));
if (fr.IsBlack() || pdf == 0.f) continue;
Assert(pdf >= 0.f);
// Trace BSDF final gather ray and accumulate radiance
RayDifferential bounceRay(p, wi, ray, isect.rayEpsilon);
auto optGatherIsect = scene.Intersect(bounceRay);
if (optGatherIsect) {
// Compute exitant radiance _Lindir_ using radiance photons
Spectrum Lindir = 0.f;
Normal nGather = optGatherIsect->dg.nn;
nGather = Faceforward(nGather, -bounceRay.d);
RadiancePhotonProcess proc(nGather);
float md2 = INFINITY;
radianceMap->Lookup(optGatherIsect->dg.p, proc, md2);
if (proc.photon != NULL)
Lindir = proc.photon->Lo;
Lindir *= renderer->Transmittance(scene, bounceRay, NULL, rng, arena);
// 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 (uint32_t 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
BSDFSample gatherSample(sample, indirGatherSampleOffsets, i);
int photonNum = min((int)nIndirSamplePhotons - 1,
Floor2Int(gatherSample.uComponent * nIndirSamplePhotons));
// Sample gather ray direction from _photonNum_
Vector vx, vy;
CoordinateSystem(photonDirs[photonNum], &vx, &vy);
Vector wi = UniformSampleCone(gatherSample.uDir[0], gatherSample.uDir[1],
cosGatherAngle, vx, vy, photonDirs[photonNum]);
//.........这里部分代码省略.........
示例6: compute_outgoing_radiance_light_sampling_low_variance
void DirectLightingIntegrator::compute_outgoing_radiance_light_sampling_low_variance(
SamplingContext& sampling_context,
const MISHeuristic mis_heuristic,
const Dual3d& outgoing,
Spectrum& radiance,
SpectrumStack& aovs) const
{
radiance.set(0.0f);
aovs.set(0.0f);
// todo: if we had a way to know that a BSDF is purely specular, we could
// immediately return black here since there will be no contribution from
// such a BSDF.
// Sample emitting triangles.
if (m_light_sampler.get_emitting_triangle_count() > 0)
{
sampling_context.split_in_place(3, m_light_sample_count);
for (size_t i = 0; i < m_light_sample_count; ++i)
{
const Vector3d s = sampling_context.next_vector2<3>();
LightSample sample;
m_light_sampler.sample_emitting_triangles(m_time, s, sample);
add_emitting_triangle_sample_contribution(
sample,
mis_heuristic,
outgoing,
radiance,
aovs);
}
if (m_light_sample_count > 1)
{
const float rcp_light_sample_count = 1.0f / m_light_sample_count;
radiance *= rcp_light_sample_count;
aovs *= rcp_light_sample_count;
}
}
// Sample non-physical light sources.
const size_t light_count = m_light_sampler.get_non_physical_light_count();
if (light_count > 0)
{
sampling_context.split_in_place(2, light_count);
for (size_t i = 0; i < light_count; ++i)
{
const Vector2d s = sampling_context.next_vector2<2>();
LightSample sample;
m_light_sampler.sample_non_physical_light(m_time, s, i, sample);
add_non_physical_light_sample_contribution(
sample,
outgoing,
radiance,
aovs);
}
}
}
示例7: 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);
}
示例8: switch
//.........这里部分代码省略.........
const bool missed = rayHit ? rayHit->Miss() : false;
if (missed ||
(state == ONLY_SHADOW_RAYS) ||
(state == TRANSPARENT_ONLY_SHADOW_RAYS_STEP) ||
(depth >= renderEngine->maxPathDepth)) {
if (missed && scene->infiniteLight && (scene->useInfiniteLightBruteForce || specularBounce)) {
// Add the light emitted by the infinite light
radiance += scene->infiniteLight->Le(pathRay.d) * throughput;
}
// Hit nothing/only shadow rays/maxdepth, terminate the path
sampleBuffer->SplatSample(sample.screenX, sample.screenY, radiance);
// Restart the path
Init(renderEngine, sampler);
return;
}
// Something was hit
const unsigned int currentTriangleIndex = rayHit->index;
const unsigned int currentMeshIndex = scene->dataSet->GetMeshID(currentTriangleIndex);
// Get the triangle
const ExtMesh *mesh = scene->objects[currentMeshIndex];
const unsigned int triIndex = scene->dataSet->GetMeshTriangleID(currentTriangleIndex);
// Get the material
const Material *triMat = scene->objectMaterials[currentMeshIndex];
// Check if it is a light source
if (triMat->IsLightSource()) {
if (specularBounce) {
// Only TriangleLight can be directly hit
const LightMaterial *mLight = (LightMaterial *) triMat;
Spectrum Le = mLight->Le(mesh, triIndex, -pathRay.d);
radiance += Le * throughput;
}
// Terminate the path
sampleBuffer->SplatSample(sample.screenX, sample.screenY, radiance);
// Restart the path
Init(renderEngine, sampler);
return;
}
//--------------------------------------------------------------------------
// Build the shadow rays (if required)
//--------------------------------------------------------------------------
// Interpolate face normal
Normal N = mesh->InterpolateTriNormal(triIndex, rayHit->b1, rayHit->b2);
const SurfaceMaterial *triSurfMat = (SurfaceMaterial *) triMat;
const Point hitPoint = pathRay(rayHit->t);
const Vector wo = -pathRay.d;
Spectrum surfaceColor;
if (mesh->HasColors())
surfaceColor = mesh->InterpolateTriColor(triIndex, rayHit->b1, rayHit->b2);
else
surfaceColor = Spectrum(1.f, 1.f, 1.f);
// Check if I have to apply texture mapping or normal mapping
TexMapInstance *tm = scene->objectTexMaps[currentMeshIndex];
BumpMapInstance *bm = scene->objectBumpMaps[currentMeshIndex];
NormalMapInstance *nm = scene->objectNormalMaps[currentMeshIndex];
示例9: while
// return the radiance of a specific direction
// note : there are one factor makes the method biased.
// there is a limitation on the number of vertexes in the path
Spectrum PathTracing::Li( const Ray& ray , const PixelSample& ps ) const
{
Spectrum L = 0.0f;
Spectrum throughput = 1.0f;
int bounces = 0;
Ray r = ray;
while(true)
{
Intersection inter;
// get the intersection between the ray and the scene
// if it's a light , accumulate the radiance and break
if( false == scene.GetIntersect( r , &inter ) )
{
if( bounces == 0 )
return scene.Le( r );
break;
}
if( bounces == 0 ) L+=inter.Le(-r.m_Dir);
// make sure there is intersected primitive
Sort_Assert( inter.primitive != 0 );
// evaluate the light
Bsdf* bsdf = inter.primitive->GetMaterial()->GetBsdf(&inter);
float light_pdf = 0.0f;
LightSample light_sample = (bounces==0)?ps.light_sample[0]:LightSample(true);
BsdfSample bsdf_sample = (bounces==0)?ps.bsdf_sample[0]:BsdfSample(true);
const Light* light = scene.SampleLight( light_sample.t , &light_pdf );
if( light_pdf > 0.0f )
L += throughput * EvaluateDirect( r , scene , light , inter , light_sample ,
bsdf_sample , BXDF_TYPE(BXDF_ALL) ) / light_pdf;
// sample the next direction using bsdf
float path_pdf;
Vector wi;
BXDF_TYPE bxdf_type;
Spectrum f;
BsdfSample _bsdf_sample = (bounces==0)?ps.bsdf_sample[1]:BsdfSample(true);
f = bsdf->sample_f( -r.m_Dir , wi , _bsdf_sample , &path_pdf , BXDF_ALL , &bxdf_type );
if( f.IsBlack() || path_pdf == 0.0f )
break;
// update path weight
throughput *= f * AbsDot( wi , inter.normal ) / path_pdf;
if( throughput.GetIntensity() == 0.0f )
break;
if( bounces > 4 )
{
float continueProperbility = min( 0.5f , throughput.GetIntensity() );
if( sort_canonical() > continueProperbility )
break;
throughput /= continueProperbility;
}
r.m_Ori = inter.intersect;
r.m_Dir = wi;
r.m_fMin = 0.001f;
++bounces;
// note : the following code makes the method biased
// 'path_per_pixel' could be set very large to reduce the side-effect.
if( bounces >= max_recursive_depth )
break;
}
return L;
}
示例10: min
u_int64_t CPU_Worker::AdvancePhotonPath(u_int64_t photonTarget) {
uint todoPhotonCount = 0;
PhotonPath* livePhotonPaths = new PhotonPath[rayBuffer->GetSize()];
rayBuffer->Reset();
size_t initc = min((int) rayBuffer->GetSize(), (int) photonTarget);
double start = WallClockTime();
for (size_t i = 0; i < initc; ++i) {
int p = rayBuffer->ReserveRay();
Ray * b = &(rayBuffer->GetRayBuffer())[p];
engine->InitPhotonPath(engine->ss, &livePhotonPaths[i], b, seedBuffer[i]);
}
while (todoPhotonCount < photonTarget) {
Intersect(rayBuffer);
#ifndef __DEBUG
omp_set_num_threads(config->max_threads);
#pragma omp parallel for schedule(guided)
#endif
for (unsigned int i = 0; i < rayBuffer->GetRayCount(); ++i) {
PhotonPath *photonPath = &livePhotonPaths[i];
Ray *ray = &rayBuffer->GetRayBuffer()[i];
RayHit *rayHit = &rayBuffer->GetHitBuffer()[i];
if (photonPath->done == true) {
continue;
}
if (rayHit->Miss()) {
photonPath->done = true;
} else { // Something was hit
Point hitPoint;
Spectrum surfaceColor;
Normal N, shadeN;
if (engine->GetHitPointInformation(engine->ss, ray, rayHit, hitPoint, surfaceColor,
N, shadeN))
continue;
const unsigned int currentTriangleIndex = rayHit->index;
const unsigned int currentMeshIndex = engine->ss->meshIDs[currentTriangleIndex];
POINTERFREESCENE::Material *hitPointMat =
&engine->ss->materials[engine->ss->meshMats[currentMeshIndex]];
uint matType = hitPointMat->type;
if (matType == MAT_AREALIGHT) {
photonPath->done = true;
} else {
float fPdf;
Vector wi;
Vector wo = -ray->d;
bool specularBounce = true;
float u0 = getFloatRNG(seedBuffer[i]);
float u1 = getFloatRNG(seedBuffer[i]);
float u2 = getFloatRNG(seedBuffer[i]);
Spectrum f;
switch (matType) {
case MAT_MATTE:
engine->ss->Matte_Sample_f(&hitPointMat->param.matte, &wo, &wi, &fPdf, &f,
&shadeN, u0, u1, &specularBounce);
f *= surfaceColor;
break;
case MAT_MIRROR:
engine->ss->Mirror_Sample_f(&hitPointMat->param.mirror, &wo, &wi, &fPdf,
&f, &shadeN, &specularBounce);
f *= surfaceColor;
break;
case MAT_GLASS:
engine->ss->Glass_Sample_f(&hitPointMat->param.glass, &wo, &wi, &fPdf, &f,
&N, &shadeN, u0, &specularBounce);
f *= surfaceColor;
break;
//.........这里部分代码省略.........
示例11: convert
static void convert(const Spectrum &from, float *to) {
*to = from.y();
}
示例12: omp_set_num_threads
void CPU_Worker::AdvanceEyePaths( RayBuffer *rayBuffer, EyePath* todoEyePaths, uint* eyePathIndexes) {
const uint max = rayBuffer->GetRayCount();
omp_set_num_threads(config->max_threads);
#pragma omp parallel for schedule(guided)
for (uint i = 0; i < max; i++) {
EyePath *eyePath = &todoEyePaths[eyePathIndexes[i]];
const RayHit *rayHit = &rayBuffer->GetHitBuffer()[i];
if (rayHit->Miss()) {
// Add an hit point
//HitPointInfo &hp = *(engine->GetHitPointInfo(eyePath->pixelIndex));
HitPointStaticInfo &hp = hitPointsStaticInfo_iterationCopy[eyePath->sampleIndex];
//HitPoint &hp = GetHitPoint(hitPointsIndex++);
hp.type = CONSTANT_COLOR;
hp.scrX = eyePath->scrX;
hp.scrY = eyePath->scrY;
// if (scene->infiniteLight)
// hp.throughput = scene->infiniteLight->Le(
// eyePath->ray.d) * eyePath->throughput;
// else
// hp.throughput = Spectrum();
if (ss->infiniteLight || ss->sunLight || ss->skyLight) {
// hp.throughput = scene->infiniteLight->Le(eyePath->ray.d) * eyePath->throughput;
if (ss->infiniteLight)
ss->InfiniteLight_Le(&hp.throughput, &eyePath->ray.d, ss->infiniteLight,
ss->infiniteLightMap);
if (ss->sunLight)
ss->SunLight_Le(&hp.throughput, &eyePath->ray.d, ss->sunLight);
if (ss->skyLight)
ss->SkyLight_Le(&hp.throughput, &eyePath->ray.d, ss->skyLight);
hp.throughput *= eyePath->throughput;
} else
hp.throughput = Spectrum();
// Free the eye path
//ihp.accumPhotonCount = 0;
//ihp.accumReflectedFlux = Spectrum();
//ihp.photonCount = 0;
//hp.reflectedFlux = Spectrum();
eyePath->done = true;
//--todoEyePathCount;
} else {
// Something was hit
Point hitPoint;
Spectrum surfaceColor;
Normal N, shadeN;
if (engine->GetHitPointInformation(ss, &eyePath->ray, rayHit, hitPoint, surfaceColor,
N, shadeN))
continue;
// Get the material
const unsigned int currentTriangleIndex = rayHit->index;
const unsigned int currentMeshIndex = ss->meshIDs[currentTriangleIndex];
const uint materialIndex = ss->meshMats[currentMeshIndex];
POINTERFREESCENE::Material *hitPointMat = &ss->materials[materialIndex];
uint matType = hitPointMat->type;
if (matType == MAT_AREALIGHT) {
// Add an hit point
//HitPointInfo &hp = *(engine->GetHitPointInfo(
// eyePath->pixelIndex));
HitPointStaticInfo &hp = hitPointsStaticInfo_iterationCopy[eyePath->sampleIndex];
hp.type = CONSTANT_COLOR;
hp.scrX = eyePath->scrX;
hp.scrY = eyePath->scrY;
//ihp.accumPhotonCount = 0;
//ihp.accumReflectedFlux = Spectrum();
//ihp.photonCount = 0;
//hp.reflectedFlux = Spectrum();
Vector md = -eyePath->ray.d;
ss->AreaLight_Le(&hitPointMat->param.areaLight, &md, &N,
&hp.throughput);
hp.throughput *= eyePath->throughput;
// Free the eye path
eyePath->done = true;
//--todoEyePathCount;
} else {
//.........这里部分代码省略.........
示例13: switch
void NativeFilm::UpdateScreenBuffer() {
switch (toneMapParams->GetType()) {
case TONEMAP_LINEAR: {
const LinearToneMapParams &tm = (LinearToneMapParams &)(*toneMapParams);
const SamplePixel *sp = sampleFrameBuffer->GetPixels();
Pixel *p = frameBuffer->GetPixels();
const unsigned int pixelCount = width * height;
const float perScreenNormalizationFactor = tm.scale / (float)statsTotalSampleCount;
for (unsigned int i = 0; i < pixelCount; ++i) {
const float weight = sp[i].weight;
if (weight > 0.f) {
if (usePerScreenNormalization) {
p[i].r = Radiance2PixelFloat(sp[i].radiance.r * perScreenNormalizationFactor);
p[i].g = Radiance2PixelFloat(sp[i].radiance.g * perScreenNormalizationFactor);
p[i].b = Radiance2PixelFloat(sp[i].radiance.b * perScreenNormalizationFactor);
} else {
const float invWeight = tm.scale / weight;
p[i].r = Radiance2PixelFloat(sp[i].radiance.r * invWeight);
p[i].g = Radiance2PixelFloat(sp[i].radiance.g * invWeight);
p[i].b = Radiance2PixelFloat(sp[i].radiance.b * invWeight);
}
} else {
p[i].r = 0.f;
p[i].g = 0.f;
p[i].b = 0.f;
}
}
break;
}
case TONEMAP_REINHARD02: {
const Reinhard02ToneMapParams &tm = (Reinhard02ToneMapParams &)(*toneMapParams);
const float alpha = .1f;
const float preScale = tm.preScale;
const float postScale = tm.postScale;
const float burn = tm.burn;
const SamplePixel *sp = sampleFrameBuffer->GetPixels();
Pixel *p = frameBuffer->GetPixels();
const unsigned int pixelCount = width * height;
const float perScreenNormalizationFactor = 1.f / (float)statsTotalSampleCount;
// Use the frame buffer as temporary storage and calculate the average luminance
float Ywa = 0.f;
for (unsigned int i = 0; i < pixelCount; ++i) {
const float weight = sp[i].weight;
Spectrum rgb = sp[i].radiance;
if ((weight > 0.f) && !rgb.IsNaN()) {
if (usePerScreenNormalization)
rgb *= perScreenNormalizationFactor;
else
rgb /= weight;
// Convert to XYZ color space
p[i].r = 0.412453f * rgb.r + 0.357580f * rgb.g + 0.180423f * rgb.b;
p[i].g = 0.212671f * rgb.r + 0.715160f * rgb.g + 0.072169f * rgb.b;
p[i].b = 0.019334f * rgb.r + 0.119193f * rgb.g + 0.950227f * rgb.b;
Ywa += p[i].g;
} else {
p[i].r = 0.f;
p[i].g = 0.f;
p[i].b = 0.f;
}
}
Ywa /= pixelCount;
// Avoid division by zero
if (Ywa == 0.f)
Ywa = 1.f;
const float Yw = preScale * alpha * burn;
const float invY2 = 1.f / (Yw * Yw);
const float pScale = postScale * preScale * alpha / Ywa;
for (unsigned int i = 0; i < pixelCount; ++i) {
Spectrum xyz = p[i];
const float ys = xyz.g;
xyz *= pScale * (1.f + ys * invY2) / (1.f + ys);
// Convert back to RGB color space
p[i].r = 3.240479f * xyz.r - 1.537150f * xyz.g - 0.498535f * xyz.b;
p[i].g = -0.969256f * xyz.r + 1.875991f * xyz.g + 0.041556f * xyz.b;
p[i].b = 0.055648f * xyz.r - 0.204043f * xyz.g + 1.057311f * xyz.b;
// Gamma correction
p[i].r = Radiance2PixelFloat(p[i].r);
p[i].g = Radiance2PixelFloat(p[i].g);
p[i].b = Radiance2PixelFloat(p[i].b);
}
break;
}
default:
assert (false);
//.........这里部分代码省略.........
示例14: cummulative
void VolumePatIntegrator::EyeRandomWalk(const Scene *scene, const Ray &eyeRay,
VolumeVertexList& vertexList, RNG &rng) const {
// Do a random walk for the eye ray in the volume
Spectrum cummulative(1.f);
// Find the intersection between the eye ray and the volume
VolumeRegion *vr = scene->volumeRegion;
float t0, t1;
if (!vr || !vr->IntersectP(eyeRay, &t0, &t1) || (t1-t0) == 0.f || t0 < 0.f) {
return;
}
// Find the intersection point between the sampled light ray and the volume
RayDifferential ray(eyeRay);
Point p = ray(t0), pPrev;
uint64_t bounces = 0;
while(vr->WorldBound().Inside(p)) {
Vector wi = -ray.d;
const Spectrum sigma_a = vr->Sigma_a(p, wi, eyeRay.time);
const Spectrum sigma_s = vr->Sigma_s(p, wi, eyeRay.time);
const Spectrum STER = vr->STER(p, wi, eyeRay.time);
// Construct and add the _eyeVertex_ to the _vertexList_
VolumeVertex eyeVertex(p, wi, sigma_a, sigma_s, cummulative, 1.0);
vertexList.push_back(eyeVertex);
// Sample the direction of the next event
float directionPdf = 1.f;
Vector wo;
if(STER.y() > rng.RandomFloat()) {
// Change the ray direction due to a scattering event at _p_
if(!vr->SampleDirection(p, wi, wo, &directionPdf, rng)) {
break; // Direction error
}
// Account for the losses due to the scattering event at _p_
cummulative *= sigma_s * vr->p(p, wi, wo, ray.time);
} else {
// Account only for the trnsmittance between the previous and the
// next events becuse there is no direction change.
wo = ray.d;
}
// Sample the distance of the next event
ray = RayDifferential(p, wo, 0, INFINITY);
float tDist;
float distancePdf = 1.f;
Point Psample;
if(!vr->SampleDistance(ray, &tDist, Psample, &distancePdf, rng)) {
break; // The sampled point is outside the volume
}
// Account for the sampling Pdfs from sampling a direction and/or distance
const float pdf = distancePdf * directionPdf;
cummulative *= 1 / pdf;
// Update the events and account for the transmittance between the events
pPrev = p;
p = Psample;
const Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
const Spectrum stepTau = vr->tau(tauRay, .5f * stepSize, rng.RandomFloat());
const Spectrum TrPP = Exp(-stepTau);
cummulative *= TrPP;
// Possibly terminate ray marching if _cummulative_ is small
if (cummulative.y() < 1e-3) {
const float continueProb = .5f;
if (rng.RandomFloat() > continueProb) {
cummulative = 0.f;
break;
}
cummulative /= continueProb;
}
// Terminate if bounces are more than requested
bounces++;
if (bounces > maxDepth) {
break;
}
}
}
示例15: ray
Spectrum PathIntegrator::Li(const Scene *scene, const Renderer *renderer,
const RayDifferential &r, const Intersection &isect,
const Sample *sample, RNG &rng, MemoryArena &arena) const {
// Declare common path integration variables
Spectrum pathThroughput = 1., L = 0.;
RayDifferential ray(r);
bool specularBounce = false;
Intersection localIsect;
const Intersection *isectp = &isect;
for (int bounces = 0; ; ++bounces) {
// Possibly add emitted light at path vertex
if (bounces == 0 || specularBounce)
L += pathThroughput * isectp->Le(-ray.d);
// Sample illumination from lights to find path contribution
BSDF *bsdf = isectp->GetBSDF(ray, arena);
const Point &p = bsdf->dgShading.p;
const Normal &n = bsdf->dgShading.nn;
Vector wo = -ray.d;
if (bounces < SAMPLE_DEPTH)
L += pathThroughput *
UniformSampleOneLight(scene, renderer, arena, p, n, wo,
isectp->rayEpsilon, ray.time, bsdf, sample, rng,
lightNumOffset[bounces], &lightSampleOffsets[bounces],
&bsdfSampleOffsets[bounces]);
else
L += pathThroughput *
UniformSampleOneLight(scene, renderer, arena, p, n, wo,
isectp->rayEpsilon, ray.time, bsdf, sample, rng);
// Sample BSDF to get new path direction
// Get _outgoingBSDFSample_ for sampling new path direction
BSDFSample outgoingBSDFSample;
if (bounces < SAMPLE_DEPTH)
outgoingBSDFSample = BSDFSample(sample, pathSampleOffsets[bounces], 0);
else
outgoingBSDFSample = BSDFSample(rng);
Vector wi;
float pdf;
BxDFType flags;
Spectrum f = bsdf->Sample_f(wo, &wi, outgoingBSDFSample, &pdf,
BSDF_ALL, &flags);
if (f.IsBlack() || pdf == 0.)
break;
specularBounce = (flags & BSDF_SPECULAR) != 0;
pathThroughput *= f * AbsDot(wi, n) / pdf;
ray = RayDifferential(p, wi, ray, isectp->rayEpsilon);
// Possibly terminate the path
if (bounces > 3) {
float continueProbability = min(.5f, pathThroughput.y());
if (rng.RandomFloat() > continueProbability)
break;
pathThroughput /= continueProbability;
}
if (bounces == maxDepth)
break;
// Find next vertex of path
if (!scene->Intersect(ray, &localIsect)) {
if (specularBounce)
for (uint32_t i = 0; i < scene->lights.size(); ++i)
L += pathThroughput * scene->lights[i]->Le(ray);
break;
}
if (bounces > 1)
pathThroughput *= renderer->Transmittance(scene, ray, NULL, rng, arena);
isectp = &localIsect;
}
return L;
}