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/emission.h"
00028 #include "paramset.h"
00029
00030
00031 void EmissionIntegrator::RequestSamples(Sampler *sampler, Sample *sample,
00032 const Scene *scene) {
00033 tauSampleOffset = sample->Add1D(1);
00034 scatterSampleOffset = sample->Add1D(1);
00035 }
00036
00037
00038 Spectrum EmissionIntegrator::Transmittance(const Scene *scene,
00039 const Renderer *renderer, const RayDifferential &ray,
00040 const Sample *sample, RNG &rng, MemoryArena &arena) const {
00041 if (!scene->volumeRegion) return Spectrum(1.f);
00042 float step, offset;
00043 if (sample) {
00044 step = stepSize;
00045 offset = sample->oneD[tauSampleOffset][0];
00046 }
00047 else {
00048 step = 4.f * stepSize;
00049 offset = rng.RandomFloat();
00050 }
00051 Spectrum tau = scene->volumeRegion->tau(ray, step, offset);
00052 return Exp(-tau);
00053 }
00054
00055
00056 Spectrum EmissionIntegrator::Li(const Scene *scene,
00057 const Renderer *renderer, const RayDifferential &ray,
00058 const Sample *sample, RNG &rng, Spectrum *T,
00059 MemoryArena &arena) const {
00060 VolumeRegion *vr = scene->volumeRegion;
00061 Assert(sample != NULL);
00062 float t0, t1;
00063 if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) {
00064 *T = Spectrum(1.f);
00065 return 0.f;
00066 }
00067
00068 Spectrum Lv(0.);
00069
00070
00071 int nSamples = Ceil2Int((t1-t0) / stepSize);
00072 float step = (t1 - t0) / nSamples;
00073 Spectrum Tr(1.f);
00074 Point p = ray(t0), pPrev;
00075 Vector w = -ray.d;
00076 t0 += sample->oneD[scatterSampleOffset][0] * step;
00077 for (int i = 0; i < nSamples; ++i, t0 += step) {
00078
00079 pPrev = p;
00080 p = ray(t0);
00081 Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
00082 Spectrum stepTau = vr->tau(tauRay,
00083 .5f * stepSize, rng.RandomFloat());
00084 Tr *= Exp(-stepTau);
00085
00086
00087 if (Tr.y() < 1e-3) {
00088 const float continueProb = .5f;
00089 if (rng.RandomFloat() > continueProb) break;
00090 Tr /= continueProb;
00091 }
00092
00093
00094 Lv += Tr * vr->Lve(p, w, ray.time);
00095 }
00096 *T = Tr;
00097 return Lv * step;
00098 }
00099
00100
00101 EmissionIntegrator *CreateEmissionVolumeIntegrator(const ParamSet ¶ms) {
00102 float stepSize = params.FindOneFloat("stepsize", 1.f);
00103 return new EmissionIntegrator(stepSize);
00104 }
00105
00106