GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
1 / 1
100.0%
Branches:
-
-%
Functions:
-
-%

render/rt/camera_pass.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file camera_pass.h
3 /// @brief Pinhole cameras traced through the scene, every view in one dispatch: a shaded colour
4 /// image to look at, and each pixel's distance, normal, instance and albedo in buffers kernels,
5 /// CUDA or PyTorch read in place.
6 ///
7 /// CameraOutputs outputs{.colour = graph.Import(image, "colour"), .colourIndex = index};
8 /// camera.Add(graph, {.cameraToWorld = orbit.Transform(), .size = {640, 480}}, outputs);
9 #pragma once
10
11 #include "ernie/device/bindless.h"
12 #include "ernie/device/kernel.h"
13 #include "ernie/device/shader_compiler.h"
14 #include "ernie/graph/graph.h"
15 #include "ernie/shaders/sensors/camera.slang"
16 #include "ernie/shaders/spectral/spectrum.slang"
17
18 #include <glm/mat4x4.hpp>
19 #include <glm/vec2.hpp>
20 #include <glm/vec3.hpp>
21
22 #include <cstdint>
23 #include <optional>
24 #include <span>
25
26 namespace ernie {
27
28 /// @brief A pinhole camera in the scene's frame, in double: the pass makes it relative to the
29 /// render origin before it rounds to float.
30 struct PinholeView {
31 /// Camera to world; the camera looks down -z with +y up, as `glm::lookAtRH`'s inverse.
32 glm::dmat4 cameraToWorld{1.0};
33 /// Radians.
34 double verticalFov = 0.785398;
35 /// Pixels.
36 glm::uvec2 size{1};
37 };
38
39 /// @brief What a camera pass writes for a view; each left out is not written. Each written one is
40 /// replaced by its version after the pass.
41 struct CameraOutputs {
42 /// A storage image of the view's size, and its slot in the pass's heap.
43 std::optional<graph::Image> colour;
44 BindlessIndex colourIndex;
45 /// What `colour` shows where nothing is hit, as it is stored.
46 glm::vec3 background{0.0f};
47 /// A float a pixel, row by row: the hit distance in metres, infinity where nothing is hit.
48 std::optional<graph::Buffer> distances;
49 /// Three floats a pixel: the world normal, zero where nothing is hit.
50 std::optional<graph::Buffer> normals;
51 /// A uint32 a pixel: the instance row hit, or `kNoInstance`.
52 std::optional<graph::Buffer> instances;
53 /// `kBands` floats a pixel: the albedo hit, per spectral band; zero where nothing is hit.
54 std::optional<graph::Buffer> albedos;
55 /// Four bytes a pixel: the colour as RGBA8, as `colour` holds it.
56 std::optional<graph::Buffer> ldr;
57 };
58
59 /// @brief A view and what to write of it.
60 struct CameraView {
61 PinholeView view;
62 CameraOutputs outputs;
63 };
64
65 /// @brief Traces pinhole cameras through the scene the graph's `TraceScene` describes, one ray a
66 /// pixel, shading what each hits by its albedo and a headlight.
67 10 class CameraPass {
68 public:
69 static constexpr std::uint32_t kNoInstance = shaders::kNoInstance;
70 /// The spectral bands albedos carry: RGB mode's three, linear sRGB.
71 static constexpr std::uint32_t kBands = shaders::kBands;
72
73 CameraPass(DeviceContext& context, const ShaderCompiler& compiler, const BindlessHeap& heap);
74
75 /// @brief Adds the pass tracing every view in one dispatch, after the ray tracer's builds.
76 /// @throws std::invalid_argument when the graph has no `TraceScene`.
77 void Add(graph::Graph& graph, std::span<CameraView> views) const;
78 void Add(graph::Graph& graph, const PinholeView& view, CameraOutputs& outputs) const;
79
80 private:
81 ComputeKernel kernel_;
82 };
83
84 } // namespace ernie
85