Spectrum VSDScatteringIntegrator::LiSingle(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; float t0, t1; vr->IntersectP(ray, &t0, &t1); // Do single scattering volume integration in _vr_ Spectrum Lv(0.); // Prepare for volume integration stepping int nSamples = Ceil2Int((t1-t0) / stepSize); float step = (t1 - t0) / nSamples; Spectrum Tr(1.f); Point p = ray(t0), pPrev; t0 += sample->oneD[scatterSampleOffset][0] * step; // Compute the emission from the voxels, not from the light sources for (int i = 0; i < nSamples; ++i, t0 += step) { // Advance to sample at _t0_ and update _T_ pPrev = p; p = ray(t0); Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth); Spectrum stepTau = vr->tau(tauRay, .5f * stepSize, rng.RandomFloat()); Tr *= Exp(-stepTau); // Possibly terminate ray marching if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; break; } Tr /= continueProb; } // Compute emission term at _p_ Lv += Tr * vr->PhotonDensity(p); } *T = Tr; return Lv * step; }
Spectrum VSDScatteringIntegrator::LiMultiple(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; float t0, t1; vr->IntersectP(ray, &t0, &t1); // Do multiple scattering volume integration in _vr_ Spectrum Lv(0.); // Prepare for random walk Spectrum Tr(1.f); Point p = ray(t0), pPrev = ray.o; // printf("%f %f %f, ", p.x, p.y, p.z); int steps = 0; // Sample the events in a random walk // BBox bb = vr->WorldBound(); // printf("%f %f %f & %f %f %f \n", // bb.pMin.x, bb.pMin.y, bb.pMin.z, bb.pMax.x, bb.pMax.y, bb.pMax.z); while(vr->WorldBound().Inside(p)) { //printf("%f %f %f %d \n", p.x, p.y, p.z, steps); steps++; // Sample direction Vector wi = -ray.d, wo; float pdfDirection = 0.f; if(!vr->SampleDirection(p, wi, wo, &pdfDirection, rng)) { // printf("return 1 \n"); return Lv; } Ray r(p, wo, 0); // Sample a distance float pdfDistance = 0.f; float tDist; Point pSample; if(!vr->SampleDistance(r, &tDist, pSample, &pdfDistance, rng)) { // printf("return 2 \n"); return Lv; } // Compute the transmittance pPrev = p; p = r(tDist); Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, r.time, r.depth); Spectrum stepTau = vr->tau(tauRay, .5f * stepSize, rng.RandomFloat()); Tr *= Exp(-stepTau); // Possibly terminate random walk if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; // printf("return 3 \n"); break; } Tr /= continueProb; } // Compute emission term at _p_ Lv += Tr * vr->PhotonDensity(p) / (pdfDistance * pdfDirection); } // printf("%f %f %f %d \n", p.x, p.y, p.z, steps); // printf("%d, ", steps); return Lv; }