v0.18.0
Breaking changes
Volume meshes unified into one item type
Opaque and transparent volume meshes are now one type. The old TransparentVolumeMeshItem is gone; VolumeMeshItem gains an optional transparency field that flips the render between the boundary surface and a projected-tet pass through the interior. Submission goes through one scene field instead of two. Uploading also collapses to one helper (with a transparency-capable variant for hosts that need volumetric rendering). Selection outlines and cell picking work in both modes automatically.
The transparent pass also drops its colormap-at-upload coupling: changing the colormap is now free per frame, like every other item type.
Features
Per-vertex deformation as a single mechanism
Skinning, wind, displacement, morph targets, ocean surfaces, and similar effects now register against one extension point. A plugin supplies a short WGSL body and per-vertex data; the body runs in every mesh draw (solid, transparent, instanced, shadow, outline) so the deformed mesh casts a deformed shadow and tracks a deformed selection outline. The previous parallel pipelines for skinning and vertex displacement are gone in favour of this one path. Up to four host deformers can be registered at once. See docs/overviews/plugin-types.md for the recipe.
GPU particle systems
Particle effects can run end to end on the GPU. Upload a system once with a capacity and a render route, then submit one item per frame with emitter settings (rate, lifetime, spawn shape, initial velocity) and a list of force fields. The renderer handles emission, simulation, and rendering. Spawn shapes include point, box, and sphere; velocity distributions cover fixed, box, and cone; forces include gravity, drag, and point attractors. Per-particle CPU work on the host drops to zero.
Mesh-rendered GPU particles
GPU particle systems can draw their live particles as instanced meshes instead of sprites. Pick a mesh, a blend mode, and an alignment rule (identity, velocity-aligned, or stable random tumble seeded at spawn); the simulation path is unchanged and one draw call covers the whole system. Useful for debris, projectiles, gibs, casings, dropped collectibles, and anything else that doesn't want a billboard.
Lit sprites and lit particles
Sprites and GPU particles can opt into the scene lighting: directional, point, spot, and hemisphere ambient all apply, so smoke, dust, and fog read with a clear lit and shaded side instead of looking flat. Three normal modes (spherical for round soft particles, flat for camera-aligned art, normal-mapped for textured surfaces) and an optional cascade shadow tap with PCF filtering. Defaults preserve the previous emissive billboard behaviour.
Sprite orientation and refraction
Sprites gain two new orientation modes alongside the default camera-facing: velocity-stretched (aligns the long axis with motion, length scales with speed) for sparks and rain streaks, and axis-locked (long axis pinned to a world direction) for vertical flames and grass cards. Sprites can also enable per-pixel scene refraction for heat haze, shockwaves, water splashes, and force-field hits; the renderer distorts the scene behind the sprite based on its texture. Refraction is HDR-path only.
Per-material UV transform
Materials can now shift and scale their texture UVs. Pick a sub-region of a texture, tile a wood or stone pattern at a different rate, or share one atlas across many materials without re-authoring meshes. Affects every texture the material samples (colour, normal, ambient occlusion, metallic-roughness, emissive). Works for single draws and instanced batches.
Ribbon trails: colour and blend modes
Ribbons can fade per vertex with an RGBA attribute and select between alpha, additive, and premultiplied blend modes. Useful for trails that go from invisible at the tail to bright at the head without a colourmap, and for additive streaks that brighten where segments overlap.
Stroked polyline overlay
A new screen-space polyline overlay primitive: a list of waypoints, a thickness, a colour, a join mode (mitre with auto-bevel fallback, or always-bevel), and an optional closed flag. Includes a path-sampling constructor for tracing a generated curve.
Richer overlay shapes
Several extensions to screen-space overlay shapes:
- Radial and conical gradient fills, plus multi-stop variants of linear, radial, and conical gradients (up to four stops).
- Clipping groups: a designated mask shape's bounding rectangle clips other shapes that reference it. Solid shapes only.
- Per-shape rotation, applied to fill, border, shadow, and gradient direction. The bounding box stays axis-aligned.
- 9-slice texture fills for resizable panel art, with independent stretch or tile behaviour for centre and edge regions.
- Texture transform: offset, scale, rotation, flip, and a new mirror tile mode for texture-filled shapes.
- Inner shadows for pressed buttons, dropdowns, and recessed surfaces. Shapes can carry an outer or inner shadow, not both at once.
Overlay animation tracks
Overlay shapes gain six independent animation tracks (opacity, position, size, fill, border, rotation) with five easing curves (linear, ease-in, ease-out, ease-in-out, pulse) and three repeat modes (once, loop, ping-pong). For non-linear motion, an alternate closure-driven path track stores a function called once per frame at the eased time; bezier and polyline constructors cover common 2D cases.
Improvements
- The built-in plugins (animation, constraints, physics, skeletal animation, skinning) moved to one top-level module:
viewport_lib::plugins. Each plugin reaches its API through its own subpath, mirroring how an external plugin crate is consumed. GPU skinning is now opt-in: hosts callSkinningPlugin::installonce at startup before uploading skin data; hosts without skinned content pay nothing for it. Skinning uploads happen through the plugin handle (attach_weights,attach_palette) rather than methods on the renderer. The old paths are gone in this release; seedocs/migration-guides/v0.18.0-plugins-module-and-opt-in-skinning.mdfor a complete mapping. The same pattern applies elsewhere: plugin-specific outputs (physics contacts, skinning updates, camera commands) now flow through the runtime's generic typed event bus rather than dedicated fields, so external plugins get the same surface as built-ins. - Ribbons can sample a texture, multiplied into the resolved ribbon colour. Useful for lightning, slash arcs, laser beams, and similar effects. Per-vertex
ucoordinates are optional; when empty they derive from cumulative arc length so the texture stretches evenly across each strip. - Sprites can carry per-instance soft-particle fade distances. Mixed-size batches (large smoke puffs next to small embers) can vary the fade per instance instead of sharing one value.
Bug fixes
- Mesh-instance batches no longer crash on draw. The pass was missing the deform bind group that the instanced mesh pipeline expects.
- Single-sided skinned characters render correctly with normal backface culling. They were previously silently dropped from the draw queue.
- Shadow acne that shifted with the light direction is gone. Cascade bias is now stable for any light direction; previously certain orientations produced a band of acne or broad acne with the light below the horizon.
- Removed a shadow-terminator fade that was hiding legitimate shadows. With lights below the horizon it produced bright stripes that read as acne; the new bias work above handles the original grazing-angle artifact it was masking.
- New viewports no longer render their first frame fully black-shadowed. The shadow uniform is now seeded for slots created mid-frame; the bug was invisible under continuous repaint but broke single-shot and headless rendering.
- 1K and 2K shadow atlas resolutions no longer silently misconfigure the shadow filter; resolution settings now take full effect.
- Contact shadows now appear at close contact points instead of leaving a bright spot where objects meet a surface. Spot lights also get correct contact shadows.
- Overlay clip rectangles now scale correctly on high-DPI displays. Clipped shapes previously vanished entirely on any display with a pixel ratio other than 1.
- Overlay shape hit testing now honours rotation. Clicks on rotated shapes resolved against the un-rotated silhouette before.