Skip to content

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 16 May 08:38
· 220 commits to master since this release

Breaking changes

  • HDR rendering is now on by default. Applications that relied on the old LDR-only path should explicitly disable post-processing. The main rendering entry points support both modes; the paint-to-texture helpers remain LDR-only.
  • Per-item appearance control (visibility, unlit, opacity) is now unified under a single AppearanceSettings struct on every item type, replacing the scattered fields that existed before:
    • Material no longer has unlit or opacity fields. These are now controlled per-item through appearance.
    • SceneRenderItem.visible and VolumeMeshItem.visible are replaced by appearance.hidden (note the inverted polarity).
    • GlyphItem.unlit is replaced by appearance.unlit.
    • SceneRenderItem.render_as_wireframe and VolumeMeshItem.render_as_wireframe are replaced by appearance.wireframe.
    • Item types constructed with struct literal syntax (e.g. GpuMarchingCubesJob) need to add appearance: Default::default().

Improvements

  • PolylineItem batches now render as thin 1px lines when ViewportFrame::wireframe_mode is enabled or when appearance.wireframe is set. Previously polylines rendered as thick screen-space billboards regardless of wireframe mode.
  • SpriteItem batches now render wireframe overlays when ViewportFrame::wireframe_mode is enabled or when appearance.wireframe is set. Batches with 100 or fewer sprites show a 4-edge quad outline per sprite; larger batches show an AABB box. Outline corners are computed to match the sprite shader exactly, handling both WorldSpace and ScreenSpace size modes and per-instance rotation.
  • GPU marching cubes surfaces now render in wireframe when ViewportFrame::wireframe_mode is enabled or when appearance.wireframe is set on the job. Triangle edges are generated procedurally on the GPU via a fourth compute pass and drawn with a LineList pipeline; no CPU readback is required.
  • VolumeItem, GaussianSplatItem, and TransparentVolumeMeshItem now render wireframe overlays when ViewportFrame::wireframe_mode is enabled or when appearance.wireframe is set on an individual item. Volumes show an OBB; small splat clouds (<=100) show three orthogonal rings per splat, and larger clouds show an OBB fitted via PCA; transparent volume meshes show their boundary surface edges.
  • Glyphs and tensor glyphs now render in wireframe when ViewportFrame::wireframe_mode is enabled, or when appearance.wireframe is set on an individual item. Previously enabling wireframe left dark holes in the scene where these item types were drawn.
  • Streamtubes, tubes, and ribbons now render in wireframe when ViewportFrame::wireframe_mode is enabled, or when appearance.wireframe is set on an individual item. Previously these types also left dark holes in wireframe scenes.
  • Unified appearance settings across all renderable item types. Setting item.appearance.hidden, .unlit, or .opacity now works on every type without knowing how that type is rendered:
    • unlit skips lighting entirely and outputs the raw resolved colour. For mesh shaders the early-out fires right after colour resolution, before normal mapping, shadow maps, and the lighting loop. For types with fixed directional lighting (tensor glyphs, streamtubes, tubes, ribbons, implicit surfaces, marching cubes) the light calculation is skipped completely.
    • opacity multiplies the final output alpha on every lit geometry type. Glyph, tensor glyph, streamtube, tube, ribbon, implicit surface, and marching cubes types all now support it. The marching cubes pipeline has alpha blending enabled to make this work.
    • Scene graph nodes can set appearance via scene.set_appearance(node_id, settings), which propagates through to the rendered items.
  • Picking and selection highlight coverage now extends to more scene types:
    • Implicit surfaces, marching-cubes surfaces, image slices, surface slices, and screen images now participate in the unified picking API and can show object-level selection outlines.
    • Streamtubes, tubes, and ribbons can now highlight selected segments and strips in the same style as polylines.
    • Transparent volume meshes can now show object-level selection outlines.
  • Selection outlines for polylines, tubes, streamtubes, and ribbons now use the same depth-buffer edge-detection effect as triangle mesh objects, instead of point sprite discs at each control point. The outline follows the actual silhouette of the rendered geometry.
  • Tone mapping now defaults to Khronos Neutral instead of ACES. This keeps ordinary SDR colours closer to how they looked in the older LDR path, while still preserving HDR highlight compression. ACES remains available for scenes that want a stronger filmic look.
  • Post-processing types now live in a dedicated module, without changing existing import paths.
  • Transparent volume meshes require the HDR/post-processing path. This was already true in practice and is now called out clearly in the API documentation.

Performance

  • Unlit meshes now skip normal mapping, shadow map samples, AO, matcap, and the full lighting loop. Previously the unlit check ran late in the fragment shader, after most of that work was already done.

Fixes

  • Streamtubes, tubes, and ribbons ignored scene lights and used a hardcoded light direction. They now read from the scene light settings, so rotating or recolouring a directional light affects them the same way it affects meshes and other lit geometry. The old direction is used as a fallback when no lights are set.
  • Vector glyphs were often very dark. The shaft used one-sided lighting, so back-facing faces only got ambient (0.2 brightness); and the hardcoded light direction was nearly vertical, leaving horizontal vector fields dim everywhere. Glyphs now use two-sided diffuse so the full shaft is lit, and they read from the scene light settings instead of a fixed direction.
  • Meshes with scalar colourmap attributes could show a dot of the wrong colour at scalar extremes: a blue dot at the peak of a red mound, or a red dot at the trough of a blue one. The colourmap sampler was configured for tiling rather than clamping, so values at the top or bottom of the scalar range wrapped around to the opposite end of the colourmap.
  • Selection highlights for streamtubes, tubes, and ribbons are now visible and complete. Selected segments could disappear inside the rendered surface, and selected control points could fail to show at all.
  • HDR callback rendering now uses physical pixel resolution on HiDPI and Retina displays. This fixes validation errors caused by mismatched attachment sizes.
  • Tone-mapped output was too bright in HDR mode. The swapchain was being gamma-corrected twice, and the Khronos Neutral operator was not matching the real algorithm closely enough. Colours in the normal SDR range now stay much closer to the old LDR look.
  • Screen images with per-pixel depth now render correctly in HDR scenes. Previously they could disappear entirely.
  • Unified picking now returns mesh vertex hits correctly when the pick mask asks for both cells and vertices at once.
  • The viewport background could turn black in HDR mode when any sub-object highlight was active. Depth is now preserved correctly through the highlight pass.
  • Example and test cleanup:
    • Fixed a missing display_center field in tests/clip_volume.rs.
    • Removed a few unused mut bindings and an unused queue variable in examples/tests.

Removals

  • Removed the old HDR showcase callback example and its custom blit shader. The built-in ViewportCallback now covers that workflow directly.