MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
UVFieldProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
7
8namespace MayaFlux::Buffers {
9
10/**
11 * @enum UVProjectionMode
12 * @brief Projection mode encoded in push constants for uv_field.comp
13 */
14enum class UVProjectionMode : uint8_t { ///< Backing type matches push constant uint in uv_field.comp
15 CARTESIAN = 0,
16 CYLINDRICAL = 1,
17 SPHERICAL = 2,
18 AXIAL_BLEND = 3
19};
20
21/**
22 * @class UVFieldProcessor
23 * @brief Compute pass that writes UV and optionally samples colour into a vertex SSBO
24 *
25 * Runs after NetworkGeometryProcessor has uploaded vertex data and before
26 * RenderProcessor draws. The vertex buffer (Usage::VERTEX, already carries
27 * eStorageBuffer) is bound as an SSBO at binding 0. A VKImage is bound as a
28 * combined image sampler at binding 1.
29 *
30 * The compute shader evaluates the chosen projection for every vertex in one
31 * dispatch, writing glm::vec2 UV at byte offset 28 and, when a texture source
32 * is present, glm::vec3 colour (sampled from the image at the computed UV) at
33 * byte offset 12.
34 *
35 * Push constant layout (uv_field.comp must match exactly, 80 bytes):
36 * offset 0 uint vertex_count
37 * offset 4 uint mode (UVProjectionMode)
38 * offset 8 uint write_colour (0 = UV only, 1 = also write sampled colour)
39 * offset 12 uint _pad
40 * offset 16 vec3 param_origin
41 * offset 28 float param_scale
42 * offset 32 vec3 param_axis
43 * offset 44 float param_aux (cylindrical height / triplanar blend)
44 *
45 * Usage:
46 * @code
47 * auto uv_proc = std::make_shared<UVFieldProcessor>();
48 * uv_proc->set_projection(UVProjectionMode::CYLINDRICAL);
49 * uv_proc->set_axis(glm::vec3(0.0F, 1.0F, 0.0F));
50 * uv_proc->set_origin(glm::vec3(0.0F));
51 * uv_proc->set_scale(1.0F);
52 * uv_proc->set_aux(2.0F); // cylinder height
53 * uv_proc->set_texture(vk_image); // optional: also writes colour
54 * chain->add_postprocessor(uv_proc, self);
55 * @endcode
56 */
57class MAYAFLUX_API UVFieldProcessor : public ComputeProcessor {
58public:
60 ~UVFieldProcessor() override = default;
61
62 // -------------------------------------------------------------------------
63 // Projection configuration
64 // -------------------------------------------------------------------------
65
66 /**
67 * @brief Set projection mode
68 * @param mode Projection algorithm applied in the shader
69 */
70 void set_projection(UVProjectionMode mode);
71
72 /**
73 * @brief Set world-space origin of the projection
74 * @param origin Anchor point for UV tile (planar/cylindrical/spherical)
75 */
76 void set_origin(const glm::vec3& origin);
77
78 /**
79 * @brief Set projection axis
80 * @param axis Normal for planar, rotation axis for cylindrical (normalised)
81 */
82 void set_axis(const glm::vec3& axis);
83
84 /**
85 * @brief Set UV scale
86 * @param scale Multiplier applied to UV output (larger = tighter tiling)
87 */
88 void set_scale(float scale);
89
90 /**
91 * @brief Set auxiliary projection parameter
92 * @param aux Cylinder height for CYLINDRICAL, blend exponent for TRIPLANAR
93 */
94 void set_aux(float aux);
95
96 // -------------------------------------------------------------------------
97 // Texture source
98 // -------------------------------------------------------------------------
99
100 /**
101 * @brief Bind a texture to sample colour from at computed UV coordinates
102 * @param image Source VKImage (must be in eShaderReadOnlyOptimal layout)
103 * @param config Sampler configuration (default: linear, repeat)
104 *
105 * When set, the shader also writes sampled colour to vertex colour (offset 12).
106 * When not set (or called with nullptr), only UV is written.
107 */
108 void set_texture(
109 std::shared_ptr<Core::VKImage> image,
110 const Portal::Graphics::SamplerConfig& config = {});
111
112 /**
113 * @brief Remove the texture source
114 *
115 * Reverts to UV-only mode (colour is not touched).
116 */
117 void clear_texture();
118
119 [[nodiscard]] std::string_view get_type_name() const { return "UVField"; }
120
121protected:
122 void on_attach(const std::shared_ptr<Buffer>& buffer) override;
123 void on_descriptors_created() override;
124 bool on_before_execute(
126 const std::shared_ptr<VKBuffer>& buffer) override;
127
128private:
129 // -------------------------------------------------------------------------
130 // Push constant mirror (kept in sync with shader layout)
131 // -------------------------------------------------------------------------
133 uint32_t vertex_count { 0 };
134 uint32_t mode { static_cast<uint32_t>(UVProjectionMode::CARTESIAN) };
135 uint32_t write_colour { 0 };
136 uint32_t _pad { 0 };
137 glm::vec3 param_origin { 0.0F };
138 float param_scale { 1.0F };
139 glm::vec3 param_axis { 0.0F, 0.0F, 1.0F };
140 float param_aux { 1.0F };
141 };
142 static_assert(sizeof(PushConstants) == 48,
143 "UVFieldProcessor::PushConstants layout mismatch — update uv_field.comp");
144
146 std::shared_ptr<Core::VKImage> m_texture;
147 vk::Sampler m_sampler;
149};
150
151} // namespace MayaFlux::Buffers
IO::ImageData image
Specialized ShaderProcessor for Compute Pipelines.
Portal::Graphics::SamplerConfig m_sampler_config
~UVFieldProcessor() override=default
std::shared_ptr< Core::VKImage > m_texture
Compute pass that writes UV and optionally samples colour into a vertex SSBO.
UVProjectionMode
Projection mode encoded in push constants for uv_field.comp.
@ CARTESIAN
Backing type matches push constant uint in uv_field.comp.