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 "integrators/useprobes.h"
00028 #include "integrators/photonmap.h"
00029 #include "integrators/directlighting.h"
00030 #include "integrators/emission.h"
00031 #include "parallel.h"
00032 #include "scene.h"
00033 #include "progressreporter.h"
00034 #include "camera.h"
00035 #include "intersection.h"
00036 #include "paramset.h"
00037 #include "montecarlo.h"
00038 
00039 
00040 UseRadianceProbes *CreateRadianceProbesSurfaceIntegrator(const ParamSet ¶mSet) {
00041     string filename = paramSet.FindOneString("filename", "probes.out");
00042     return new UseRadianceProbes(filename);
00043 }
00044 
00045 
00046 UseRadianceProbes::UseRadianceProbes(const string &filename) {
00047     lightSampleOffsets = NULL;
00048     bsdfSampleOffsets = NULL;
00049     
00050     FILE *f = fopen(filename.c_str(), "r");
00051     if (f) {
00052         if (fscanf(f, "%d %d %d", &lmax, &includeDirectInProbes,
00053                    &includeIndirectInProbes) != 3 ||
00054             fscanf(f, "%d %d %d", &nProbes[0], &nProbes[1], &nProbes[2]) != 3 ||
00055             fscanf(f, "%f %f %f %f %f %f", &bbox.pMin.x, &bbox.pMin.y, &bbox.pMin.z,
00056                 &bbox.pMax.x, &bbox.pMax.y, &bbox.pMax.z) != 6)
00057             Severe("Error reading data from radiance probe file \"%s\"", filename.c_str());
00058     
00059         c_in = new Spectrum[SHTerms(lmax) * nProbes[0] * nProbes[1] * nProbes[2]];
00060         int offset = 0;
00061         for (int i = 0; i < nProbes[0] * nProbes[1] * nProbes[2]; ++i) {
00062             for (int j = 0; j < SHTerms(lmax); ++j)
00063                 if (!c_in[offset++].Read(f))
00064                     Severe("Error reading data from radiance probe file \"%s\"",
00065                         filename.c_str());
00066         }
00067         fclose(f);
00068     }
00069     else
00070         Error("Unable to read saved radiance volume values from file \"%s\"",
00071               filename.c_str());
00072 }
00073 
00074 
00075 UseRadianceProbes::~UseRadianceProbes() {
00076     delete[] lightSampleOffsets;
00077     delete[] bsdfSampleOffsets;
00078     delete[] c_in;
00079 }
00080 
00081 
00082 void UseRadianceProbes::RequestSamples(Sampler *sampler, Sample *sample, const Scene *scene) {
00083     
00084     uint32_t nLights = scene->lights.size();
00085     lightSampleOffsets = new LightSampleOffsets[nLights];
00086     bsdfSampleOffsets = new BSDFSampleOffsets[nLights];
00087     for (uint32_t i = 0; i < nLights; ++i) {
00088         const Light *light = scene->lights[i];
00089         int nSamples = light->nSamples;
00090         if (sampler) nSamples = sampler->RoundSize(nSamples);
00091         lightSampleOffsets[i] = LightSampleOffsets(nSamples, sample);
00092         bsdfSampleOffsets[i] = BSDFSampleOffsets(nSamples, sample);
00093     }
00094 }
00095 
00096 
00097 Spectrum UseRadianceProbes::Li(const Scene *scene, const Renderer *renderer,
00098             const RayDifferential &ray, const Intersection &isect,
00099             const Sample *sample, RNG &rng, MemoryArena &arena) const {
00100     Spectrum L(0.);
00101     Vector wo = -ray.d;
00102     
00103     L += isect.Le(wo);
00104 
00105     
00106     BSDF *bsdf = isect.GetBSDF(ray, arena);
00107     const Point &p = bsdf->dgShading.p;
00108     const Normal &n = bsdf->dgShading.nn;
00109     
00110     if (!includeDirectInProbes)
00111         L += UniformSampleAllLights(scene, renderer, arena, p, n,
00112                 wo, isect.rayEpsilon, ray.time, bsdf, sample, rng,
00113                 lightSampleOffsets, bsdfSampleOffsets);
00114 
00115     
00116 
00117     
00118     Vector offset = bbox.Offset(p);
00119     float voxx = (offset.x * nProbes[0]) - 0.5f;
00120     float voxy = (offset.y * nProbes[1]) - 0.5f;
00121     float voxz = (offset.z * nProbes[2]) - 0.5f;
00122     int vx = Floor2Int(voxx), vy = Floor2Int(voxy), vz = Floor2Int(voxz);
00123     float dx = voxx - vx, dy = voxy - vy, dz = voxz - vz;
00124 
00125     
00126     const Spectrum *b000 = c_inXYZ(lmax, vx,   vy,   vz);
00127     const Spectrum *b100 = c_inXYZ(lmax, vx+1, vy,   vz);
00128     const Spectrum *b010 = c_inXYZ(lmax, vx,   vy+1, vz);
00129     const Spectrum *b110 = c_inXYZ(lmax, vx+1, vy+1, vz);
00130     const Spectrum *b001 = c_inXYZ(lmax, vx,   vy,   vz+1);
00131     const Spectrum *b101 = c_inXYZ(lmax, vx+1, vy,   vz+1);
00132     const Spectrum *b011 = c_inXYZ(lmax, vx,   vy+1, vz+1);
00133     const Spectrum *b111 = c_inXYZ(lmax, vx+1, vy+1, vz+1);
00134 
00135     
00136     Spectrum *c_inp = arena.Alloc<Spectrum>(SHTerms(lmax));
00137     for (int i = 0; i < SHTerms(lmax); ++i) {
00138         
00139         Spectrum c00 = Lerp(dx, b000[i], b100[i]);
00140         Spectrum c10 = Lerp(dx, b010[i], b110[i]);
00141         Spectrum c01 = Lerp(dx, b001[i], b101[i]);
00142         Spectrum c11 = Lerp(dx, b011[i], b111[i]);
00143         Spectrum c0 = Lerp(dy, c00, c10);
00144         Spectrum c1 = Lerp(dy, c01, c11);
00145         c_inp[i] = Lerp(dz, c0, c1);
00146     }
00147 
00148     
00149     Spectrum *c_E = arena.Alloc<Spectrum>(SHTerms(lmax));
00150     SHConvolveCosTheta(lmax, c_inp, c_E);
00151 
00152     
00153     Spectrum rho = bsdf->rho(wo, rng, BSDF_ALL_REFLECTION);
00154     float *Ylm = ALLOCA(float, SHTerms(lmax));
00155     SHEvaluate(Vector(Faceforward(n, wo)), lmax, Ylm);
00156     Spectrum E = 0.f;
00157     for (int i = 0; i < SHTerms(lmax); ++i)
00158         E += c_E[i] * Ylm[i];
00159     L += rho * INV_PI * E.Clamp();
00160     return L;
00161 }
00162 
00163