Commit a7b44f7
authored
feat: 2d UI revamp (#223)
* feat: Add renderling-ui crate with SDF-based 2D/UI renderer
Introduces a dedicated lightweight 2D rendering pipeline separate from
the 3D PBR pipeline. Uses SlabAllocator for GPU memory management with
Hybrid<UiDrawCallDescriptor> wrapper types (UiRect, UiCircle, UiEllipse)
following the Camera pattern for live GPU updates via set_*/with_* methods.
- SDF-based shape rendering (rect, rounded rect, circle, ellipse)
- Gradient fills (linear, radial), borders, anti-aliased edges
- 3 GPU bindings and 32-byte vertices (vs 13 bindings / ~160 bytes for 3D)
- Instanced quads with per-pixel SDF evaluation in fragment shader
- 6 visual regression tests with baseline images
* feat: Add atlas-based image rendering and fix viewport slab ordering
Add UiImage element type with atlas texture support, enabling
texture/image rendering in the 2D UI pipeline. Fix critical bug
where Atlas::new() was allocated before UiViewport on the slab,
causing the shader (which reads viewport at offset 0) to read
garbage data and render blank white output.
- Add UiImage wrapper with set/with builders for position, size,
tint, opacity, z-depth
- Replace dummy atlas with real Atlas integration (512x512x2)
- Add atlas_size field to UiViewport for correct UV mapping
- Fix shader to use viewport.atlas_size instead of viewport.size
for AtlasTextureDescriptor::uv() calls
- Add AtlasImage, AtlasTexture, UiImage to public re-exports
- Recompile shaders with updated UiViewport layout
- Add 2 image rendering tests (checkerboard + tint)
- Regenerate baseline images with correct rendering
- 8 renderling-ui tests + 101 renderling tests pass
* feat: Add text rendering via glyph_brush to renderling-ui
Port text rendering from the old UI module to the new lightweight
2D pipeline. Glyph rasterization uses glyph_brush to produce a
Luma8 cache image, which is converted to RGBA (white + alpha) and
uploaded to the atlas. Each visible glyph gets its own
AtlasTextureDescriptor pointing to its sub-region in the cache,
and a UiDrawCallDescriptor with element_type TextGlyph. The
existing fragment shader samples glyph coverage from the atlas
alpha channel and multiplies by fill_color.
- Add GlyphCache wrapping GlyphBrush with Luma8 cache image
- Add UiText handle type with set_z/set_opacity methods
- Add add_font(), add_text(), remove_text() to UiRenderer
- Add image as optional dep behind 'text' feature
- Re-export FontArc, FontId, Section, Text, UiText
- Add 2 text tests (plain text + text overlaid on a rounded rect)
- 10 renderling-ui tests + 101 renderling tests pass, 0 clippy warnings
* feat: Add lyon-based vector path rendering to renderling-ui
Port path/vector rendering from the old UI module to the new
lightweight 2D pipeline. Uses lyon for tessellation (fill and
stroke), de-indexes the triangle mesh, and writes UiVertex arrays
to the slab. The existing vertex shader's Path branch reads
pre-tessellated vertices from the slab, and the fragment shader
passes through the interpolated vertex color.
- Add UiPathBuilder with lyon path commands (begin, line_to,
quadratic/cubic bezier, add_rectangle, add_circle, etc.)
- Add fill() and stroke() methods for tessellation
- Add StrokeConfig (line width, cap, join) configuration
- Add UiPath handle type with z-depth and opacity setters
- Add path_builder() and remove_path() to UiRenderer
- Re-export StrokeConfig, UiPath, UiPathBuilder behind 'path' feature
- Add 3 path tests (filled triangle, stroked circle, mixed shapes)
- 13 renderling-ui tests + 101 renderling tests pass, 0 clippy warnings
* Remove old ui module from renderling, migrate example crate to renderling-ui
Delete the old renderling::ui module (cpu.rs, sdf.rs, text.rs, path.rs) and
its test baselines, remove the 'ui' feature flag and its optional deps
(glyph_brush, lyon, loading-bytes). Move loading-bytes to dev-dependencies
since it's still needed by wasm tests. Update the example crate to use
renderling-ui's UiRenderer, UiRect, UiText, and Section APIs instead of
the removed Ui type.
* Add image-filled paths, enable 4x MSAA by default, use typed slab Ids
Add UiPathBuilder::with_fill_image() for filling tessellated paths with
atlas textures. The shader samples the atlas when atlas_texture_id is set
on Path elements, using bounding-box-derived UVs. Add UiRenderer::upload_image()
to load images without creating a draw call.
Enable 4x MSAA by default (matching the old Ui behavior) and expose
with_msaa_sample_count() for configuration.
Replace raw u32 fields in UiDrawCallDescriptor with typed Ids:
atlas_texture_id becomes Id<AtlasTextureDescriptor> and
atlas_descriptor_id becomes Id<AtlasDescriptor>, using Id::NONE
as the unset sentinel. Update shader and CPU code accordingly.
* Add compositor for UI overlay, property getters for all element types
Add a Compositor to the renderling crate (compositor_vertex +
compositor_fragment shaders) that alpha-blends a source texture onto a
target framebuffer via a fullscreen quad. This fixes the black screen
when overlaying the UI renderer on a 3D stage with MSAA enabled: the UI
now renders to an intermediate texture, resolves MSAA there, and the
compositor blends it onto the final view preserving the scene beneath.
Add property getters to all UI element types (UiRect, UiCircle,
UiEllipse, UiImage, UiPath, UiText) so current values can be read back
— a prerequisite for the upcoming tweening/animation system.
Fix the example app's UI renderer clearing the 3D scene by removing the
erroneous .with_background_color(Vec4::ZERO) call, which was causing a
LoadOp::Clear that wiped the stage output.
* Fix alpha blending, entry points, and doc comments (PR review)
Address all 5 Copilot review comments from PR #223:
- Switch entire UI pipeline and compositor to premultiplied-alpha
blending. The fragment shader now premultiplies RGB by final alpha
before output, and both the UI pipeline and compositor use
PREMULTIPLIED_ALPHA_BLENDING. This fixes edge darkening on borders
and correct compositing of MSAA-resolved overlay textures.
- Fix border coverage in the fragment shader: compute straight-alpha
weighted blend of border and fill colors, then premultiply at the
end, avoiding the previous double-application of alpha at AA edges.
- Use explicit entry points (Some(linkage.entry_point)) in the UI
render pipeline for consistency with the rest of the codebase.
- Update clip_rect doc to note it is reserved for future use (not
currently enforced by the shader or renderer).
- Fix ui_vertex doc comment to only mention Path elements reading
from the slab (TextGlyph uses the standard quad generation path).1 parent 7d668ed commit a7b44f7
53 files changed
Lines changed: 3884 additions & 1701 deletions
File tree
- .github/workflows
- crates
- example
- src
- renderling-ui
- src
- renderling
- shaders
- src
- compositor
- linkage
- ui_slab
- ui
- cpu
- test_img
- ui2d
- ui
- path
- text
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
40 | 42 | | |
41 | 43 | | |
42 | 44 | | |
| |||
56 | 58 | | |
57 | 59 | | |
58 | 60 | | |
59 | | - | |
| 61 | + | |
60 | 62 | | |
61 | 63 | | |
62 | 64 | | |
| |||
65 | 67 | | |
66 | 68 | | |
67 | 69 | | |
68 | | - | |
69 | | - | |
70 | | - | |
| 70 | + | |
| 71 | + | |
71 | 72 | | |
| 73 | + | |
| 74 | + | |
72 | 75 | | |
73 | 76 | | |
74 | 77 | | |
75 | 78 | | |
76 | | - | |
| 79 | + | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
80 | 83 | | |
81 | 84 | | |
82 | 85 | | |
83 | | - | |
| 86 | + | |
84 | 87 | | |
85 | 88 | | |
86 | 89 | | |
| |||
99 | 102 | | |
100 | 103 | | |
101 | 104 | | |
102 | | - | |
| 105 | + | |
103 | 106 | | |
104 | 107 | | |
105 | 108 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | 21 | | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
78 | | - | |
| 78 | + | |
79 | 79 | | |
80 | 80 | | |
81 | | - | |
| 81 | + | |
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | | - | |
| 86 | + | |
| 87 | + | |
88 | 88 | | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
95 | 100 | | |
96 | | - | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
97 | 104 | | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
| 105 | + | |
102 | 106 | | |
103 | 107 | | |
104 | 108 | | |
105 | 109 | | |
106 | 110 | | |
107 | 111 | | |
108 | 112 | | |
109 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
110 | 117 | | |
111 | 118 | | |
112 | 119 | | |
| |||
160 | 167 | | |
161 | 168 | | |
162 | 169 | | |
163 | | - | |
| 170 | + | |
164 | 171 | | |
165 | 172 | | |
166 | | - | |
| 173 | + | |
167 | 174 | | |
168 | 175 | | |
169 | 176 | | |
| |||
199 | 206 | | |
200 | 207 | | |
201 | 208 | | |
202 | | - | |
| 209 | + | |
203 | 210 | | |
204 | 211 | | |
205 | 212 | | |
| |||
223 | 230 | | |
224 | 231 | | |
225 | 232 | | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
226 | 251 | | |
227 | 252 | | |
228 | 253 | | |
| |||
249 | 274 | | |
250 | 275 | | |
251 | 276 | | |
252 | | - | |
| 277 | + | |
| 278 | + | |
253 | 279 | | |
254 | 280 | | |
255 | 281 | | |
| |||
260 | 286 | | |
261 | 287 | | |
262 | 288 | | |
263 | | - | |
264 | 289 | | |
265 | 290 | | |
266 | 291 | | |
| |||
365 | 390 | | |
366 | 391 | | |
367 | 392 | | |
368 | | - | |
| 393 | + | |
369 | 394 | | |
370 | 395 | | |
371 | 396 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
0 commit comments