nightshade 0.57.0

A cross-platform data-oriented game engine.
Documentation
//! Virtualized geometry: rendering meshes as hierarchies of small triangle
//! clusters instead of as one monolithic vertex and index buffer.
//!
//! A meshlet mesh is baked offline from a regular
//! [`Mesh`](crate::render::geometry::Mesh)
//! with `from_mesh` (behind the `meshlet_processor` feature), which splits it
//! into clusters, simplifies them into a level-of-detail hierarchy, and
//! quantizes the vertex data into compact bitstreams. Register the result with
//! `MeshletAssets` and reference the returned id from a
//! [`MeshletMesh`](components::MeshletMesh) component:
//!
//! ```ignore
//! let baked = from_mesh(&create_sphere_mesh(2.0, 128), MESHLET_DEFAULT_VERTEX_POSITION_QUANTIZATION_FACTOR)?;
//! let asset_id = world.res_mut::<MeshletAssets>().register(baked);
//! world.spawn_with((
//!     MeshletMesh { asset_id },
//!     LocalTransform::default(),
//!     GlobalTransform::default(),
//! ));
//! ```
//!
//! What that buys is a drawn triangle count that follows the pixels rather than
//! the model, and an asset that uploads once however many entities reference
//! it: a hundred thousand entities sharing one bake cost one upload, and all
//! but the nearest of them resolve to a handful of coarse clusters.
//!
//! Meshlet entities render through their own pass rather than the standard mesh
//! pipeline. Each frame a compute pass walks every instance's hierarchy on the
//! GPU and picks one level of detail per region of it, the surviving clusters
//! rasterize into a buffer holding just the cluster and triangle each pixel
//! landed on, and a fullscreen resolve reconstructs that triangle and shades
//! it. The pass shares the scene's depth buffer, so meshlet geometry and
//! regular meshes occlude each other correctly.
//!
//! This side of it stays deliberately thin. [`sync_meshlets`] hands the
//! renderer a transform and an asset id per entity and nothing else: which
//! clusters draw, and how many, are decided on the GPU from data that already
//! lives there. Nothing here iterates the scene per frame beyond collecting
//! that list.
//!
//! Materials, shadows, and picking do not reach meshlet entities yet, so a
//! meshlet surface shades from a placeholder rather than from its material.
//!
//! [`sync_meshlets`]: crate::ecs::graphics::scene_sync
//!
//! Everything here needs the `meshlet` feature except
//! [`MeshletMesh`](components::MeshletMesh) itself, which registers
//! unconditionally because the component schema cannot take a feature gate on
//! one field. Without the feature there is no `MeshletAssets` to mint an id
//! from, no sync, and no pass, so the component is inert rather than merely
//! unrendered.

pub mod components;
#[cfg(feature = "meshlet")]
pub mod resources;