Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2a6a9c8
feature: edge capacity
reromanlee Oct 4, 2026
6165e2e
feature: glyph packs
reromanlee Oct 4, 2026
ea8638d
feature: glyph lookups
reromanlee Oct 4, 2026
108be93
feature: text layout
reromanlee Oct 4, 2026
d935803
feature: text shape
reromanlee Oct 4, 2026
e61c60a
feature: symbol shape
reromanlee Oct 4, 2026
1a0a18e
feature: glyph components
reromanlee Oct 4, 2026
3a65593
feature: live pack edits
reromanlee Oct 4, 2026
38ac85c
feature: enum generator
reromanlee Oct 4, 2026
31d8dc4
feature: glyph editing
reromanlee Oct 4, 2026
db2196f
feature: glyph gallery
reromanlee Oct 4, 2026
a5b05dc
feature: glyph canvas
reromanlee Oct 4, 2026
963a6ea
feature: glyph details
reromanlee Oct 4, 2026
f78c5eb
feature: preview strip
reromanlee Oct 4, 2026
11bbd4d
feature: glyph inspectors
reromanlee Oct 4, 2026
8eeada0
polish: glyph metrics
reromanlee Oct 4, 2026
270a32f
create: default font
reromanlee Oct 4, 2026
c9a87b7
create: default symbols
reromanlee Oct 4, 2026
0d2869b
create: default glyphs
reromanlee Oct 4, 2026
37e5787
fix: in-memory packs
reromanlee Oct 4, 2026
400090e
create: inspector tests
reromanlee Oct 4, 2026
bfa289e
feature: gallery names
reromanlee Oct 4, 2026
7798c32
create: glyph scene
reromanlee Oct 4, 2026
7adb314
docs: text and symbols
reromanlee Oct 4, 2026
368088b
release: 2.1.0
reromanlee Oct 4, 2026
d35b8a0
fix: symbol factory test
reromanlee Oct 4, 2026
6fec868
polish: glyph scene
reromanlee Oct 4, 2026
3908152
docs: readme screenshots
reromanlee Oct 4, 2026
4d368f9
polish: editor screenshot
reromanlee Oct 4, 2026
1346cb6
polish: readme alt texts
reromanlee Oct 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ Continuous integration checks what a machine without a GPU can: the tests on the
1. Every check of the pull request passes: the tests on both Unity versions, and the WebGL, Android, iOS, macOS and Linux builds.
2. The whole test suite passes locally on a real GPU, on the oldest and the newest supported Unity.
3. The Stress Test sample runs smoothly in Windows, Android and WebGL builds, with frame, main thread and GPU times no worse than the previous release's.
4. Both scenes of the Shape Gallery sample and all three occlusion modes look right on the same devices, in the Built-in, URP and HDRP pipelines.
4. All three scenes of the Shape Gallery sample and all three occlusion modes look right on the same devices, in the Built-in, URP and HDRP pipelines.
5. In the Editor, under each pipeline, shape components draw in the Scene and Game views and in Prefab Mode, Draw As Gizmo shapes show only in the Scene view and in the Game view with Gizmos on, and clicking a wireframe never selects a hidden container.
6. A Profiler capture of an Android development build under load shows no new spikes in the `Wireframes.*` markers and no allocations in steady frames.
7. The timings in the test results artifacts are no worse than the previous release's.
8. `package.json` has the new version, `CHANGELOG.md` has its section, and the README and `Documentation/` describe the release; a major release also updates `Documentation/MIGRATION.md`.
6. In the Editor, with the package installed from git, the Glyph Editor shows the Default Font and Default Symbols read-only and duplicates them to Assets. On the copy, editing glyphs with the mouse, the keyboard and the details panel, undo, Generate Enum and Ctrl+S all work, and a text drawing with the copy follows every edit.
7. A Profiler capture of an Android development build under load shows no new spikes in the `Wireframes.*` markers and no allocations in steady frames.
8. The timings in the test results artifacts are no worse than the previous release's.
9. `package.json` has the new version, `CHANGELOG.md` has its section, and the README and `Documentation/` describe the release; a major release also updates `Documentation/MIGRATION.md`.

### After merging

Expand Down
Binary file added .github/glyph-editor-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/glyph-editor-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/glyphs.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/shapes.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/stress-test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed .github/wireframes-shapes.jpg
Binary file not shown.
Binary file removed .github/wireframes-stress-test.jpg
Binary file not shown.
25 changes: 16 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
# Wireframes (Unreleased)
# Wireframes 2.1.0

### What's new

