本文整理汇总了C++中BSDF::Sample方法的典型用法代码示例。如果您正苦于以下问题:C++ BSDF::Sample方法的具体用法?C++ BSDF::Sample怎么用?C++ BSDF::Sample使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BSDF
的用法示例。
在下文中一共展示了BSDF::Sample方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TraceEyePath
void LightCPURenderThread::TraceEyePath(Sampler *sampler, vector<SampleResult> *sampleResults) {
LightCPURenderEngine *engine = (LightCPURenderEngine *)renderEngine;
Scene *scene = engine->renderConfig->scene;
PerspectiveCamera *camera = scene->camera;
Film *film = threadFilm;
const u_int filmWidth = film->GetWidth();
const u_int filmHeight = film->GetHeight();
// Sample offsets
const u_int sampleBootSize = 11;
const u_int sampleEyeStepSize = 3;
Ray eyeRay;
const float screenX = min(sampler->GetSample(0) * filmWidth, (float)(filmWidth - 1));
const float screenY = min(sampler->GetSample(1) * filmHeight, (float)(filmHeight - 1));
camera->GenerateRay(screenX, screenY, &eyeRay,
sampler->GetSample(9), sampler->GetSample(10));
Spectrum radiance, eyePathThroughput(1.f, 1.f, 1.f);
int depth = 1;
while (depth <= engine->maxPathDepth) {
const u_int sampleOffset = sampleBootSize + (depth - 1) * sampleEyeStepSize;
RayHit eyeRayHit;
BSDF bsdf;
Spectrum connectionThroughput;
const bool somethingWasHit = scene->Intersect(device, false,
sampler->GetSample(sampleOffset), &eyeRay, &eyeRayHit, &bsdf, &connectionThroughput);
if (!somethingWasHit) {
// Nothing was hit, check infinite lights (including sun)
const Spectrum throughput = eyePathThroughput * connectionThroughput;
if (scene->envLight)
radiance += throughput * scene->envLight->GetRadiance(scene, -eyeRay.d);
if (scene->sunLight)
radiance += throughput * scene->sunLight->GetRadiance(scene, -eyeRay.d);
break;
} else {
// Something was hit, check if it is a light source
if (bsdf.IsLightSource())
radiance = eyePathThroughput * connectionThroughput * bsdf.GetEmittedRadiance(scene);
else {
// Check if it is a specular bounce
float bsdfPdf;
Vector sampledDir;
BSDFEvent event;
float cosSampleDir;
const Spectrum bsdfSample = bsdf.Sample(&sampledDir,
sampler->GetSample(sampleOffset + 1),
sampler->GetSample(sampleOffset + 2),
&bsdfPdf, &cosSampleDir, &event);
if (bsdfSample.Black() || ((depth == 1) && !(event & SPECULAR)))
break;
// If depth = 1 and it is a specular bounce, I continue to trace the
// eye path looking for a light source
eyePathThroughput *= connectionThroughput * bsdfSample * (cosSampleDir / bsdfPdf);
assert (!eyePathThroughput.IsNaN() && !eyePathThroughput.IsInf());
eyeRay = Ray(bsdf.hitPoint, sampledDir);
}
++depth;
}
}
// Add a sample even if it is black in order to avoid aliasing problems
// between sampled pixel and not sampled one (in PER_PIXEL_NORMALIZED buffer)
AddSampleResult(*sampleResults, PER_PIXEL_NORMALIZED,
screenX, screenY, radiance, (depth == 1) ? 1.f : 0.f);
}
示例2: RenderFunc
void PathCPURenderThread::RenderFunc() {
//SLG_LOG("[PathCPURenderEngine::" << threadIndex << "] Rendering thread started");
//--------------------------------------------------------------------------
// Initialization
//--------------------------------------------------------------------------
PathCPURenderEngine *engine = (PathCPURenderEngine *)renderEngine;
RandomGenerator *rndGen = new RandomGenerator(engine->seedBase + threadIndex);
Scene *scene = engine->renderConfig->scene;
PerspectiveCamera *camera = scene->camera;
Film * film = threadFilm;
const unsigned int filmWidth = film->GetWidth();
const unsigned int filmHeight = film->GetHeight();
// Setup the sampler
double metropolisSharedTotalLuminance, metropolisSharedSampleCount;
Sampler *sampler = engine->renderConfig->AllocSampler(rndGen, film,
&metropolisSharedTotalLuminance, &metropolisSharedSampleCount);
const unsigned int sampleBootSize = 4;
const unsigned int sampleStepSize = 9;
const unsigned int sampleSize =
sampleBootSize + // To generate eye ray
engine->maxPathDepth * sampleStepSize; // For each path vertex
sampler->RequestSamples(sampleSize);
//--------------------------------------------------------------------------
// Trace paths
//--------------------------------------------------------------------------
vector<SampleResult> sampleResults(1);
sampleResults[0].type = PER_PIXEL_NORMALIZED;
while (!boost::this_thread::interruption_requested()) {
float alpha = 1.f;
Ray eyeRay;
const float screenX = min(sampler->GetSample(0) * filmWidth, (float)(filmWidth - 1));
const float screenY = min(sampler->GetSample(1) * filmHeight, (float)(filmHeight - 1));
camera->GenerateRay(screenX, screenY, &eyeRay,
sampler->GetSample(2), sampler->GetSample(3));
int depth = 1;
bool lastSpecular = true;
float lastPdfW = 1.f;
Spectrum radiance;
Spectrum pathThrouput(1.f, 1.f, 1.f);
BSDF bsdf;
while (depth <= engine->maxPathDepth) {
const unsigned int sampleOffset = sampleBootSize + (depth - 1) * sampleStepSize;
RayHit eyeRayHit;
Spectrum connectionThroughput;
if (!scene->Intersect(device, false, sampler->GetSample(sampleOffset),
&eyeRay, &eyeRayHit, &bsdf, &connectionThroughput)) {
// Nothing was hit, look for infinitelight
DirectHitInfiniteLight(lastSpecular, pathThrouput * connectionThroughput, eyeRay.d,
lastPdfW, &radiance);
if (depth == 1)
alpha = 0.f;
break;
}
pathThrouput *= connectionThroughput;
// Something was hit
// Check if it is a light source
if (bsdf.IsLightSource()) {
DirectHitFiniteLight(lastSpecular, pathThrouput,
eyeRayHit.t, bsdf, lastPdfW, &radiance);
}
// Note: pass-through check is done inside SceneIntersect()
//------------------------------------------------------------------
// Direct light sampling
//------------------------------------------------------------------
DirectLightSampling(sampler->GetSample(sampleOffset + 1),
sampler->GetSample(sampleOffset + 2),
sampler->GetSample(sampleOffset + 3),
sampler->GetSample(sampleOffset + 4),
sampler->GetSample(sampleOffset + 5),
pathThrouput, bsdf, depth, &radiance);
//------------------------------------------------------------------
// Build the next vertex path ray
//------------------------------------------------------------------
Vector sampledDir;
BSDFEvent event;
float cosSampledDir;
const Spectrum bsdfSample = bsdf.Sample(&sampledDir,
sampler->GetSample(sampleOffset + 6),
sampler->GetSample(sampleOffset + 7),
&lastPdfW, &cosSampledDir, &event);
if (bsdfSample.Black())
break;
lastSpecular = ((event & SPECULAR) != 0);
//.........这里部分代码省略.........
示例3: RenderFunc
void LightCPURenderThread::RenderFunc() {
//SLG_LOG("[LightCPURenderThread::" << threadIndex << "] Rendering thread started");
//--------------------------------------------------------------------------
// Initialization
//--------------------------------------------------------------------------
LightCPURenderEngine *engine = (LightCPURenderEngine *)renderEngine;
RandomGenerator *rndGen = new RandomGenerator(engine->seedBase + threadIndex);
Scene *scene = engine->renderConfig->scene;
PerspectiveCamera *camera = scene->camera;
Film *film = threadFilm;
// Setup the sampler
double metropolisSharedTotalLuminance, metropolisSharedSampleCount;
Sampler *sampler = engine->renderConfig->AllocSampler(rndGen, film,
&metropolisSharedTotalLuminance, &metropolisSharedSampleCount);
const u_int sampleBootSize = 11;
const u_int sampleEyeStepSize = 4;
const u_int sampleLightStepSize = 5;
const u_int sampleSize =
sampleBootSize + // To generate the initial setup
engine->maxPathDepth * sampleEyeStepSize + // For each eye vertex
engine->maxPathDepth * sampleLightStepSize; // For each light vertex
sampler->RequestSamples(sampleSize);
//--------------------------------------------------------------------------
// Trace light paths
//--------------------------------------------------------------------------
vector<SampleResult> sampleResults;
while (!boost::this_thread::interruption_requested()) {
sampleResults.clear();
// Select one light source
float lightPickPdf;
const LightSource *light = scene->SampleAllLights(sampler->GetSample(2), &lightPickPdf);
// Initialize the light path
float lightEmitPdfW;
Ray nextEventRay;
Spectrum lightPathFlux = light->Emit(scene,
sampler->GetSample(3), sampler->GetSample(4), sampler->GetSample(5), sampler->GetSample(6),
&nextEventRay.o, &nextEventRay.d, &lightEmitPdfW);
if (lightPathFlux.Black()) {
sampler->NextSample(sampleResults);
continue;
}
lightPathFlux /= lightEmitPdfW * lightPickPdf;
assert (!lightPathFlux.IsNaN() && !lightPathFlux.IsInf());
// Sample a point on the camera lens
Point lensPoint;
if (!camera->SampleLens(sampler->GetSample(7), sampler->GetSample(8),
&lensPoint)) {
sampler->NextSample(sampleResults);
continue;
}
//----------------------------------------------------------------------
// I don't try to connect the light vertex directly with the eye
// because InfiniteLight::Emit() returns a point on the scene bounding
// sphere. Instead, I trace a ray from the camera like in BiDir.
// This is also a good why to test the Film Per-Pixel-Normalization and
// the Per-Screen-Normalization Buffers used by BiDir.
//----------------------------------------------------------------------
TraceEyePath(sampler, &sampleResults);
//----------------------------------------------------------------------
// Trace the light path
//----------------------------------------------------------------------
int depth = 1;
while (depth <= engine->maxPathDepth) {
const u_int sampleOffset = sampleBootSize + sampleEyeStepSize * engine->maxPathDepth +
(depth - 1) * sampleLightStepSize;
RayHit nextEventRayHit;
BSDF bsdf;
Spectrum connectionThroughput;
if (scene->Intersect(device, true, sampler->GetSample(sampleOffset),
&nextEventRay, &nextEventRayHit, &bsdf, &connectionThroughput)) {
// Something was hit
lightPathFlux *= connectionThroughput;
//--------------------------------------------------------------
// Try to connect the light path vertex with the eye
//--------------------------------------------------------------
ConnectToEye(sampler->GetSample(sampleOffset + 1),
bsdf, lensPoint, lightPathFlux, sampleResults);
if (depth >= engine->maxPathDepth)
break;
//--------------------------------------------------------------
// Build the next vertex path ray
//--------------------------------------------------------------
//.........这里部分代码省略.........
示例4: CollectResults
double PathHybridState::CollectResults(HybridRenderThread *renderThread) {
PathHybridRenderThread *thread = (PathHybridRenderThread *)renderThread;
PathHybridRenderEngine *renderEngine = (PathHybridRenderEngine *)thread->renderEngine;
Scene *scene = renderEngine->renderConfig->scene;
// Was a shadow ray traced ?
if (!directLightRadiance.Black()) {
// It was, check the result
const Ray *shadowRay;
const RayHit *shadowRayHit;
thread->PopRay(&shadowRay, &shadowRayHit);
BSDF bsdf;
// "(depth - 1 - 1)" is used because it is a shadow ray of previous path vertex
const unsigned int sampleOffset = sampleBootSize + (depth - 1 - 1) * sampleStepSize;
const bool miss = FinalizeRay(thread, shadowRay, shadowRayHit, &bsdf,
sampler->GetSample(sampleOffset + 5), &directLightRadiance);
if (miss) {
// The light source is visible, add the direct light sampling component
sampleResults[0].radiance += directLightRadiance;
}
}
// The next path vertex ray
const Ray *ray;
const RayHit *rayHit;
thread->PopRay(&ray, &rayHit);
BSDF bsdf;
const unsigned int sampleOffset = sampleBootSize + (depth - 1) * sampleStepSize;
const bool miss = FinalizeRay(thread, ray, rayHit, &bsdf, sampler->GetSample(sampleOffset),
&throuput);
if (miss) {
// Nothing was hit, look for infinitelight
DirectHitInfiniteLight(scene, ray->d);
if (depth == 1)
sampleResults[0].alpha = 0.f;
SplatSample(thread);
return 1.0;
} else {
// Something was hit
// Check if a light source was hit
if (bsdf.IsLightSource())
DirectHitFiniteLight(scene, rayHit->t, bsdf);
// Direct light sampling (initialize directLightRay)
DirectLightSampling(thread,
sampler->GetSample(sampleOffset + 1),
sampler->GetSample(sampleOffset + 2),
sampler->GetSample(sampleOffset + 3),
sampler->GetSample(sampleOffset + 4),
bsdf);
// Build the next vertex path ray
Vector sampledDir;
BSDFEvent event;
float cosSampledDir;
const Spectrum bsdfSample = bsdf.Sample(&sampledDir,
sampler->GetSample(sampleOffset + 6),
sampler->GetSample(sampleOffset + 7),
&lastPdfW, &cosSampledDir, &event);
if (bsdfSample.Black()) {
SplatSample(thread);
return 1.0;
} else {
lastSpecular = ((event & SPECULAR) != 0);
if ((depth >= renderEngine->rrDepth) && !lastSpecular) {
// Russian Roulette
const float prob = RenderEngine::RussianRouletteProb(bsdfSample, renderEngine->rrImportanceCap);
if (sampler->GetSample(sampleOffset + 8) < prob)
lastPdfW *= prob;
else {
SplatSample(thread);
return 1.0;
}
}
++depth;
// Check if I have reached the max. path depth
if (depth > renderEngine->maxPathDepth) {
SplatSample(thread);
return 1.0;
} else {
throuput *= bsdfSample * (cosSampledDir / lastPdfW);
assert (!throuput.IsNaN() && !throuput.IsInf());
nextPathVertexRay = Ray(bsdf.hitPoint.p, sampledDir);
}
}
}
return 0.0;
}