MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
InfluxProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Buffers {
6
7/**
8 * @class InfluxProcessor
9 * @brief VolumeFieldProcessor adding a shaped contribution into a field
10 * every cycle.
11 *
12 * The shape lives in the shader. Each concrete shader defines
13 * `float shape(vec3 p, float t)` over world position and elapsed time,
14 * includes volume_influx.glsl for the parameter block and the dispatch,
15 * and is selected by constructor argument. There is no mode word.
16 *
17 * Every cell adds shape * rate * time_step into the field. Nothing here
18 * removes anything: a chain with an influx stage and dissipation of
19 * exactly one grows without bound. Rate and the carrier's dissipation are
20 * a pair and want setting together.
21 *
22 * Elapsed time advances by time_step each cycle and is passed to the
23 * shape function, so a shader can vary its own geometry over time without
24 * the caller driving it. Time is the shared prefix's trailing word.
25 *
26 * Parameter offsets past the prefix, for feed():
27 * 32 center x, 36 center y, 40 center z, 44 radius,
28 * 48 rate, 52 time step, 56 falloff.
29 * The three bounds words at 64 are lattice-derived and not feedable.
30 */
31class MAYAFLUX_API InfluxProcessor : public VolumeFieldProcessor {
32public:
33 /**
34 * @struct InfluxParams
35 * @brief Push constant block the influx shaders receive.
36 *
37 * The leading eight words are the shared lattice prefix, written by
38 * the base. This declaration fixes the offsets of everything after.
39 */
40 struct InfluxParams {
41 uint32_t width;
42 uint32_t height;
43 uint32_t depth;
44 uint32_t pad0;
48 float elapsed;
49 float center_x;
50 float center_y;
51 float center_z;
52 float radius;
53 float rate;
54 float time_step;
55 float falloff;
56 float pad1;
60 float pad2;
61 };
62
63 static_assert(sizeof(InfluxParams) == 80);
64 static_assert(sizeof(InfluxParams) % 16 == 0);
65
66 /**
67 * @struct Spot
68 * @brief Where and how an influx adds, in one aggregate, for configure().
69 *
70 * A radius of zero means 8 percent of the lattice's smallest side, which
71 * is 0.16 for a lattice two units across.
72 */
73 struct Spot {
74 glm::vec3 center { 0.0F };
75 float radius { 0.0F };
76 float rate { 1.0F };
77 float time_step { 1.0F / 60.0F };
78 float falloff { 1.0F };
79 };
80
81 /**
82 * @brief Construct an influx stage.
83 * @param field Name of the field added into. Must be double-buffered.
84 * Stride may be sizeof(float) or sizeof(glm::vec4) depending on
85 * which shader is supplied.
86 * @param shader_path Path to a shader defining shape().
87 */
88 InfluxProcessor(std::string field, const std::string& shader_path);
89
90 /**
91 * @brief Construct an influx stage from a generated ShaderSpec.
92 * @param field Name of the field added into.
93 * @param spec ShaderSpec defining shape() and including the dispatch.
94 */
95 InfluxProcessor(std::string field, const Portal::Graphics::ShaderSpec& spec);
96
97 /**
98 * @brief Construct an influx stage already placed.
99 * @param field Name of the field added into.
100 * @param shader_path Path to a shader defining shape().
101 * @param spot Placement and strength.
102 */
103 InfluxProcessor(std::string field, const std::string& shader_path, const Spot& spot);
104
105 /**
106 * @brief Replace centre, radius, rate, time step and falloff at once.
107 * @param spot Settings. Unnamed fields take their defaults, not the current values.
108 */
109 void configure(const Spot& spot);
110
111 /**
112 * @brief Set the shape's world-space centre.
113 * @param center Position. Interpretation is the shader's.
114 */
115 void set_center(const glm::vec3& center);
116
117 /**
118 * @brief Set the shape's characteristic size.
119 * @param radius World units. Interpretation is the shader's.
120 */
121 void set_radius(float radius);
122
123 /**
124 * @brief Set the amount added per unit time at shape value one.
125 * @param rate Multiplier. Zero disables the stage without removing it.
126 */
127 void set_rate(float rate);
128
129 /**
130 * @brief Set the integration step. Match the advection stage's step.
131 * @param dt Seconds per cycle. Also the increment applied to elapsed time.
132 */
133 void set_time_step(float dt);
134
135 /**
136 * @brief Set the shape's edge softness.
137 * @param falloff Interpretation is the shader's. Zero is a hard edge
138 * in shaders that honour it.
139 */
140 void set_falloff(float falloff);
141
142 /**
143 * @brief Reset elapsed time to zero.
144 *
145 * Restarts any time-varying geometry the shader implements. Does not
146 * touch the field.
147 */
148 void restart();
149
150 /** @brief Seconds since construction or the last restart. */
151 [[nodiscard]] float get_elapsed() const { return m_elapsed; }
152
153 /** @brief Name of the field added into. */
154 [[nodiscard]] const std::string& get_field() const { return m_field; }
155
156 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
157
158protected:
159 /**
160 * @brief Raise the parameter block and write everything past the prefix.
161 */
162 void on_volume_ready() override;
163
164private:
165 /**
166 * @brief Build the binding table for the field name.
167 * @param field Field bound in both slots.
168 * @return Table binding the read slot and the write slot.
169 */
170 static std::vector<FieldBinding> make_bindings(const std::string& field);
171
172 /**
173 * @brief Write every parameter past the shared prefix.
174 */
175 void write_tail();
176
177 std::string m_field;
178
179 glm::vec3 m_center { 0.0F };
180 float m_radius { 0.15F };
181 bool m_auto_radius { false };
182 float m_rate { 1.0F };
183 float m_time_step { 1.0F / 60.0F };
184 float m_falloff { 1.0F };
185 float m_elapsed { 0.0F };
186};
187
188} // namespace MayaFlux::Buffers
float rate
float time_step
float radius
float falloff
std::shared_ptr< NetworkGeometryBuffer > buffer
float get_elapsed() const
Seconds since construction or the last restart.
const std::string & get_field() const
Name of the field added into.
VolumeFieldProcessor adding a shaped contribution into a field every cycle.
ComputeProcessor operating on named fields of a VolumeGridBuffer.
Push constant block the influx shaders receive.
Where and how an influx adds, in one aggregate, for configure().
Complete declarative description of a generated compute shader.