1. Shape components draw a shape on their GameObject without code, in Edit Mode, Play Mode and builds: **Add Component > Wireframes** has one for every shape, such as `WireframeSphere` and `WireframeLine`.
2. Every change to a component shows up in the next render, made in the Inspector, by undo, animation or a script, and components do no work per frame.
3. Disabling a component or its GameObject hides its shape at no cost, and enabling it again allocates nothing.
4. Components share containers by occlusion, transparency and layer, so many of them draw in a few draw calls; a color with alpha below 1 draws transparent, and shapes draw on their GameObject's layer.
5. `DrawAsGizmo` draws a component's shape like a gizmo, in the Scene view and in the Game view while its Gizmos button is on, and builds leave it out.
6. Prefab Mode draws the components of the prefab being edited.
7. The Shape Gallery sample has a ComponentGallery scene made of components, and continuous integration builds it too.
8. A container without shapes skips its work before each render once its empty chunks are released.
2. Text and symbols are drawn with lines like every other shape, in 2D or 3D: `CreateText` and `CreateSymbol` create them in a container, and the `WireframeText` and `WireframeSymbol` components draw them on GameObjects.
3. The package's Default Glyphs draw the 95 printable ASCII characters with its Default Font, and 23 symbols, such as `DefaultSymbols.Warning`, with its Default Symbols.
4. The Glyph Editor, in **Window > Wireframes > Glyph Editor**, shows a glyph pack's characters and symbols in a gallery and edits each glyph's lines on a canvas or as exact X and Y values, with undo, while texts and symbols that draw with the pack follow each edit.
5. Every change to a component shows up in the next render, made in the Inspector, by undo, animation or a script, and components do no work per frame.
6. Text is aligned in its bounds, wraps at spaces or runs past them, has proportional or monospace characters with character and line spacing, and changes every frame without allocating through `SetText(ReadOnlySpan<char>)`.
7. Glyph packs, made with **Create > Wireframes > Glyph Pack**, are listed in a `WireframeGlyphs`, where the first pack that has a glyph draws it and the Inspector says which glyphs each pack overrides; code names symbols by the enum the Glyph Editor generates for each pack, so no lookup compares strings.
8. Disabling a component or its GameObject hides its shape at no cost, and enabling it again allocates nothing.
9. Components share containers by occlusion, transparency and layer, so many of them draw in a few draw calls; a color with alpha below 1 draws transparent, and shapes draw on their GameObject's layer.
10. `DrawAsGizmo` draws a component's shape like a gizmo, in the Scene view and in the Game view while its Gizmos button is on, and builds leave it out.
11. Prefab Mode draws the components of the prefab being edited.
12. A character or symbol the glyphs lack is drawn as `?`, with one warning for each.
13. The Shape Gallery sample names its shapes with text and has two more scenes, ComponentGallery, made of components, and TextAndSymbols, and continuous integration builds all three.
14. A container without shapes skips its work before each render once its empty chunks are released.

### Known issues

1. The Hierarchy's Scene visibility toggles don't hide components' wireframes, and the Gizmos menu's per-component checkboxes don't affect gizmo shapes.
2. Clicking a component's wireframe in the Scene view doesn't select its GameObject.
3. A script that changes a GameObject's layer moves its components' shapes to that layer on their next change.
4. Stereo rendering for XR is untested.
4. Text has no kerning, and the Default Font has only the printable ASCII characters.
5. Stereo rendering for XR is untested.

# Wireframes 2.0.0

Expand Down
24 changes: 21 additions & 3 deletions Documentation/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A shape attaches to Transforms, called bones, and moves, turns and scales with t
4. When a bone is destroyed, its shapes stay where they were drawn last and switch to world space.
5. Any Transform in a scene can be a bone. Nothing is added to it, and a prefab asset is refused with an `ArgumentException`.

### 17 shapes
### 19 shapes

| Shape | Usual Create method | Component | What it is |
|---|---|---|---|
Expand All @@ -33,8 +33,10 @@ A shape attaches to Transforms, called bones, and moves, turns and scales with t
| `IStadium` | `CreateStadium(centerA, centerB, radius)` | `WireframeStadium` | The flat outline of a capsule. |
| `IFrustum` | `CreateFrustum(endA, endB, radiusA, radiusB, sideCount)` | `WireframeFrustum` | Two regular polygons joined at every corner. Prisms and regular pyramids are frustums too. |
| `IPyramid` | `CreatePyramid(tip, baseCenter, baseSize)` | `WireframePyramid` | A rectangular base joined to a tip, like a camera's view without its near plane. |
| `IText` | `CreateText(position, rotation, text)` | `WireframeText` | Lines of text drawn with glyphs, aligned in bounds, proportional or monospace. |
| `ISymbol` | `CreateSymbol(position, rotation, symbol)` | `WireframeSymbol` | A symbol drawn with a glyph, named by a generated enum, such as `DefaultSymbols.Heart`. |

