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/single.h"
00028 #include "scene.h"
00029 #include "paramset.h"
00030 #include "montecarlo.h"
00031
00032
00033 void SingleScatteringIntegrator::RequestSamples(Sampler *sampler, Sample *sample,
00034 const Scene *scene) {
00035 tauSampleOffset = sample->Add1D(1);
00036 scatterSampleOffset = sample->Add1D(1);
00037 }
00038
00039
00040 Spectrum SingleScatteringIntegrator::Transmittance(const Scene *scene,
00041 const Renderer *renderer, const RayDifferential &ray,
00042 const Sample *sample, RNG &rng, MemoryArena &arena) const {
00043 if (!scene->volumeRegion) return Spectrum(1.f);
00044 float step, offset;
00045 if (sample) {
00046 step = stepSize;
00047 offset = sample->oneD[tauSampleOffset][0];
00048 }
00049 else {
00050 step = 4.f * stepSize;
00051 offset = rng.RandomFloat();
00052 }
00053 Spectrum tau = scene->volumeRegion->tau(ray, step, offset);
00054 return Exp(-tau);
00055 }
00056
00057
00058 Spectrum SingleScatteringIntegrator::Li(const Scene *scene, const Renderer *renderer,
00059 const RayDifferential &ray, const Sample *sample, RNG &rng,
00060 Spectrum *T, MemoryArena &arena) const {
00061 VolumeRegion *vr = scene->volumeRegion;
00062 float t0, t1;
00063 if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) {
00064 *T = 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
00078
00079 float *lightNum = arena.Alloc<float>(nSamples);
00080 LDShuffleScrambled1D(1, nSamples, lightNum, rng);
00081 float *lightComp = arena.Alloc<float>(nSamples);
00082 LDShuffleScrambled1D(1, nSamples, lightComp, rng);
00083 float *lightPos = arena.Alloc<float>(2*nSamples);
00084 LDShuffleScrambled2D(1, nSamples, lightPos, rng);
00085 uint32_t sampOffset = 0;
00086 for (int i = 0; i < nSamples; ++i, t0 += step) {
00087
00088 pPrev = p;
00089 p = ray(t0);
00090 Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
00091 Spectrum stepTau = vr->tau(tauRay,
00092 .5f * stepSize, rng.RandomFloat());
00093 Tr *= Exp(-stepTau);
00094
00095
00096 if (Tr.y() < 1e-3) {
00097 const float continueProb = .5f;
00098 if (rng.RandomFloat() > continueProb) break;
00099 Tr /= continueProb;
00100 }
00101
00102
00103 Lv += Tr * vr->Lve(p, w, ray.time);
00104 Spectrum ss = vr->sigma_s(p, w, ray.time);
00105 if (!ss.IsBlack() && scene->lights.size() > 0) {
00106 int nLights = scene->lights.size();
00107 int ln = min(Floor2Int(lightNum[sampOffset] * nLights),
00108 nLights-1);
00109 Light *light = scene->lights[ln];
00110
00111 float pdf;
00112 VisibilityTester vis;
00113 Vector wo;
00114 LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
00115 lightPos[2*sampOffset+1]);
00116 Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
00117
00118 if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {
00119 Spectrum Ld = L * vis.Transmittance(scene, renderer, NULL, rng, arena);
00120 Lv += Tr * ss * vr->p(p, w, -wo, ray.time) * Ld * float(nLights) /
00121 pdf;
00122 }
00123 }
00124 ++sampOffset;
00125 }
00126 *T = Tr;
00127 return Lv * step;
00128 }
00129
00130
00131 SingleScatteringIntegrator *CreateSingleScatteringIntegrator(const ParamSet ¶ms) {
00132 float stepSize = params.FindOneFloat("stepsize", 1.f);
00133 return new SingleScatteringIntegrator(stepSize);
00134 }
00135
00136