camera.cpp 3.5 KB
Newer Older
M
Matt Pharr 已提交
1 2 3 4 5 6 7 8 9 10 11 12
// pbrt is Copyright(c) 1998-2020 Matt Pharr, Wenzel Jakob, and Greg Humphreys.
// The pbrt source code is licensed under the Apache License, Version 2.0.
// SPDX: Apache-2.0

#include <pbrt/pbrt.h>

#include <pbrt/cameras.h>
#include <pbrt/options.h>
#include <pbrt/samplers.h>
#include <pbrt/util/bluenoise.h>
#include <pbrt/util/spectrum.h>
#include <pbrt/util/vecmath.h>
13
#include <pbrt/wavefront/integrator.h>
M
Matt Pharr 已提交
14 15 16

namespace pbrt {

17
// WavefrontPathIntegrator Camera Ray Methods
M
Matt Pharr 已提交
18 19
void WavefrontPathIntegrator::GenerateCameraRays(int y0, Transform movingFromCamera,
                                                 int sampleIndex) {
M
Matt Pharr 已提交
20
    // Define _generateRays_ lambda function
M
Matt Pharr 已提交
21
    auto generateRays = [=](auto sampler) {
22 23 24
        using ConcreteSampler = std::remove_reference_t<decltype(*sampler)>;
        if constexpr (!std::is_same_v<ConcreteSampler, MLTSampler> &&
                      !std::is_same_v<ConcreteSampler, DebugMLTSampler>)
M
Matt Pharr 已提交
25
            GenerateCameraRays<ConcreteSampler>(y0, movingFromCamera, sampleIndex);
M
Matt Pharr 已提交
26
    };
M
Matt Pharr 已提交
27

M
Matt Pharr 已提交
28 29 30
    sampler.DispatchCPU(generateRays);
}

31
template <typename ConcreteSampler>
M
Matt Pharr 已提交
32 33
void WavefrontPathIntegrator::GenerateCameraRays(int y0, Transform movingFromCamera,
                                                 int sampleIndex) {
34
    RayQueue *rayQueue = CurrentRayQueue(0);
35
    ParallelFor(
36
        "Generate camera rays", maxQueueSize, PBRT_CPU_GPU_LAMBDA(int pixelIndex) {
M
Matt Pharr 已提交
37 38
            // Enqueue camera ray and set pixel state for sample
            // Compute pixel coordinates for _pixelIndex_
39
            Bounds2i pixelBounds = film.PixelBounds();
M
Matt Pharr 已提交
40 41 42
            int xResolution = pixelBounds.pMax.x - pixelBounds.pMin.x;
            Point2i pPixel(pixelBounds.pMin.x + pixelIndex % xResolution,
                           y0 + pixelIndex / xResolution);
43 44
            pixelSampleState.pPixel[pixelIndex] = pPixel;

M
Matt Pharr 已提交
45
            // Test pixel coordinates against pixel bounds
46 47 48
            if (!InsideExclusive(pPixel, pixelBounds))
                return;

49
            // Initialize _Sampler_ for current pixel and sample
50
            ConcreteSampler pixelSampler = *sampler.Cast<ConcreteSampler>();
51 52
            pixelSampler.StartPixelSample(pPixel, sampleIndex, 0);

53
            // Sample wavelengths for ray path
54
            Float lu = pixelSampler.Get1D();
55 56 57 58
            if (GetOptions().disableWavelengthJitter)
                lu = 0.5f;
            SampledWavelengths lambda = film.SampleWavelengths(lu);

59
            // Generate _CameraSample_ and corresponding ray
60 61 62
            CameraSample cameraSample = GetCameraSample(pixelSampler, pPixel, filter);
            pstd::optional<CameraRay> cameraRay =
                camera.GenerateRay(cameraSample, lambda);
M
Matt Pharr 已提交
63 64
            if (cameraRay)
                cameraRay->ray = movingFromCamera(cameraRay->ray);
65 66 67 68

            // Initialize remainder of _PixelSampleState_ for ray
            pixelSampleState.L[pixelIndex] = SampledSpectrum(0.f);
            pixelSampleState.lambda[pixelIndex] = lambda;
M
Matt Pharr 已提交
69
            pixelSampleState.filterWeight[pixelIndex] = cameraSample.filterWeight;
70 71 72 73 74 75 76 77 78 79 80 81
            if (initializeVisibleSurface)
                pixelSampleState.visibleSurface[pixelIndex] = VisibleSurface();

            // Enqueue camera ray for intersection tests
            if (cameraRay) {
                rayQueue->PushCameraRay(cameraRay->ray, lambda, pixelIndex);
                pixelSampleState.cameraRayWeight[pixelIndex] = cameraRay->weight;
            } else
                pixelSampleState.cameraRayWeight[pixelIndex] = SampledSpectrum(0);
        });
}

M
Matt Pharr 已提交
82
}  // namespace pbrt