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 #include "dynload.h"
00027 #include "context.h"
00028
00029 using namespace lux;
00030
00031
00032 void EmissionIntegrator::RequestSamples(Sample *sample,
00033 const Scene *scene) {
00034 tauSampleOffset = sample->Add1D(1);
00035 scatterSampleOffset = sample->Add1D(1);
00036 }
00037
00038 void EmissionIntegrator::Transmittance(const TsPack *tspack, const Scene *scene,
00039 const Ray &ray, const Sample *sample, float *alpha, SWCSpectrum *const L) const {
00040 if (!scene->volumeRegion)
00041 return;
00042
00043 float step = stepSize;
00044 float offset = sample->oneD[tauSampleOffset][0];
00045 SWCSpectrum tau =
00046 SWCSpectrum(tspack, scene->volumeRegion->Tau(ray, step, offset));
00047 *L *= Exp(-tau);
00048 }
00049 int EmissionIntegrator::Li(const TsPack *tspack, const Scene *scene,
00050 const RayDifferential &ray, const Sample *sample,
00051 SWCSpectrum *Lv, float *alpha) const {
00052 VolumeRegion *vr = scene->volumeRegion;
00053 float t0, t1;
00054 if (!vr || !vr->IntersectP(ray, &t0, &t1)) return 0.f;
00055
00056 *Lv = 0.f;
00057
00058 int N = Ceil2Int((t1-t0) / stepSize);
00059 float step = (t1 - t0) / N;
00060 SWCSpectrum Tr(1.f);
00061 Point p = ray(t0), pPrev;
00062 Vector w = -ray.d;
00063 t0 += sample->oneD[scatterSampleOffset][0] * step;
00064 for (int i = 0; i < N; ++i, t0 += step) {
00065
00066 pPrev = p;
00067 p = ray(t0);
00068 SWCSpectrum stepTau = SWCSpectrum(tspack, vr->Tau(Ray(pPrev, p - pPrev, 0, 1),
00069 .5f * stepSize, tspack->rng->floatValue()));
00070 Tr *= Exp(-stepTau);
00071
00072 if (Tr.Filter(tspack) < 1e-3f) {
00073 const float continueProb = .5f;
00074 if (tspack->rng->floatValue() > continueProb) break;
00075 Tr /= continueProb;
00076 }
00077
00078 *Lv += Tr * SWCSpectrum(tspack, vr->Lve(p, w));
00079 }
00080 *Lv *= step;
00081 return group;
00082 }
00083 VolumeIntegrator* EmissionIntegrator::CreateVolumeIntegrator(const ParamSet ¶ms) {
00084 float stepSize = params.FindOneFloat("stepsize", 1.f);
00085 return new EmissionIntegrator(stepSize, Context::getActiveLightGroup());
00086 }
00087
00088 static DynamicLoader::RegisterVolumeIntegrator<EmissionIntegrator> r("emission");