Every shape except lines and polylines also has a Create method on a bone, in its local space, one from a position and a rotation, and one without arguments for a white shape of unit size. Round shapes are drawn like Unity's gizmos, with rings and a few lines, from 3 to 1,024 segments per ring.
Every shape except lines and polylines also has a Create method on a bone, in its local space, one from a position and a rotation, and one without arguments for a white shape of unit size, or with only what it draws for texts and symbols. Round shapes are drawn like Unity's gizmos, with rings and a few lines, from 3 to 1,024 segments per ring.

### Shape components

Expand All @@ -50,13 +52,29 @@ Every shape has a component that draws it on its GameObject without any code, th

The Hierarchy's Scene visibility toggles don't hide components' wireframes, and the Gizmos menu's per-component checkboxes don't affect gizmo shapes.

### Text and symbols

Texts and symbols draw glyphs, made of lines like every other shape, so they stand anywhere in 2D or 3D, follow their bones and draw in the same containers.

1. The package's Default Glyphs draw the 95 printable ASCII characters with its Default Font, a single-line design, and 23 symbols with its Default Symbols, from arrows and checks to media buttons. Texts, symbols and new components use them unless given glyphs of their own.
2. Text is laid out in bounds: each line aligned left, center or right, the lines together top, middle or bottom, wrapped at spaces or left to run past the bounds, with character and line spacing in glyph boxes.
3. Characters are proportional, as wide as their lines, or monospace, a whole glyph box each.
4. `SetText(ReadOnlySpan<char>)` changes a text without allocating once its buffers fit, and a text keeps spare room, so most changes rewrite it in place.
5. A character or symbol the glyphs lack is drawn as `?`, with one warning for each.
6. Glyph packs hold characters, found by character, and symbols, found by a keyword. A glyph list puts packs in priority order, the first pack that has a glyph draws it, and its Inspector says which glyphs each pack overrides.
7. Code names symbols by an enum generated for each pack, whose members are their keywords' hashes, so no lookup compares strings.
8. The Glyph Editor shows a pack's glyphs in a gallery, with characters and symbols apart, and edits each glyph's strokes on a canvas with a grid, guides and snapping, or point by point with exact X and Y values, with undo. Texts and symbols drawing with the pack follow each edit at once.
9. Packs installed from a registry, git or a tarball are read-only, and the Glyph Editor duplicates them into the project to edit them.

Text has no kerning, and the Default Font covers ASCII only, so other characters need a pack of your own.

### Edits upload only what they change

A setter only records the change, and each edited shape is written once per frame however many of its properties changed. Only the changed ranges of the GPU buffers are uploaded, and moving bones uploads nothing but their matrices. Tests check that editing one shape among many uploads that shape alone.

### Steady frames allocate nothing

Frames that move bones, edit shapes, hide and show them, or change nothing allocate no managed memory, which tests enforce. Freed space is reused by the next shape of the same size and packed away once it fills half a buffer, and memory past the reserved capacity is given back as shapes are disposed.
Frames that move bones, edit shapes, rewrite texts, hide and show shapes, or change nothing allocate no managed memory, which tests enforce. Freed space is reused by the next shape of the same size and packed away once it fills half a buffer, and memory past the reserved capacity is given back as shapes are disposed.

### Containers

Expand Down
9 changes: 6 additions & 3 deletions Documentation/PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,16 @@ Up to 1.0, shapes were drawn by a `SkinnedMeshRenderer`. Before 2.0 replaced it
| Stadium | 34 | 34 |
| Frustum with n sides | 2n | 3n |
| Pyramid | 5 | 8 |
| Text | About 7 per character of the Default Font, rounded up to a power of two, at least 16 | About 5 per character of the Default Font |
| Symbol | 16 for most Default Symbols, and 32 or 64 for round ones | 1 to 34 for the Default Symbols |

### Tips

1. **Move bones rather than editing points.** A moving bone uploads its 48 bytes, while an edit rewrites every vertex of its shape.
2. **Reserve capacity for a known load** with `VertexCapacity` and `EdgeCapacity`, so buffers never grow mid-game.
3. **Hide shapes that come back** with `IsVisible` instead of disposing and creating them again.
4. **Lower `segmentCount`** for small or distant round shapes.
5. **Group shapes in few containers.** Each container has its own bone texture and draw calls.
6. **Use `Fade` where it helps,** since it doubles a container's draw calls.
7. **Hide whole containers that are off screen.** Shapes follow arbitrary Transforms, so their meshes have fixed bounds of ±1,000 km and are never frustum-culled.
5. **Rewrite a text with `SetText`** rather than creating another: it keeps room to grow, so most changes rewrite it in place without allocating.
6. **Group shapes in few containers.** Each container has its own bone texture and draw calls.
7. **Use `Fade` where it helps,** since it doubles a container's draw calls.
8. **Hide whole containers that are off screen.** Shapes follow arbitrary Transforms, so their meshes have fixed bounds of ±1,000 km and are never frustum-culled.
Loading
Loading