-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Meshlet rendering (initial feature) (#10164)
# Objective - Implements a more efficient, GPU-driven (#1342) rendering pipeline based on meshlets. - Meshes are split into small clusters of triangles called meshlets, each of which acts as a mini index buffer into the larger mesh data. Meshlets can be compressed, streamed, culled, and batched much more efficiently than monolithic meshes. ![image](https://github.com/bevyengine/bevy/assets/47158642/cb2aaad0-7a9a-4e14-93b0-15d4e895b26a) ![image](https://github.com/bevyengine/bevy/assets/47158642/7534035b-1eb7-4278-9b99-5322e4401715) # Misc * Future work: #11518 * Nanite reference: https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf Two pass occlusion culling explained very well: https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501 --------- Co-authored-by: Ricky Taylor <[email protected]> Co-authored-by: vero <[email protected]> Co-authored-by: François <[email protected]> Co-authored-by: atlas dostal <[email protected]>
- Loading branch information
1 parent
f096ad4
commit 4f20faa
Showing
40 changed files
with
4,304 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
use bevy_asset::{ | ||
io::{Reader, Writer}, | ||
saver::{AssetSaver, SavedAsset}, | ||
Asset, AssetLoader, AsyncReadExt, AsyncWriteExt, LoadContext, | ||
}; | ||
use bevy_math::Vec3; | ||
use bevy_reflect::TypePath; | ||
use bytemuck::{Pod, Zeroable}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::sync::Arc; | ||
|
||
/// A mesh that has been pre-processed into multiple small clusters of triangles called meshlets. | ||
/// | ||
/// A [`bevy_render::mesh::Mesh`] can be converted to a [`MeshletMesh`] using `MeshletMesh::from_mesh` when the `meshlet_processor` cargo feature is enabled. | ||
/// The conversion step is very slow, and is meant to be ran once ahead of time, and not during runtime. This type of mesh is not suitable for | ||
/// dynamically generated geometry. | ||
/// | ||
/// There are restrictions on the [`crate::Material`] functionality that can be used with this type of mesh. | ||
/// * Materials have no control over the vertex shader or vertex attributes. | ||
/// * Materials must be opaque. Transparent, alpha masked, and transmissive materials are not supported. | ||
/// * Materials must use the [`crate::Material::meshlet_mesh_fragment_shader`] method (and similar variants for prepass/deferred shaders) | ||
/// which requires certain shader patterns that differ from the regular material shaders. | ||
/// * Limited control over [`bevy_render::render_resource::RenderPipelineDescriptor`] attributes. | ||
/// | ||
/// See also [`super::MaterialMeshletMeshBundle`] and [`super::MeshletPlugin`]. | ||
#[derive(Asset, TypePath, Serialize, Deserialize, Clone)] | ||
pub struct MeshletMesh { | ||
/// The total amount of triangles summed across all meshlets in the mesh. | ||
pub total_meshlet_triangles: u64, | ||
/// Raw vertex data bytes for the overall mesh. | ||
pub vertex_data: Arc<[u8]>, | ||
/// Indices into `vertex_data`. | ||
pub vertex_ids: Arc<[u32]>, | ||
/// Indices into `vertex_ids`. | ||
pub indices: Arc<[u8]>, | ||
/// The list of meshlets making up this mesh. | ||
pub meshlets: Arc<[Meshlet]>, | ||
/// A list of spherical bounding volumes, 1 per meshlet. | ||
pub meshlet_bounding_spheres: Arc<[MeshletBoundingSphere]>, | ||
} | ||
|
||
/// A single meshlet within a [`MeshletMesh`]. | ||
#[derive(Serialize, Deserialize, Copy, Clone, Pod, Zeroable)] | ||
#[repr(C)] | ||
pub struct Meshlet { | ||
/// The offset within the parent mesh's [`MeshletMesh::vertex_ids`] buffer where the indices for this meshlet begin. | ||
pub start_vertex_id: u32, | ||
/// The offset within the parent mesh's [`MeshletMesh::indices`] buffer where the indices for this meshlet begin. | ||
pub start_index_id: u32, | ||
/// The amount of triangles in this meshlet. | ||
pub triangle_count: u32, | ||
} | ||
|
||
/// A spherical bounding volume used for culling a [`Meshlet`]. | ||
#[derive(Serialize, Deserialize, Copy, Clone, Pod, Zeroable)] | ||
#[repr(C)] | ||
pub struct MeshletBoundingSphere { | ||
pub center: Vec3, | ||
pub radius: f32, | ||
} | ||
|
||
/// An [`AssetLoader`] and [`AssetSaver`] for `.meshlet_mesh` [`MeshletMesh`] assets. | ||
pub struct MeshletMeshSaverLoad; | ||
|
||
impl AssetLoader for MeshletMeshSaverLoad { | ||
type Asset = MeshletMesh; | ||
type Settings = (); | ||
type Error = bincode::Error; | ||
|
||
async fn load<'a>( | ||
&'a self, | ||
reader: &'a mut Reader<'_>, | ||
_settings: &'a Self::Settings, | ||
_load_context: &'a mut LoadContext<'_>, | ||
) -> Result<Self::Asset, Self::Error> { | ||
let mut bytes = Vec::new(); | ||
reader.read_to_end(&mut bytes).await?; | ||
bincode::deserialize(&bytes) | ||
} | ||
|
||
fn extensions(&self) -> &[&str] { | ||
&["meshlet_mesh"] | ||
} | ||
} | ||
|
||
impl AssetSaver for MeshletMeshSaverLoad { | ||
type Asset = MeshletMesh; | ||
type Settings = (); | ||
type OutputLoader = Self; | ||
type Error = bincode::Error; | ||
|
||
async fn save<'a>( | ||
&'a self, | ||
writer: &'a mut Writer, | ||
asset: SavedAsset<'a, Self::Asset>, | ||
_settings: &'a Self::Settings, | ||
) -> Result<(), Self::Error> { | ||
let bytes = bincode::serialize(asset.get())?; | ||
writer.write_all(&bytes).await?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#import bevy_core_pipeline::fullscreen_vertex_shader::FullscreenVertexOutput | ||
|
||
@group(0) @binding(0) var material_depth: texture_2d<u32>; | ||
|
||
/// This pass copies the R16Uint material depth texture to an actual Depth16Unorm depth texture. | ||
|
||
@fragment | ||
fn copy_material_depth(in: FullscreenVertexOutput) -> @builtin(frag_depth) f32 { | ||
return f32(textureLoad(material_depth, vec2<i32>(in.position.xy), 0).r) / 65535.0; | ||
} |
Oops, something went wrong.