MayaFlux 0.5.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 * @brief Construct an influx stage.
68 * @param field Name of the field added into. Must be double-buffered.
69 * Stride may be sizeof(float) or sizeof(glm::vec4) depending on
70 * which shader is supplied.
71 * @param shader_path Path to a shader defining shape().
72 */
73 InfluxProcessor(std::string field, const std::string& shader_path);
74
75 /**
76 * @brief Construct an influx stage from a generated ShaderSpec.
77 * @param field Name of the field added into.
78 * @param spec ShaderSpec defining shape() and including the dispatch.
79 */
80 InfluxProcessor(std::string field, const Portal::Graphics::ShaderSpec& spec);
81
82 /**
83 * @brief Set the shape's world-space centre.
84 * @param center Position. Interpretation is the shader's.
85 */
86 void set_center(const glm::vec3& center);
87
88 /**
89 * @brief Set the shape's characteristic size.
90 * @param radius World units. Interpretation is the shader's.
91 */
92 void set_radius(float radius);
93
94 /**
95 * @brief Set the amount added per unit time at shape value one.
96 * @param rate Multiplier. Zero disables the stage without removing it.
97 */
98 void set_rate(float rate);
99
100 /**
101 * @brief Set the integration step. Match the advection stage's step.
102 * @param dt Seconds per cycle. Also the increment applied to elapsed time.
103 */
104 void set_time_step(float dt);
105
106 /**
107 * @brief Set the shape's edge softness.
108 * @param falloff Interpretation is the shader's. Zero is a hard edge
109 * in shaders that honour it.
110 */
111 void set_falloff(float falloff);
112
113 /**
114 * @brief Reset elapsed time to zero.
115 *
116 * Restarts any time-varying geometry the shader implements. Does not
117 * touch the field.
118 */
119 void restart();
120
121 /** @brief Seconds since construction or the last restart. */
122 [[nodiscard]] float get_elapsed() const { return m_elapsed; }
123
124 /** @brief Name of the field added into. */
125 [[nodiscard]] const std::string& get_field() const { return m_field; }
126
127 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
128
129protected:
130 /**
131 * @brief Raise the parameter block and write everything past the prefix.
132 */
133 void on_volume_ready() override;
134
135private:
136 /**
137 * @brief Build the binding table for the field name.
138 * @param field Field bound in both slots.
139 * @return Table binding the read slot and the write slot.
140 */
141 static std::vector<FieldBinding> make_bindings(const std::string& field);
142
143 /**
144 * @brief Write every parameter past the shared prefix.
145 */
146 void write_tail();
147
148 std::string m_field;
149
150 glm::vec3 m_center { 0.0F };
151 float m_radius { 0.15F };
152 float m_rate { 1.0F };
153 float m_time_step { 1.0F / 60.0F };
154 float m_falloff { 1.0F };
155 float m_elapsed { 0.0F };
156};
157
158} // namespace MayaFlux::Buffers
float rate
float radius
float falloff
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.
Complete declarative description of a generated compute shader.