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 #include "scene.h"
00026 #include "camera.h"
00027 #include "film.h"
00028 #include "sampling.h"
00029 #include "dynload.h"
00030 #include "volume.h"
00031
00032 void Scene::Render() {
00033
00034 Sample *sample = new Sample(surfaceIntegrator,
00035 volumeIntegrator,
00036 this);
00037
00038 surfaceIntegrator->Preprocess(this);
00039 volumeIntegrator->Preprocess(this);
00040
00041 ProgressReporter progress(sampler->TotalSamples(), "Rendering");
00042 while (sampler->GetNextSample(sample)) {
00043
00044 RayDifferential ray;
00045 float rayWeight = camera->GenerateRay(*sample, &ray);
00046
00047 ++(sample->imageX);
00048 float wt1 = camera->GenerateRay(*sample, &ray.rx);
00049 --(sample->imageX);
00050 ++(sample->imageY);
00051 float wt2 = camera->GenerateRay(*sample, &ray.ry);
00052 if (wt1 > 0 && wt2 > 0) ray.hasDifferentials = true;
00053 --(sample->imageY);
00054
00055 float alpha;
00056 Spectrum Ls = 0.f;
00057 if (rayWeight > 0.f)
00058 Ls = rayWeight * Li(ray, sample, &alpha);
00059
00060 if (Ls.IsNaN()) {
00061 Error("Not-a-number radiance value returned "
00062 "for image sample. Setting to black.");
00063 Ls = Spectrum(0.f);
00064 }
00065 else if (Ls.y() < -1e-5) {
00066 Error("Negative luminance value, %g, returned "
00067 "for image sample. Setting to black.", Ls.y());
00068 Ls = Spectrum(0.f);
00069 }
00070 else if (isinf(Ls.y())) {
00071 Error("Infinite luminance value returned "
00072 "for image sample. Setting to black.");
00073 Ls = Spectrum(0.f);
00074 }
00075
00076 camera->film->AddSample(*sample, ray, Ls, alpha);
00077
00078 BSDF::FreeAll();
00079
00080 static StatsCounter cameraRaysTraced("Camera", "Camera Rays Traced");
00081 ++cameraRaysTraced;
00082 progress.Update();
00083 }
00084
00085 delete sample;
00086 progress.Done();
00087 camera->film->WriteImage();
00088 }
00089 Scene::~Scene() {
00090 delete camera;
00091 delete sampler;
00092 delete surfaceIntegrator;
00093 delete volumeIntegrator;
00094 delete aggregate;
00095 delete volumeRegion;
00096 for (u_int i = 0; i < lights.size(); ++i)
00097 delete lights[i];
00098 }
00099 Scene::Scene(Camera *cam, SurfaceIntegrator *si,
00100 VolumeIntegrator *vi, Sampler *s,
00101 Primitive *accel, const vector<Light *> <s,
00102 VolumeRegion *vr) {
00103 lights = lts;
00104 aggregate = accel;
00105 camera = cam;
00106 sampler = s;
00107 surfaceIntegrator = si;
00108 volumeIntegrator = vi;
00109 volumeRegion = vr;
00110 if (lts.size() == 0)
00111 Warning("No light sources defined in scene; "
00112 "possibly rendering a black image.");
00113
00114 bound = aggregate->WorldBound();
00115 if (volumeRegion) bound = Union(bound, volumeRegion->WorldBound());
00116 }
00117 const BBox &Scene::WorldBound() const {
00118 return bound;
00119 }
00120 Spectrum Scene::Li(const RayDifferential &ray,
00121 const Sample *sample, float *alpha) const {
00122 Spectrum Lo = surfaceIntegrator->Li(this, ray, sample, alpha);
00123 Spectrum T = volumeIntegrator->Transmittance(this, ray, sample, alpha);
00124 Spectrum Lv = volumeIntegrator->Li(this, ray, sample, alpha);
00125 return T * Lo + Lv;
00126 }
00127 Spectrum Scene::Transmittance(const Ray &ray) const {
00128 return volumeIntegrator->Transmittance(this, ray, NULL, NULL);
00129 }