00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdafx.h"
00027 #include "renderers/samplerrenderer.h"
00028 #include "scene.h"
00029 #include "film.h"
00030 #include "volume.h"
00031 #include "sampler.h"
00032 #include "integrator.h"
00033 #include "progressreporter.h"
00034 #include "camera.h"
00035 #include "intersection.h"
00036
00037
00038 void SamplerRendererTask::Run() {
00039 PBRT_STARTED_RENDERTASK(taskNum);
00040
00041 Sampler *sampler = mainSampler->GetSubSampler(taskNum, taskCount);
00042 if (!sampler)
00043 {
00044 reporter.Update();
00045 PBRT_FINISHED_RENDERTASK(taskNum);
00046 return;
00047 }
00048
00049
00050 MemoryArena arena;
00051 RNG rng(taskNum);
00052
00053
00054 int maxSamples = sampler->MaximumSampleCount();
00055 Sample *samples = origSample->Duplicate(maxSamples);
00056 RayDifferential *rays = new RayDifferential[maxSamples];
00057 Spectrum *Ls = new Spectrum[maxSamples];
00058 Spectrum *Ts = new Spectrum[maxSamples];
00059 Intersection *isects = new Intersection[maxSamples];
00060
00061
00062 int sampleCount;
00063 while ((sampleCount = sampler->GetMoreSamples(samples, rng)) > 0) {
00064
00065 for (int i = 0; i < sampleCount; ++i) {
00066
00067 PBRT_STARTED_GENERATING_CAMERA_RAY(&samples[i]);
00068 float rayWeight = camera->GenerateRayDifferential(samples[i], &rays[i]);
00069 rays[i].ScaleDifferentials(1.f / sqrtf(sampler->samplesPerPixel));
00070 PBRT_FINISHED_GENERATING_CAMERA_RAY(&samples[i], &rays[i], rayWeight);
00071
00072
00073 PBRT_STARTED_CAMERA_RAY_INTEGRATION(&rays[i], &samples[i]);
00074 if (rayWeight > 0.f)
00075 Ls[i] = rayWeight * renderer->Li(scene, rays[i], &samples[i], rng,
00076 arena, &isects[i], &Ts[i]);
00077 else {
00078 Ls[i] = 0.f;
00079 Ts[i] = 1.f;
00080 }
00081
00082
00083 if (Ls[i].HasNaNs()) {
00084 Error("Not-a-number radiance value returned "
00085 "for image sample. Setting to black.");
00086 Ls[i] = Spectrum(0.f);
00087 }
00088 else if (Ls[i].y() < -1e-5) {
00089 Error("Negative luminance value, %f, returned"
00090 "for image sample. Setting to black.", Ls[i].y());
00091 Ls[i] = Spectrum(0.f);
00092 }
00093 else if (isinf(Ls[i].y())) {
00094 Error("Infinite luminance value returned"
00095 "for image sample. Setting to black.");
00096 Ls[i] = Spectrum(0.f);
00097 }
00098 PBRT_FINISHED_CAMERA_RAY_INTEGRATION(&rays[i], &samples[i], &Ls[i]);
00099 }
00100
00101
00102 if (sampler->ReportResults(samples, rays, Ls, isects, sampleCount))
00103 {
00104 for (int i = 0; i < sampleCount; ++i)
00105 {
00106 PBRT_STARTED_ADDING_IMAGE_SAMPLE(&samples[i], &rays[i], &Ls[i], &Ts[i]);
00107 camera->film->AddSample(samples[i], Ls[i]);
00108 PBRT_FINISHED_ADDING_IMAGE_SAMPLE();
00109 }
00110 }
00111
00112
00113 arena.FreeAll();
00114 }
00115
00116
00117 camera->film->UpdateDisplay(sampler->xPixelStart,
00118 sampler->yPixelStart, sampler->xPixelEnd+1, sampler->yPixelEnd+1);
00119 delete sampler;
00120 delete[] samples;
00121 delete[] rays;
00122 delete[] Ls;
00123 delete[] Ts;
00124 delete[] isects;
00125 reporter.Update();
00126 PBRT_FINISHED_RENDERTASK(taskNum);
00127 }
00128
00129
00130
00131
00132 SamplerRenderer::SamplerRenderer(Sampler *s, Camera *c,
00133 SurfaceIntegrator *si, VolumeIntegrator *vi) {
00134 sampler = s;
00135 camera = c;
00136 surfaceIntegrator = si;
00137 volumeIntegrator = vi;
00138 }
00139
00140
00141 SamplerRenderer::~SamplerRenderer() {
00142 delete sampler;
00143 delete camera;
00144 delete surfaceIntegrator;
00145 delete volumeIntegrator;
00146 }
00147
00148
00149 void SamplerRenderer::Render(const Scene *scene) {
00150 PBRT_FINISHED_PARSING();
00151
00152 PBRT_STARTED_PREPROCESSING();
00153 surfaceIntegrator->Preprocess(scene, camera, this);
00154 volumeIntegrator->Preprocess(scene, camera, this);
00155 PBRT_FINISHED_PREPROCESSING();
00156 PBRT_STARTED_RENDERING();
00157
00158 Sample *sample = new Sample(sampler, surfaceIntegrator,
00159 volumeIntegrator, scene);
00160
00161
00162
00163
00164 int nPixels = camera->film->xResolution * camera->film->yResolution;
00165 int nTasks = max(32 * NumSystemCores(), nPixels / (16*16));
00166 nTasks = RoundUpPow2(nTasks);
00167 ProgressReporter reporter(nTasks, "Rendering");
00168 vector<Task *> renderTasks;
00169 for (int i = 0; i < nTasks; ++i)
00170 renderTasks.push_back(new SamplerRendererTask(scene, this, camera,
00171 reporter,
00172 sampler, sample, nTasks-1-i, nTasks));
00173 EnqueueTasks(renderTasks);
00174 WaitForAllTasks();
00175 for (uint32_t i = 0; i < renderTasks.size(); ++i)
00176 delete renderTasks[i];
00177 reporter.Done();
00178 PBRT_FINISHED_RENDERING();
00179
00180 delete sample;
00181 camera->film->WriteImage();
00182 }
00183
00184
00185 Spectrum SamplerRenderer::Li(const Scene *scene,
00186 const RayDifferential &ray, const Sample *sample, RNG &rng,
00187 MemoryArena &arena, Intersection *isect, Spectrum *T) const {
00188 Assert(ray.time == sample->time);
00189 Assert(!ray.HasNaNs());
00190
00191 Spectrum localT;
00192 if (!T) T = &localT;
00193 Intersection localIsect;
00194 if (!isect) isect = &localIsect;
00195 Spectrum Li = 0.f;
00196 if (scene->Intersect(ray, isect))
00197 Li = surfaceIntegrator->Li(scene, this, ray, *isect, sample,
00198 rng, arena);
00199 else {
00200
00201 for (uint32_t i = 0; i < scene->lights.size(); ++i)
00202 Li += scene->lights[i]->Le(ray);
00203 }
00204 Spectrum Lvi = volumeIntegrator->Li(scene, this, ray, sample, rng,
00205 T, arena);
00206 return *T * Li + Lvi;
00207 }
00208
00209
00210 Spectrum SamplerRenderer::Transmittance(const Scene *scene,
00211 const RayDifferential &ray, const Sample *sample, RNG &rng,
00212 MemoryArena &arena) const {
00213 return volumeIntegrator->Transmittance(scene, this, ray, sample,
00214 rng, arena);
00215 }
00216
00217