MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
AdvectProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6
7/**
8 * @class AdvectProcessor
9 * @brief VolumeFieldProcessor carrying one field along a velocity field
10 * by semi-Lagrangian backtrace.
11 *
12 * Each cell traces its centre backward through the velocity field by one
13 * time step, samples the carried field trilinearly at the arrival point,
14 * and writes the result to its own index in the carried field's write
15 * slot. Out-of-bounds arrivals clamp to the lattice edge.
16 *
17 * Constructed against two field names: the velocity field to trace
18 * through, and the field to carry. Naming the same field for both gives
19 * velocity self-advection, which is the first stage of an incompressible
20 * step. Naming a scalar carries density, temperature, or any other
21 * passively transported quantity.
22 *
23 * The carried field is registered for swap, so a subsequent stage reading
24 * that field observes the advected values.
25 *
26 * Usage:
27 * @code
28 * auto self = std::make_shared<AdvectProcessor>("velocity", "velocity", spec);
29 * auto carry = std::make_shared<AdvectProcessor>("velocity", "density", spec);
30 * chain->add_processor(self, volume);
31 * chain->add_processor(carry, volume);
32 * @endcode
33 */
34class MAYAFLUX_API AdvectProcessor : public VolumeFieldProcessor {
35public:
36 /**
37 * @struct AdvectParams
38 * @brief Push constant block the advection shader receives.
39 *
40 * The leading eight words are VolumeFieldProcessor::LatticeParams and
41 * are written by the base. This declaration exists to fix the offsets
42 * of the two fields past that prefix.
43 */
44 struct AdvectParams {
45 uint32_t width;
46 uint32_t height;
47 uint32_t depth;
48 uint32_t pad0;
52 float time_step;
54 float pad1;
55 float pad2;
56 float pad3;
57 };
58
59 /**
60 * @brief Construct an advection stage.
61 * @param velocity_field Name of the field traced through. Must have
62 * stride sizeof(glm::vec4).
63 * @param carried_field Name of the field transported. May equal
64 * @p velocity_field for self-advection. Must be double-buffered.
65 * @param shader_path Path to the compute shader implementing the trace.
66 */
68 std::string velocity_field,
69 std::string carried_field,
70 const std::string& shader_path);
71
72 /**
73 * @brief Construct an advection stage from a generated ShaderSpec.
74 * @param velocity_field Name of the field traced through.
75 * @param carried_field Name of the field transported.
76 * @param spec ShaderSpec implementing the trace.
77 */
79 std::string velocity_field,
80 std::string carried_field,
82
83 /**
84 * @brief Set the integration step passed to the shader each cycle.
85 * @param dt Seconds per step. Takes effect next cycle.
86 */
87 void set_time_step(float dt);
88
89 /**
90 * @brief Set the multiplicative decay applied to the carried value.
91 * @param dissipation Factor in [0, 1]. One preserves the quantity;
92 * values below one bleed it off over time, which suits smoke
93 * density and temperature. Takes effect next cycle.
94 */
95 void set_dissipation(float dissipation);
96
97 /** @brief Name of the field this stage traces through. */
98 [[nodiscard]] const std::string& get_velocity_field() const { return m_velocity_field; }
99
100 /** @brief Name of the field this stage transports. */
101 [[nodiscard]] const std::string& get_carried_field() const { return m_carried_field; }
102
103protected:
104 /**
105 * @brief Reserve the full parameter block and write the step and
106 * dissipation words.
107 */
108 void on_volume_ready() override;
109
110private:
111 /**
112 * @brief Write time step and dissipation past the shared prefix.
113 */
114 void write_tail();
115
116 /**
117 * @brief Build the binding table for the two field names.
118 * @param velocity_field Field traced through.
119 * @param carried_field Field transported.
120 * @return Table binding velocity read, carried read, and carried write.
121 */
122 static std::vector<FieldBinding> make_bindings(
123 const std::string& velocity_field, const std::string& carried_field);
124
125 std::string m_velocity_field;
126 std::string m_carried_field;
127
128 float m_time_step { 1.0F / 60.0F };
129 float m_dissipation { 1.0F };
130};
131
132} // namespace MayaFlux::Buffers
const std::string & get_velocity_field() const
Name of the field this stage traces through.
const std::string & get_carried_field() const
Name of the field this stage transports.
VolumeFieldProcessor carrying one field along a velocity field by semi-Lagrangian backtrace.
ComputeProcessor operating on named fields of a VolumeGridBuffer.
Push constant block the advection shader receives.
Complete declarative description of a generated compute shader.