MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BuoyancyProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6
7/**
8 * @class BuoyancyProcessor
9 * @brief VolumeFieldProcessor accumulating a Boussinesq body force into a
10 * velocity field from a temperature field and a density field.
11 *
12 * Each cell adds dt * (temperature_gain * (T - ambient) - density_gain * d)
13 * scaled by the direction vector into its own velocity, writing the write
14 * slot and swapping. No neighbourhood is read, so the stencil is local and
15 * the boundary needs no special case.
16 *
17 * The direction vector carries both axis and magnitude: passing
18 * (0, 9.81, 0) and unit gains is equivalent to passing (0, 1, 0) and gains
19 * of 9.81. Nothing in the stage assumes an up axis.
20 *
21 * Naming the same field for temperature and density is valid and gives a
22 * single-quantity buoyancy: set the gain for the unwanted term to zero.
23 * The stage does not require a distinct temperature field to exist.
24 *
25 * Placement is after advection and before divergence. Running it after the
26 * pressure solve injects divergence the solve has already removed.
27 */
28class MAYAFLUX_API BuoyancyProcessor : public VolumeFieldProcessor {
29public:
30 /**
31 * @struct BuoyancyParams
32 * @brief Push constant block the buoyancy shader receives.
33 *
34 * The leading eight words are the shared lattice prefix and are written
35 * by the base. This declaration exists to fix the offsets of the fields
36 * past that prefix.
37 */
39 uint32_t width;
40 uint32_t height;
41 uint32_t depth;
42 uint32_t pad0;
46 float time_step;
50 float ambient;
53 float pad1;
54 float pad2;
55 };
56
57 static_assert(sizeof(BuoyancyParams) % 16 == 0);
58
59 /**
60 * @brief Construct a buoyancy stage.
61 * @param temperature_field Name of the scalar field driving rise. Must
62 * have stride sizeof(float).
63 * @param density_field Name of the scalar field driving fall. Must have
64 * stride sizeof(float). May equal @p temperature_field.
65 * @param velocity_field Name of the field accumulated into. Must have
66 * stride sizeof(glm::vec4) and be double-buffered.
67 * @param direction Force axis and magnitude in world units.
68 * @param shader_path Path to the compute shader.
69 */
71 std::string temperature_field,
72 std::string density_field,
73 std::string velocity_field,
74 const glm::vec3& direction,
75 const std::string& shader_path);
76
77 /**
78 * @brief Construct a buoyancy stage from a generated ShaderSpec.
79 * @param temperature_field Name of the scalar field driving rise.
80 * @param density_field Name of the scalar field driving fall.
81 * @param velocity_field Name of the field accumulated into.
82 * @param direction Force axis and magnitude in world units.
83 * @param spec ShaderSpec implementing the accumulate.
84 */
86 std::string temperature_field,
87 std::string density_field,
88 std::string velocity_field,
89 const glm::vec3& direction,
91
92 /**
93 * @brief Set the integration step passed to the shader each cycle.
94 * @param dt Seconds per step. Match the advection stage's step.
95 */
96 void set_time_step(float dt);
97
98 /**
99 * @brief Set the force axis and magnitude.
100 * @param direction World-space vector. Not normalized.
101 */
102 void set_direction(const glm::vec3& direction);
103
104 /**
105 * @brief Set the temperature at which the rise term vanishes.
106 * @param ambient Reference temperature. Cells below it sink.
107 */
108 void set_ambient(float ambient);
109
110 /**
111 * @brief Set the coefficient on the temperature difference.
112 * @param gain Multiplier. Zero disables the rise term.
113 */
114 void set_temperature_gain(float gain);
115
116 /**
117 * @brief Set the coefficient on the density value.
118 * @param gain Multiplier. Zero disables the fall term.
119 */
120 void set_density_gain(float gain);
121
122 /** @brief Seconds per step. */
123 [[nodiscard]] float get_time_step() const { return m_time_step; }
124
125 /** @brief Force axis and magnitude. */
126 [[nodiscard]] const glm::vec3& get_direction() const { return m_direction; }
127
128 /** @brief Name of the field driving rise. */
129 [[nodiscard]] const std::string& get_temperature_field() const { return m_temperature_field; }
130
131 /** @brief Name of the field driving fall. */
132 [[nodiscard]] const std::string& get_density_field() const { return m_density_field; }
133
134 /** @brief Name of the field accumulated into. */
135 [[nodiscard]] const std::string& get_velocity_field() const { return m_velocity_field; }
136
137protected:
138 /**
139 * @brief Raise the parameter block and write the tail.
140 */
141 void on_volume_ready() override;
142
143private:
144 /**
145 * @brief Build the binding table for the three field names.
146 * @param temperature_field Field driving rise.
147 * @param density_field Field driving fall.
148 * @param velocity_field Field accumulated into, bound in both slots.
149 * @return Table binding both scalars read and both velocity slots.
150 */
151 static std::vector<FieldBinding> make_bindings(
152 const std::string& temperature_field,
153 const std::string& density_field,
154 const std::string& velocity_field);
155
156 /**
157 * @brief Write every parameter past the shared prefix.
158 */
159 void write_tail();
160
162 std::string m_density_field;
163 std::string m_velocity_field;
164
165 glm::vec3 m_direction { 0.0F, 1.0F, 0.0F };
166 float m_time_step { 1.0F / 60.0F };
167 float m_ambient { 0.0F };
168 float m_temperature_gain { 1.0F };
169 float m_density_gain { 0.0F };
170};
171
172} // namespace MayaFlux::Buffers
float ambient
const std::string & get_temperature_field() const
Name of the field driving rise.
float get_time_step() const
Seconds per step.
const glm::vec3 & get_direction() const
Force axis and magnitude.
const std::string & get_velocity_field() const
Name of the field accumulated into.
const std::string & get_density_field() const
Name of the field driving fall.
VolumeFieldProcessor accumulating a Boussinesq body force into a velocity field from a temperature fi...
ComputeProcessor operating on named fields of a VolumeGridBuffer.
Push constant block the buoyancy shader receives.
Complete declarative description of a generated compute shader.