コード例 #1
0
ファイル: mlt.cpp プロジェクト: NickYang/pbrt-v3
void MLTIntegrator::Render(const Scene &scene) {
    ProfilePhase p(Prof::IntegratorRender);
    std::unique_ptr<Distribution1D> lightDistr =
        ComputeLightPowerDistribution(scene);
    // Generate bootstrap samples and compute normalization constant $b$
    int nBootstrapSamples = nBootstrap * (maxDepth + 1);
    std::vector<Float> bootstrapWeights(nBootstrapSamples, 0);
    if (scene.lights.size() > 0) {
        ProgressReporter progress(nBootstrap / 256,
                                  "Generating bootstrap paths");
        std::vector<MemoryArena> bootstrapThreadArenas(MaxThreadIndex());
        int chunkSize = Clamp(nBootstrap / 128, 1, 8192);
        ParallelFor([&](int i) {
            // Generate _i_th bootstrap sample
            MemoryArena &arena = bootstrapThreadArenas[threadIndex];
            for (int depth = 0; depth <= maxDepth; ++depth) {
                int rngIndex = i * (maxDepth + 1) + depth;
                MLTSampler sampler(mutationsPerPixel, rngIndex, sigma,
                                   largeStepProbability, nSampleStreams);
                Point2f pRaster;
                bootstrapWeights[rngIndex] =
                    L(scene, arena, lightDistr, sampler, depth, &pRaster).y();
                arena.Reset();
            }
            if ((i + 1 % 256) == 0) progress.Update();
        }, nBootstrap, chunkSize);
        progress.Done();
    }
    Distribution1D bootstrap(&bootstrapWeights[0], nBootstrapSamples);
    Float b = bootstrap.funcInt * (maxDepth + 1);

    // Run _nChains_ Markov chains in parallel
    Film &film = *camera->film;
    int64_t nTotalMutations =
        (int64_t)mutationsPerPixel * (int64_t)film.GetSampleBounds().Area();
    if (scene.lights.size() > 0) {
        StatTimer timer(&renderingTime);
        const int progressFrequency = 32768;
        ProgressReporter progress(nTotalMutations / progressFrequency,
                                  "Rendering");
        ParallelFor([&](int i) {
            int64_t nChainMutations =
                std::min((i + 1) * nTotalMutations / nChains, nTotalMutations) -
                i * nTotalMutations / nChains;
            // Follow {i}th Markov chain for _nChainMutations_
            MemoryArena arena;

            // Select initial state from the set of bootstrap samples
            RNG rng(i);
            int bootstrapIndex = bootstrap.SampleDiscrete(rng.UniformFloat());
            int depth = bootstrapIndex % (maxDepth + 1);

            // Initialize local variables for selected state
            MLTSampler sampler(mutationsPerPixel, bootstrapIndex, sigma,
                               largeStepProbability, nSampleStreams);
            Point2f pCurrent;
            Spectrum LCurrent =
                L(scene, arena, lightDistr, sampler, depth, &pCurrent);

            // Run the Markov chain for _nChainMutations_ steps
            for (int64_t j = 0; j < nChainMutations; ++j) {
                sampler.StartIteration();
                Point2f pProposed;
                Spectrum LProposed =
                    L(scene, arena, lightDistr, sampler, depth, &pProposed);
                // Compute acceptance probability for proposed sample
                Float accept = std::min((Float)1, LProposed.y() / LCurrent.y());

                // Splat both current and proposed samples to _film_
                if (accept > 0)
                    film.AddSplat(pProposed,
                                  LProposed * accept / LProposed.y());
                film.AddSplat(pCurrent, LCurrent * (1 - accept) / LCurrent.y());

                // Accept or reject the proposal
                if (rng.UniformFloat() < accept) {
                    pCurrent = pProposed;
                    LCurrent = LProposed;
                    sampler.Accept();
                    ++acceptedMutations;
                } else
                    sampler.Reject();
                ++totalMutations;
                if ((i * nTotalMutations / nChains + j) % progressFrequency ==
                    0)
                    progress.Update();
                arena.Reset();
            }
        }, nChains);
        progress.Done();
    }

    // Store final image computed with MLT
    camera->film->WriteImage(b / mutationsPerPixel);
}
コード例 #2
0
ファイル: mlt.cpp プロジェクト: LunaTheFinal/pbrt-v3
void MLTIntegrator::Render(const Scene &scene) {
    lightDistr =
        std::unique_ptr<Distribution1D>(ComputeLightSamplingCDF(scene));
    Film &film = *camera->film;
    // Generate bootstrap samples and compute $b$
    int bootstrapSamples = nBootstrap * (maxDepth + 1);
    std::unique_ptr<Float[]> bootstrapWeights(new Float[bootstrapSamples]);
    {
        ProgressReporter progress(nBootstrap, "Generating bootstrap paths");
        ParallelFor([&](int k) {
            // Generate a single bootstrap sample
            MemoryArena arena;
            for (int depth = 0; depth <= maxDepth; ++depth) {
                uint32_t uIndex = k * (maxDepth + 1) + depth;
                MLTSampler sampler(mutationsPerPixel, uIndex, sigma,
                                   largeStepProb);
                Point2f samplePos;
                bootstrapWeights[uIndex] =
                    L(scene, arena, sampler, depth, &samplePos).y();
            }
            progress.Update();
        }, nBootstrap);
        progress.Done();
    }
    Distribution1D bootstrap(bootstrapWeights.get(), bootstrapSamples);
    Float b = bootstrap.funcInt * (maxDepth + 1);

    // Run _nChains_ Markov Chains in parallel
    int64_t nTotalMutations =
        mutationsPerPixel * (int64_t)film.GetSampleBounds().Area();
    {
        StatTimer timer(&renderingTime);
        ProgressReporter progress(nTotalMutations / 100, "Rendering");
        ParallelFor([&](int k) {
            int64_t nChainMutations =
                std::min((k + 1) * nTotalMutations / nChains, nTotalMutations) -
                k * nTotalMutations / nChains;
            MemoryArena arena;
            std::unique_ptr<FilmTile> filmTile = film.GetFilmTile(Bounds2i(
                    film.croppedPixelBounds.pMin, film.croppedPixelBounds.pMin));
            // Select initial state from the set of bootstrap samples
            RNG rng(PCG32_DEFAULT_STATE, k);
            int bootstrapIndex = bootstrap.SampleDiscrete(rng.UniformFloat());
            int depth = bootstrapIndex % (maxDepth + 1);

            // Initialize local variables for selected state
            MLTSampler sampler(mutationsPerPixel, bootstrapIndex, sigma,
                               largeStepProb);
            Point2f currentPos, proposalPos;
            Spectrum currentL, proposalL;
            currentL = L(scene, arena, sampler, depth, &currentPos);

            // Run the Markov Chain for _nChainMutations_ steps
            for (int64_t i = 0; i != nChainMutations; ++i) {
                sampler.Begin();
                proposalL = L(scene, arena, sampler, depth, &proposalPos);
                // Compute the acceptance rate
                Float accept = std::min((Float)1, proposalL.y() / currentL.y());

                // Splat both current and proposed samples to _FilmTile_
                if (accept > 0)
                    filmTile->AddSplat(proposalPos,
                                       proposalL * accept / proposalL.y());
                filmTile->AddSplat(currentPos,
                                   currentL * (1 - accept) / currentL.y());

                // Accept or reject the proposal
                if (rng.UniformFloat() < accept) {
                    currentPos = proposalPos;
                    currentL = proposalL;
                    sampler.Accept();
                    ++acceptedMutations;
                } else {
                    sampler.Reject();
                }
                ++totalMutations;
                if (i % 100 == 0) progress.Update();
            }
            film.MergeFilmTile(std::move(filmTile));
        }, nChains);
        progress.Done();
    }
    film.WriteImage(b / mutationsPerPixel);
}