Skip to content

World text upright, in pixels, outlined and shadowed; closed camera paths (876-4/5/8, 889-4) - #896

Merged
paul-hammant merged 3 commits into
mainfrom
wip/text-and-closed-paths
Oct 31, 2026
Merged

paul-hammant merged 3 commits into
mainfrom
wip/text-and-closed-paths

Conversation

@paul-hammant

Copy link
Copy Markdown
Collaborator

Nic's answers to the #876 and #889 questions: the four items for one PR (876-4, 876-5, 876-8, 889-4). One PR for both, to save CI minutes.

World text (ae3d.worldtext, ae3d.hud, ae3d.shaders.lettering)

  • 876-4: hud.world_text_upright turns a label to the camera about the world's up only, so its lines stay level and its tops up.
  • 876-5: hud.world_text_pixels(h, on) sizes the runs after it in screen pixels. The scale is found at each draw from that draw's view, projection and the shown height of its frame: twice the point's clip w over the projection's vertical scale and the height. It holds per view, under an orthographic camera, and whatever the render scale. worldtext.instances now takes the view, the projection and the height; both renderers pass them.
  • 876-8: hud.world_text_outline and hud.world_text_shadow add runs under the text. The outline's edge is lowered by the HUD's text_outlined rule (with its limit, about 0.08 of the em); the shadow is moved down and right along the run's axes. The edge reaches the pixel shader as a flat int in 65536ths, so 0.5 is exactly 32768 and a plain run draws byte for byte as before.
  • 876-7: depth, pixels, outline and shadow are state, reset by the frame's clear.

Camera paths (ae3d.campath)

  • 889-4: set_closed(p, seconds) adds a segment from the last key back to the first. The Catmull-Rom tangents wrap round it, so a closed path that loops has no jump in position or velocity.

Verified (M6, Aether 0.841.0)

  • ./ci.sh: everything passed (8 skipped, as on main).
  • generate_shaders --check: current against glslang 16.6.0.
  • test_world_text: 65 checks on both backends, also with AE3D_MSL=1. The new frames agree between Vulkan and OpenGL. All 16 old frames are byte for byte main's.
  • test_worldtext: 54 checks on the CPU, with values worked by hand.
  • test_gpu_lettering: 35 checks, including the edge varying and the GLSL fixtures.
  • test_campath: closed-path values worked by hand, and C1 round the loop.
  • Negative controls:
    • The shader with the edge ignored fails the outline checks on both backends.
    • Unwrapped tangents fail four closed-path checks.

Nic's later items are issues only: #892 (far-text shimmer without mips), #893 (colours above 1), #894 (share the overlay's atlas on Vulkan) and #895 (retire the view writer, a camera component first).

Touches no motion code and no file of #891.

🤖 Generated with Claude Code

paul-hammant and others added 2 commits October 31, 2026 16:53
… segment (889-4)

set_closed(p, seconds) adds a segment that many seconds long from the last
key back to the first. The Catmull-Rom tangents wrap: the first key's
neighbour before it is the last, a period earlier, and the last's after it
the first, a period later. A closed path that loops goes round with no jump
in position or velocity; one that does not stops back at the first key.
Nic's answer to 889-4 on the #889 questions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…(876-4, 876-5, 876-8)

Nic's answers to the #876 questions:

- hud.world_text_upright turns a label to the camera about the world's up
  only (876-4).
- hud.world_text_pixels sizes the runs after it in screen pixels. The scale
  is found at each draw from that draw's view and projection and the shown
  height of its frame (a view's, or the window's, whatever the render
  scale), so it holds per view (876-5).
- hud.world_text_outline and world_text_shadow add runs under the text: the
  outline with its edge lowered by the HUD's text_outlined rule, the shadow
  moved down and right along the run's axes (876-8). The edge reaches the
  pixel shader as a flat int in 65536ths; 0.5 is exactly 32768, so a plain
  run's frames are byte for byte main's (all 16 of test_world_text's).
- Depth, pixels, outline and shadow are state in ae3d.worldtext, reset by
  the frame's clear (876-7's model).

worldtext.instances now takes the view, the projection and the shown height
in place of the camera's two axes; both renderers pass them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nings

ubuntu-latest became 26.04 (gcc 15) on 2026-10-31. gcc 15 warns
-Wstringop-overflow in six motion-heavy -O2 builds, which ci.sh counts
as failures; feat/anim-pipeline hits it too (#901). Pin the Linux
matrix back to the image every green run used, and print gcc's
'In function' / 'inlined from' lines with each warning so the cause
shows in the log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@paul-hammant
paul-hammant merged commit 85a8f77 into main Oct 31, 2026
10 checks passed
@paul-hammant
paul-hammant deleted the wip/text-and-closed-paths branch October 31, 2026 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant