00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "emission.h"
00025 #include "paramset.h"
00026
00027 using namespace lux;
00028
00029
00030 void EmissionIntegrator::RequestSamples(Sample *sample,
00031 const Scene *scene) {
00032 tauSampleOffset = sample->Add1D(1);
00033 scatterSampleOffset = sample->Add1D(1);
00034 }
00035 SWCSpectrum
00036 EmissionIntegrator::Transmittance(const Scene *scene,
00037 const Ray &ray, const Sample *sample,
00038 float *alpha) const {
00039 if (!scene->volumeRegion) return SWCSpectrum(1.f);
00040 float step = sample ? stepSize : 4.f * stepSize;
00041 float offset =
00042 sample ? sample->oneD[tauSampleOffset][0] :
00043 lux::random::floatValue();
00044 SWCSpectrum tau =
00045 scene->volumeRegion->Tau(ray, step, offset);
00046 return Exp(-tau);
00047 }
00048 SWCSpectrum EmissionIntegrator::Li(const Scene *scene,
00049 const RayDifferential &ray, const Sample *sample,
00050 float *alpha) const {
00051 VolumeRegion *vr = scene->volumeRegion;
00052 float t0, t1;
00053 if (!vr || !vr->IntersectP(ray, &t0, &t1)) return 0.f;
00054
00055 SWCSpectrum Lv(0.);
00056
00057 int N = Ceil2Int((t1-t0) / stepSize);
00058 float step = (t1 - t0) / N;
00059 SWCSpectrum Tr(1.f);
00060 Point p = ray(t0), pPrev;
00061 Vector w = -ray.d;
00062 if (sample)
00063 t0 += sample->oneD[scatterSampleOffset][0] * step;
00064 else
00065 t0 += lux::random::floatValue() * step;
00066 for (int i = 0; i < N; ++i, t0 += step) {
00067
00068 pPrev = p;
00069 p = ray(t0);
00070 SWCSpectrum stepTau = vr->Tau(Ray(pPrev, p - pPrev, 0, 1),
00071 .5f * stepSize, lux::random::floatValue());
00072 Tr *= Exp(-stepTau);
00073
00074 if (Tr.filter() < 1e-3) {
00075 const float continueProb = .5f;
00076 if (lux::random::floatValue() > continueProb) break;
00077 Tr /= continueProb;
00078 }
00079
00080 Lv += Tr * vr->Lve(p, w);
00081 }
00082 return Lv * step;
00083 }
00084 VolumeIntegrator* EmissionIntegrator::CreateVolumeIntegrator(const ParamSet ¶ms) {
00085 float stepSize = params.FindOneFloat("stepsize", 1.f);
00086 return new EmissionIntegrator(stepSize);
00087 }