render/rt/ray_tracer.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | /// @file ray_tracer.h | ||
| 3 | /// @brief The ray tracer: the acceleration structures the scene is traced through, kept up to date | ||
| 4 | /// each frame, and the Slang modules its passes trace them with. | ||
| 5 | /// | ||
| 6 | /// const TraceScene& scene = graph.Board().Get<TraceScene>(); | ||
| 7 | /// graph.Add("Shade", graph::Kind::Compute, | ||
| 8 | /// [&](graph::PassBuilder& pass) { scene.Read(pass); ... }, | ||
| 9 | /// [&](graph::PassContext& pass) { kernel.Dispatch(..., {scene.parameters, ...}); }); | ||
| 10 | #pragma once | ||
| 11 | |||
| 12 | #include "ernie/device/shader_compiler.h" | ||
| 13 | #include "ernie/graph/graph.h" | ||
| 14 | #include "ernie/render/geometry.h" | ||
| 15 | #include "ernie/render/instances.h" | ||
| 16 | #include "ernie/render/rt/bottom_levels.h" | ||
| 17 | #include "ernie/render/rt/top_levels.h" | ||
| 18 | #include "ernie/render/transform_graph.h" | ||
| 19 | #include "ernie/shaders/rt/ray_tracer.slang" | ||
| 20 | |||
| 21 | #include <glm/vec3.hpp> | ||
| 22 | |||
| 23 | #include <cstdint> | ||
| 24 | #include <span> | ||
| 25 | |||
| 26 | namespace ernie { | ||
| 27 | |||
| 28 | /// @brief What a tracing kernel hands its `RayTracer`, as ray_tracer.slang defines it. | ||
| 29 | using TracerParameters = shaders::TracerParameters; | ||
| 30 | |||
| 31 | /// @brief What a frame's passes trace, left on the graph's blackboard by `RayTracer::AddBuild`. | ||
| 32 | struct TraceScene { | ||
| 33 | TracerParameters parameters; | ||
| 34 | graph::Acceleration top; | ||
| 35 | graph::Buffer records; | ||
| 36 | std::uint32_t instances = 0; | ||
| 37 | /// Each instance row's albedo, three linear RGB floats, and kernels' handle of them. | ||
| 38 | graph::Buffer colours; | ||
| 39 | shaders::BufferRef<float> colourBuffer; | ||
| 40 | /// The render origin the structures are relative to: rays start from points less it. | ||
| 41 | glm::dvec3 origin{0.0}; | ||
| 42 | |||
| 43 | /// @brief Declares a pass's reads of everything tracing touches. | ||
| 44 | 25 | void Read(graph::PassBuilder& pass) const { | |
| 45 | 25 | pass.Read(top); | |
| 46 | 25 | pass.ReadAddress(records); | |
| 47 | 25 | pass.ReadAddress(colours); | |
| 48 | 25 | } | |
| 49 | }; | ||
| 50 | |||
| 51 | /// @brief The scene's acceleration structures on a device with ray queries: a bottom level for | ||
| 52 | /// each geometry, built and compacted as it changes, and a top level over the instances rebuilt | ||
| 53 | /// every frame. | ||
| 54 | 15 | class RayTracer { | |
| 55 | public: | ||
| 56 | RayTracer(DeviceContext& context, Arenas& arenas, const ShaderCompiler& compiler, | ||
| 57 | const GeometryPool& geometry); | ||
| 58 | RayTracer(const RayTracer&) = delete; | ||
| 59 | RayTracer& operator=(const RayTracer&) = delete; | ||
| 60 | |||
| 61 | /// @return The modules, in import order, a tracing kernel compiles with before its own; it | ||
| 62 | /// then imports `ray_tracer`. | ||
| 63 | static std::span<const ShaderModule> Modules(); | ||
| 64 | |||
| 65 | /// @brief Adds the passes that bring the structures up to date with the frame's geometry | ||
| 66 | /// changes, after the transforms and the geometry's and instances' uploads, and puts a | ||
| 67 | /// `TraceScene` on the graph's blackboard. | ||
| 68 | void AddBuild(graph::Graph& graph, const GeometryPool::Changes& changes, | ||
| 69 | const TransformGraph& transforms, const InstanceTable& instances); | ||
| 70 | |||
| 71 | BottomLevels& Bottoms() { | ||
| 72 | 3 | return bottoms_; | |
| 73 | } | ||
| 74 | const TopLevels& Tops() const { | ||
| 75 | return tops_; | ||
| 76 | } | ||
| 77 | |||
| 78 | private: | ||
| 79 | const GeometryPool& geometry_; | ||
| 80 | BottomLevels bottoms_; | ||
| 81 | TopLevels tops_; | ||
| 82 | }; | ||
| 83 | |||
| 84 | } // namespace ernie | ||
| 85 |