Пример #1
0
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;
}
Пример #2
0
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;
}