Expand description
English | 简体中文
§unlit3d_examples
A windowed example with selectable scenes, presented through
unlit3d::winit::presenter. Its scenes are also drawn offscreen by
tests/gpu_suite.rs, which compares every frame against a stored snapshot, so
the crate is both the workspace’s example program and a rendering regression
check. The Android APK packages it as one of its two examples, the other
being unlit3dx_examples.
It is at an early stage along with the crates it uses, and it exercises parts of them that are still under construction.
§Scenes
The example’s scenes are the snapshot scenes the GPU tests used to draw in
crates/unlit3d/tests: every one of them is now a selectable scene, and
tests/gpu_suite.rs is the check that replaced those tests. The windowed loop
shows the scene the command line selected and lists every scene in a panel, so
one can be switched to at runtime. --list-scenes prints the table:
Scenes:
spin_cube the example's own scene: a textured cube with two panels
ui_only a rich egui panel, no mesh source and no camera
mesh_and_ui a cube with the rich egui panel over it, one pass
animated a grid of cubes filling, moving and recycling over eight frames
skinned a cube bent by a two-joint skin over six frames
morphed a cube blended by two morph targets over six frames
instanced_skinned_morph three cubes sharing one mesh, deformed per instance
lit one relief surface under directional, point, spot and quad lights
lit_clusters every light kind in a per-cell local-light-count heatmap
gltf a skinned fox and a morph-target cube playing their glTF clips
mesh_topologies every primitive topology, indexed and non-indexed
transparent translucent panes composited back to front over opaque cubes
custom_pipeline a caller-registered sky family and particle family
outline inverted-hull bands beside screen-space strokes
outline_msaa the outline scene on a four-sample targetEach scene reproduces exactly what its test froze: the same world, camera and
frame sequence, so the stored snapshots still verify it. mesh_topologies and
transparent are the exceptions: they are not ported from a test but
add the coverage the ported scenes lack — every primitive topology drawn both
indexed and non-indexed, and overlapping translucent draws whose composite
depends on both the z-sort and the blend state. gltf is the other exception:
it draws the glTF documents in unlit3d_asset_files/assets through
LitGltf, so the loader’s skinning and morph-target animation are checked
against real assets rather than the hand-written ones the unit tests use. The
example reaches those documents through
asset_bytes, the crate that embeds them, so the
binary carries the models it draws and needs no file at run time.
custom_pipeline is the third: it registers two families of its own rather than
drawing through the built-in lit one. A sky family reconstructs a view ray
from the frame’s camera, samples a procedurally generated cube map and blends a
gradient and a sun from a uniform block the example writes every frame; a
particle family takes its per-instance records from an ordinary world component
and animates each sprite from a clock the example advances. Neither mesh carries
a vertex attribute — the sky’s three vertices and each particle’s six come from
the vertex index — so the scene is what checks that a caller can own a pipeline,
its bind groups, its vertex layout and its instance stream, and still read the
frame’s camera. It is also the example’s longest animated scene, at eight frames
of an orbit.
outline is the fourth: it draws two kinds of line the library offers and lets
one picture argue for both. Three bodies wear an inverted-hull band — each is one
mesh drawn twice from one buffer, lit and then spread along its own normals with
its front faces culled — so the band is a width in world units and the bodies
standing further back wear a thinner one. Beside them a LineSource draws the
orbit, its ticks and a pair of armillary rings as screen-space strokes, a width
in physical pixels, so the rings keep one weight from the near side to the far
side. The ticks are opaque, the rings and the orbit are washes blended over the
frame, so a ring shows the body it passes in front of, two crossings deepen
where they share a pixel, and a body hides the ring half behind it. One frame
holds all of it because neither kind alone shows what the other is for. Two of
the five bodies carry no vertex normals at all and are lit through the
screen-space derivative fallback, so the one frame covers both normal paths —
the baked one the band needs and the derived one a mesh without a normal channel
falls back to.
The scene is declared twice: outline captures it on a single-sampled target,
outline_msaa on a four-sample one. The difference is only how an opaque stroke
is antialiased — cut at half its coverage on the single-sampled target, its edge
carried in the alpha on the multisampled one — so a frame that lost either path
still matches its own snapshot and fails the other.
Every scene is built with the same public unlit3d API any caller would use —
nothing in the example reaches into the crates’ internals.
§How it runs
The windowed path is the whole frame loop a windowed app needs. The renderer is
spawned once as a resource entity, a scene’s meshes and materials are allocated
through its mesh source, and every RedrawRequested acquires the swap chain’s
next image, renders the ECS world into it and presents it. A resize is handed to
the surface, which reconfigures the swap chain, and to the frame’s
FrameAttachments,
which rebuilds the depth-stencil and multisample attachments it holds at the
new size.
A scene that draws 3D content declares a baseline aspect — 960×720, the shape the ported scenes were captured at. The windowed path draws such a scene through the largest rectangle of that aspect the target fits, and hands the scene that rectangle’s own size, so every scene takes its camera aspect from the region it is actually drawn into. The target only ever adds bars around the picture: a wide window shows the same view a narrow one does, larger, rather than more of it, and nothing is ever stretched. The UI is drawn over the whole target rather than the letterboxed region, because a panel has no aspect of its own. The snapshot tests turn the letterbox off and draw at the scene’s own size, so a capture is unchanged.
A readout at the top of the window, centred, reports the smoothed frame rate
and frame time. The scene selector opens in the bottom-right corner, its
bottom-right held a margin from the screen’s edge, and can be dragged anywhere
from there; the rectangle it is left at is carried into the next scene when one
is chosen. When the window changes shape — a phone rotating as fullscreen takes
it — the panel follows the corner it belongs to, keeping its distance from that
corner instead of staying where the old shape left it. A button in the
top-right corner — sized so a finger can land on it — offers fullscreen on
every platform, and is labelled for whichever the window is not. On the desktop
and in a browser it takes the window fullscreen and back:
in a browser the click is the one gesture the page is granted as permission, and
a device being held upright is then locked to landscape, so the picture fills a
phone’s screen. The lock follows from the fullscreen: the browser releases it
when fullscreen ends, and it is never applied to a device already held sideways.
Where the platform cannot change the window — Android, whose activity already
takes the whole screen — or refuses the request — a page in an iframe without
the fullscreen permission — the button is still drawn, and the press simply
does nothing.
A GPU panel reports the device the example is running on: the adapter’s name and description, the backend, the driver, the features the device was created with, and every limit it reports. It opens in the bottom-left corner and, like the scene selector, is a window that can be dragged anywhere and whose rectangle is carried into the next scene. The facts are read once, when the scene is built — a device’s features and limits cannot change — and the list scrolls within a share of the window’s height, so even a long one never covers the scene.
The GPU context is requested asynchronously, because the adapter and device requests are: on the web they resolve on the browser’s task queue, so the frame loop must not block on them. The window is created on the main thread — winit hands out a window’s raw handle only from the thread that owns it — and the context arrives back through the event loop’s proxy, where the scene is built on the thread that owns the ECS world.
A suspension does not reset any of that. The platform invalidates the render surface, and on Android destroys the native window under it, but the window handle, the GPU context and the whole ECS world stay: the swap chain alone is released and built again on the next resume, so the app comes back to the state it left — the same spin angle, camera orbit and panel values.
No application logic lives in a winit callback. unlit3d::winit::event::WinitHost
is the one ApplicationHandler the example implements — it is not implemented
at all, only driven — and every callback is an ordinary behaviour component on
an entity of the host world: the window is requested on resume, close and
Esc set an exit request, the library’s pump keeps frames coming between
compositor redraws, a resize re-letterboxes the scene, and the app’s own
UserEvent carries the GPU context back. The example’s state is the same kind
of component, so a callback writes a sibling cell and never borrows the one it
is running from.
A frame’s own work is split the same way. The frame command the pump and the
redraw requests queue computes the delta time and dispatches the host world’s
OnFrame behaviours, which make sure the scene is presented, serve the scene
switch and the fullscreen request, advance the scene, and present it through
the library’s present_frames.
The scene’s own world dispatches the same family for input distribution,
sequence stepping and the scene’s advance closure, which runs through a
queued command because it needs &mut World. The dispatch is not stable
within one order value, so every behaviour that takes part states the order
that encodes what it reads and writes — the readiness check first, then the
controls, the advance, the region restate, the library’s present, and the
scene’s command flush in the host world, and the advance after the index in
the scene world — so the dependency holds however the setup spawns them. A
caller adds a behaviour of its own the same way: spawn it, and state an order
only if it reads or writes what another behaviour does.
§Running it
cargo run -p unlit3d_examplesA window opens with the default scene — a spinning, textured cube and two egui
panels — plus a panel that lists every scene. Esc closes it; the cube’s
panel’s button, checkbox and slider drive the spin, and dragging with the left
button orbits the camera. A scene can be selected from the command line instead:
cargo run -p unlit3d_examples -- --scene skinnedTo run the same example in a browser — where WebGPU needs a secure context, so
localhost rather than file:// — use the task runner:
cargo xtask run-wasm --app unlit3dThe task builds this example and unlit3dx_examples into one site by default
and serves a landing page linking both, so --app unlit3d builds only this
one. The page it serves sizes the canvas to the viewport less a small margin of
its own, rather than to the window the example asks for, so the example fills a
phone’s screen and follows a window that is resized. The canvas is not the
picture, though: each 3D scene is drawn into the baseline-aspect region of it,
so the same picture fills whatever shape the page gives the canvas.
It is a library as well as a binary, because Android starts neither a process
nor a command line: the activity loads a shared library and calls its
android_main, and the command-line path is the binary. Both end in the same
windowed loop, so the example only has one frame loop to maintain.
The shared library is unlit3d_examples_android, a crate of its own holding
nothing but the export: crate-type applies to every target a package is built
for, so a cdylib here would link a shared library on the desktop and in the
browser too, where nothing loads one. The library keeps this crate’s name, so
the activity’s android.app.lib_name entry is unchanged.
§Model Context Protocol
--mcp serves the scene the example would otherwise have rendered, over stdio,
as a Model Context Protocol server. The
chosen scene is built first — --scene still selects it — and the client then
reads and drives it through the tools. The example’s own event loop serves it,
on the thread that owns it, so the window goes on drawing and input still
reaches the scene: the scene’s pass renders offscreen and a second pass in the
same world copies that frame into the swap chain, so the picture follows the
client. The copying pass declares no depth state and samples the offscreen
frame’s resolved colour texture, so its frames carry neither a depth nor a
multisample attachment. The world is one component of the host World, and a
tool names it.
See unlit_ecs for the server, the tools
each crate registers, and the transport.
cargo run -p unlit3d_examples --bin unlit3d-examples -- --mcp --scene spin_cube§Android
Android starts an activity, not a process: the activity loads the shared
library and calls its android_main on a thread of its own. android_main
builds the event loop with the activity winit requires on that platform and
hands it to the same windowed loop the binary drives, starting with the default
scene.
The APK carries one activity per example, because GameActivity reads the
library name out of its own android.app.lib_name manifest entry once and has
no way to load a second one. A floating tab bar over the game surface switches
between them; picking the other tab starts its activity and finishes the one it
leaves, so only one native window is ever alive.
To build the APK, which cross-compiles the library, stages it in the Gradle
project’s jniLibs directory and then runs the Gradle wrapper there:
cargo xtask build-androidThe result is android/app/build/outputs/apk/debug/app-debug.apk, installable
with adb install. --release builds a release APK instead, which this project
leaves unsigned. The project’s Gradle setup and the task’s own constants have to
agree; see the
task runner’s README.
The activities are
MainActivity.kt
and
Unlit3dxActivity.kt.
Each is a few lines over
TabbedExampleActivity.kt,
which extends GameActivity, installs the floating tab bar and takes the
screen over; the activity only says which example it is and which tab is
selected. GameActivity loads the library named by the android.app.lib_name
manifest entry and calls into it, so the whole application — window, GPU
context, frame loop — is the example crate’s.
§Snapshot tests
tests/gpu_suite.rs is where the example’s rendering is checked. It draws every
scene offscreen, with no window and no event loop, advancing it by a fixed
timestep so the same code produces the same picture, and compares each frame the
scene freezes against the scene’s stored snapshot:
cargo nextest run -p unlit3d_examplesThe test is a library test rather than a command line: the same body runs
natively and, because the test binary is what the wasm test page loads, in a
browser too. cargo xtask test runs it twice, once per device tier, and
cargo xtask test-wasm runs it against a real WebGL2 implementation.
§Options
The options are declared and parsed with
argh. Every option is --name value or a bare flag;
the value must be the next argument, so --name=value is not accepted.
| Option | Default | Meaning |
|---|---|---|
--scene <ID> | spin_cube | The scene to start from |
--list-scenes | off | Print the scene table and exit |
--size <WxH> | the scene’s own | Initial window size in pixels |
--mcp | off | Serve the world over stdio, showing its frames in the window |
§Playback pace
A snapshot test draws a multi-frame scene’s frames back to back, so one run
matches its snapshots frame by frame. The windowed loop instead plays them over
time: a scene whose animation was frozen as a few frames holds each one for
SEQUENCE_STEP (currently 0.5 s), so the sequence is watchable rather than
flashing past at the refresh rate. At most one sequence step is taken per
windowed frame, so a stall does not skip frames.
A scene whose animation carries its own timing declares no step at all and
advances from the frame delta instead, so the window runs it at the pace the
display refreshes rather than in the two steps a second a held sequence gives.
Two scenes do this. gltf plays the fox’s Walk and the morph cube’s Pulse
at each clip’s own duration, looping in real time, so the window shows the
documents as an application would rather than through a six-frame sequence.
custom_pipeline is parametric — the orbit angle and the particle clock are
both functions of time — so it accumulates the frame delta and moves every
frame. The snapshot capture still walks each scene’s sequence, because a
stored frame has to be reproducible.
§Choosing a device tier
UNLIT3D_DEVICE_TIER sets how much of the WebGPU baseline every offscreen device
a test builds is asked for. Unset, it is webgpu: the guaranteed baseline
limits, so the device is no larger than the API promises and the frame runs
wherever WebGPU does. Only the texture resolution is taken from the adapter, so
the device is never smaller than the machine allows. native asks for the
adapter’s own limits instead, which on a desktop is its full Vulkan, Metal or
DX12 capabilities.
webgl2 asks for WebGL2’s limits — no storage buffers — and the frame is
recorded as WebGL2 would record it, with the shader’s arrays read through
textureLoad and each mesh’s vertex offset baked into its indices. Any other
value is refused rather than guessed at, since running the wrong tier would pass
while testing nothing.
UNLIT3D_DEVICE_TIER=webgl2 cargo nextest run -p unlit3d_examplesWGPU_BACKEND selects the backend in the usual wgpu way and is independent of
the tier; WGPU_BACKEND=gles together with the tier is the closest a desktop
machine comes to a browser’s WebGL2, since the limits and flags are WebGL2’s
even where the GL context is not.
§Snapshots
Each test compares every frame the scene declares a snapshot for against the
snapshot directory. The comparison uses SSIMULACRA2 and fails when the score
falls below the tolerance, which the test states for the scene it draws. A
missing snapshot is written from the frame rather than failed on, so the first
run of a new test records its baseline, and SNAPSHOT_UPDATE=1 rewrites one that
exists.
The default tolerance suits a frame of whole surfaces, where a regression moves
large regions and so lands far below the line. A frame of thin primitives is
different: its pixels are outlines, and which triangle an outline pixel belongs
to is a rasterizer’s tie-breaking rule to decide — one the API leaves to each
implementation. A scatter of such pixels is worth tens of points there, so
mesh_topologies is given a tolerance of its own, stated with the measurements
that put its bound above every correct frame and below every broken one.
A scene’s own snapshots only describe a run that reproduces the scene’s stored settings, so a test draws at the scene’s own size and frame count. The letterbox fitting the windowed path applies is checked by a test of its own, which draws the default scene at a target narrower than its baseline and compares the fitted picture against a capture made for it.
A mismatch is frequently the platform showing through rather than a regression:
the stored images come from one GPU stack, and another driver’s rounding can put
a scene below the line with nothing wrong. A frame that fails is therefore
written before the test fails — natively under
UNLIT3D_SNAPSHOT_MISMATCH_DIR, and in a browser through the runner, which is
the process that has a filesystem — so the frame can be looked at instead of
guessed at from a score. CI uploads those directories as artifacts when a test
fails.
To re-bless a snapshot after an intentional rendering change, run with
SNAPSHOT_UPDATE=1, then review the image diffs in
unlit3d_asset_files
before committing them. That submodule is checked out with
git submodule update --init --checkout, which is what gets past its
update = none.
§Tests
The crate’s own tests cover the command line (src/cli.rs) and the fixed-step
playback clock (src/lib.rs), and tests/gpu_suite.rs covers the rendering.
Where each test layer sits across the workspace, and what CI runs, is in the
root README.
§License
Dual-licensed under MIT or Apache-2.0, at your option.
Re-exports§
pub(crate) use cli::Args;🔒pub(crate) use cli::Parsed;🔒pub(crate) use scenes::Advance;🔒pub(crate) use scenes::SceneControl;🔒pub(crate) use std::collections::VecDeque;🔒pub(crate) use std::io::Write;🔒pub(crate) use std::process::ExitCode;🔒pub(crate) use Bundle;🔒pub(crate) use DynamicBundle;🔒pub(crate) use bundle;🔒pub(crate) use unlit_wgpu::resources::ResourceGraph;🔒pub(crate) use unlit_wgpu::scene::ViewportRect;🔒pub(crate) use unlit3d::frame::Frame;🔒pub(crate) use unlit3d::input::winit::WinitInput;🔒pub(crate) use UiSource;🔒pub(crate) use egui;🔒pub(crate) use DisplayHandle;🔒pub(crate) use ExitOn;🔒pub(crate) use ExitRequest;🔒pub(crate) use ExitTrigger;🔒pub(crate) use Resumed;🔒pub(crate) use WindowSetup;🔒pub(crate) use WinitProxy;🔒pub(crate) use request_redraw_while_foreground;🔒pub(crate) use window;🔒pub(crate) use winit_input_behaviour;🔒pub(crate) use OnUserEvent;🔒pub(crate) use OnWindowEvent;🔒pub(crate) use WinitHost;🔒pub(crate) use unlit3d::winit::presenter::SCENE_PASS_ORDER;🔒pub(crate) use winit::event::WindowEvent;🔒pub(crate) use ControlFlow;🔒pub(crate) use EventLoop;🔒pub(crate) use EventLoopProxy;🔒pub(crate) use winit::window::Window;🔒pub(crate) use unlit3d::prelude::*;🔒
Modules§
- cli 🔒
- The example’s command line.
- fullscreen 🔒
- The fullscreen button, and the landscape lock that only a browser permits. Fullscreen: the button that takes the window fullscreen, and the landscape lock that only a browser permits.
- scenes
- The example’s selectable scenes.
Structs§
- App 🔒
- The application’s state, spawned as one object.
- Build
Presenter 🔒 - Build the presentation path once the scene’s queued world has landed.
- Frame
Rate 🔒 - The frame rate the windowed shell reports, as a component so the panel that displays it and the loop that measures it share one value.
- Fullscreen
Active 🔒 - Whether the window is fullscreen, written once per frame by the frame loop.
- Fullscreen
Request 🔒 - Set by the windowed shell’s fullscreen button, read once by the frame loop.
- Gpu 🔒
- The GPU context a scene draws with, requested asynchronously.
- GpuInfo 🔒
- The device facts the GPU-info panel shows, read once when it is mounted.
- GpuInfo
Pos 🔒 - The GPU-info panel’s rectangle the last time a scene was live, so a scene switch can rebuild it where the user left it.
- Initial
Scene 🔒 - The scene the example starts with; a switch replaces it.
- McpEnabled 🔒
- Whether to serve the world over the Model Context Protocol rather than drive a scene on this thread.
- Panel
Rects - Where the scene’s draggable panels opened, carried from the scene a switch replaced.
- Presenter
Entity 🔒 - The entity carrying the presentation path, absent until the scene and surface are ready.
- Render
World 🔒 - The render world an application presents through, under the name it reports to the MCP tools.
- RunIn
Host 🔒 - Run one MCP command against the host world itself.
- RunIn
World 🔒 - Run one MCP command against a nested world of the host.
- RunScene
Advance 🔒 - Run the scene’s own per-frame behaviour, which needs
&mut World. - Scene
- The scene’s world and the frame loop that drives it.
- Scene
Advance 🔒 - A scene’s own per-frame behaviour, stored in its world so the frame behaviour that drives it can call it with the world it mutates.
- Scene
Entity 🔒 - The host entity carrying the scene’s world and its
Scene. - Scene
Frame 🔒 - The scene’s per-frame state, spawned with its own advance.
- Scene
Switch 🔒 - Set by the windowed shell’s scene-selector panel, read once by the frame loop.
- Selector
Pos 🔒 - The selector window’s rectangle the last time a scene was live, so a scene switch can rebuild it in the same place and at the same size.
- Sequence
Clock 🔒 - Seconds accumulated towards the next advance of a scene’s index.
- Sequence
Step 🔒 - The interval a scene’s index advances at, in seconds, or
Noneto advance it once per drawn frame. - Sequence
Stepped 🔒 - Whether this frame advanced the scene’s index, decided by the sequence step and read by the behaviour that runs the scene’s own advance.
- World
Name 🔒 - The name this example reports a host world under to the MCP tools.
Enums§
- GpuInfo
Line 🔒 - One line of the GPU-info panel.
- GpuState 🔒
- Where the one-time GPU setup stands.
- User
Event 🔒 - Events delivered to the winit loop from outside a
WindowEvent.
Constants§
- ADVANCE_
ORDER 🔒 - The order the scene advances at: after the controls, which may have skipped the frame, and before the present, which draws what the advance produced.
- API_
DOCS_ 🔒AREA - The id of the API-docs button’s area.
- API_
DOCS_ 🔒LABEL - The label the API-docs button carries.
- API_
DOCS_ 🔒URL - The API docs the Pages workflow publishes beside the example page.
- CONTROLS_
ORDER 🔒 - The order the controls run at: after
ensure_presented, which may have skipped the frame, and first of the readers that act on the flag, since switching a scene skips the frame for the two after them. - FIXED_
STEP - The timestep a scene is stepped by when it is drawn without a display.
- FLUSH_
ORDER 🔒 - The order the scene world’s queued commands are applied at: after the library’s present, whose render is what queued them.
- FRAME_
RATE_ 🔒AREA - The id of the frame-rate readout’s area.
- FULLSCREEN_
AREA 🔒 - The id of the fullscreen button’s area.
- GPU_
INFO_ 🔒AREA - The id of the GPU-info panel’s area, which is also the id egui remembers the panel’s rectangle under.
- GPU_
INFO_ 🔒HEIGHT_ FRACTION - The share of the window’s height the GPU-info panel may take.
- GPU_
INFO_ 🔒MAX_ WIDTH_ FRACTION - The share of the window’s width the GPU-info panel may take, at most.
- GPU_
INFO_ 🔒MIN_ WIDTH - The narrowest the GPU-info panel may be dragged, in points.
- GPU_
INFO_ 🔒TITLE - The GPU-info panel’s title, shown in its title bar.
- GPU_
INFO_ 🔒WIDTH_ SLACK - Slack added to the GPU-info panel’s measured width.
- MCP_
SUPPORTED 🔒 - Whether this build can serve the Model Context Protocol.
- OVERLAY_
BUTTON_ 🔒MIN_ SIZE - The smallest a corner button is drawn, in points.
- OVERLAY_
BUTTON_ 🔒PADDING - A corner button’s inner padding, symmetric so the label is centred within the button it is grown to.
- OVERLAY_
GAP 🔒 - The gap between the frame-rate readout and the fullscreen button when a window is too narrow to hold them on the same row.
- OVERLAY_
MARGIN 🔒 - The distance every overlay keeps from the edge of the screen.
- READY_
ORDER 🔒 - The order the scene and its presentation path come up at.
- SAMPLE_
COUNT 🔒 - The number of samples the windowed loop presents every frame with.
- SCENE_
ADVANCE_ 🔒ORDER - The order the scene world advances its scene at: after
step_sequence, which decides whether this frame advances and records the decision for the behaviour that runs it. The value shares nothing with the host world’s orders: the two worlds dispatch separately. - SELECTOR_
DEFAULT_ 🔒WIDTH - The width the selector window opens at, in points.
- SELECTOR_
WINDOW 🔒 - The scene-selector window’s title, which is also its egui area id: the shell reads the window’s remembered rectangle by this same id.
- VIEWPORT_
ORDER 🔒 - The order the scene’s region is restated at: after the advance, and before the library’s present, which draws the pass the region belongs to.
Functions§
- advance_
scene 🔒 - Advance the scene by the frame’s delta.
- api_
docs_ 🔒button - Draw the API-docs link under the fullscreen button, and report whether it was pressed.
- corner_
button 🔒 - Draw a button that owns a corner, and report whether it was pressed.
- device_
type_ 🔒name - The name of a [
wgpu::DeviceType], for the panel’s summary line. - dispatch_
command 🔒 - Queue one MCP command against the world it names.
- dispatch_
input_ 🔒on_ frame - Run the scene world’s input dispatch for the frame.
- ensure_
presented 🔒 - Build the scene and its surface, and short-circuit the frame until both are ready.
- flush_
scene 🔒 - Apply the commands the scene world queued while presenting.
- follow_
screen_ 🔒corner - Shift a movable window by however far the screen corner it belongs to moved when the screen changed shape.
- frame_
rate_ 🔒readout - Draw the frame-rate readout, showing
text, centred along the top edge ofui’s screen. - fullscreen_
button 🔒 - Draw the fullscreen button, labelled for what pressing it does, and report whether it was pressed.
- gpu 🔒
- The GPU context, once the asynchronous setup has landed.
- gpu_
info_ 🔒default_ pos - Where the GPU-info panel opens when no position was carried over.
- gpu_
info_ 🔒lines - The lines the GPU-info panel shows, top to bottom.
- gpu_
info_ 🔒panel - Draw the GPU-info panel for
info, seeded atinitialor the bottom-left corner ofui’s screen. - gpu_
info_ 🔒width - How wide the GPU-info panel has to be to keep every line on one row.
- handle_
user_ 🔒event - Serve the events the app posts to itself.
- init_
logging 🔒 - Install the logger backend and the panic hook the example reports through.
- json_
scalar 🔒 - One limit’s value as text.
- letterbox 🔒
- The region a scene’s content is drawn into and the size its camera is built
for, for a
target-pixel render target. - limit_
rows 🔒 - The device’s limits as label/value pairs, in the order the device reports them.
- mount_
api_ 🔒docs - Mount the link to the API docs in the window’s top-right corner.
- mount_
frame_ 🔒rate - Mount the frame-rate readout at the top of the window, centred.
- mount_
fullscreen 🔒 - Mount the fullscreen button in the window’s top-right corner.
- mount_
gpu_ 🔒info - Mount the GPU-info panel, a draggable window in the bottom-left corner.
- mount_
selector 🔒 - Mount the windowed shell’s scene-selector panel.
- open_
url 🔒 - Open a URL the UI asked for, in a new tab when it asked for one.
- overlay_
button_ 🔒top - The vertical offset a corner button’s anchor is drawn at, given the area above it in the same corner.
- pivot_
factor 🔒 - The fraction of a window’s size at which its pivot sits, per axis.
- present 🔒
- Bring the scene and its presentation path up, as far as the state allows.
- presenter_
entity 🔒 - The entity carrying the presentation path, while one is up.
- release_
presenter 🔒 - Release the presentation path and drop it, before its scene goes.
- release_
surface 🔒 - Release the swap chain, keeping the presentation path for a later resume.
- request_
gpu 🔒 - Request the GPU context once a window exists to present through.
- resize_
scene 🔒 - Re-state the scene and the surface for a new window size.
- restate_
viewport 🔒 - Restate the scene’s letterboxed region on the pass that draws it.
- run
- Run the example from the command line.
- run_
scene_ 🔒advance - Run the scene’s own per-frame behaviour when the sequence advanced, and count the frame.
- selector_
default_ 🔒pos - Where the selector window opens when no position was carried over — the first build of a session.
- serve_
scene_ 🔒controls - Serve the scene selector, the fullscreen button and the UI’s URL requests.
- spawn 🔒
- Run
futureconcurrently: on a worker thread on native, in the browser’s task queue on the web (where a thread cannot be blocked). - start_
mcp 🔒 - Start the MCP stdio transport, which posts each command back to the loop.
- stderr 🔒
- Write
textto standard error. - stdout 🔒
- Write
textto standard output. - step_
sequence 🔒 - Decide whether this frame advances the scene’s sequence.
- switch_
scene 🔒 - Rebuild the app around a different scene.
- tick 🔒
- Accumulate
delta_timeintoclockand report whether astep-long interval has passed, subtracting it from the clock if so. - windowed 🔒
- Drive the windowed example on
event_loopuntil it exits.