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