2024-03-25 19:08:27 +00:00
//! Render high-poly 3d meshes using an efficient GPU-driven method. See [`MeshletPlugin`] and [`MeshletMesh`] for details.
mod asset ;
#[ cfg(feature = " meshlet_processor " ) ]
mod from_mesh ;
mod gpu_scene ;
mod material_draw_nodes ;
mod material_draw_prepare ;
mod persistent_buffer ;
mod persistent_buffer_impls ;
mod pipelines ;
mod visibility_buffer_raster_node ;
pub mod graph {
use bevy_render ::render_graph ::RenderLabel ;
#[ derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel) ]
pub enum NodeMeshlet {
VisibilityBufferRasterPass ,
Prepass ,
DeferredPrepass ,
MainOpaquePass ,
}
}
pub ( crate ) use self ::{
gpu_scene ::{ queue_material_meshlet_meshes , MeshletGpuScene } ,
material_draw_prepare ::{
prepare_material_meshlet_meshes_main_opaque_pass , prepare_material_meshlet_meshes_prepass ,
} ,
} ;
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
pub use self ::asset ::* ;
2024-03-25 19:08:27 +00:00
#[ cfg(feature = " meshlet_processor " ) ]
pub use self ::from_mesh ::MeshToMeshletMeshConversionError ;
use self ::{
gpu_scene ::{
extract_meshlet_meshes , perform_pending_meshlet_mesh_writes ,
prepare_meshlet_per_frame_resources , prepare_meshlet_view_bind_groups ,
} ,
graph ::NodeMeshlet ,
material_draw_nodes ::{
MeshletDeferredGBufferPrepassNode , MeshletMainOpaquePass3dNode , MeshletPrepassNode ,
} ,
material_draw_prepare ::{
MeshletViewMaterialsDeferredGBufferPrepass , MeshletViewMaterialsMainOpaquePass ,
MeshletViewMaterialsPrepass ,
} ,
pipelines ::{
MeshletPipelines , MESHLET_COPY_MATERIAL_DEPTH_SHADER_HANDLE , MESHLET_CULLING_SHADER_HANDLE ,
MESHLET_DOWNSAMPLE_DEPTH_SHADER_HANDLE , MESHLET_VISIBILITY_BUFFER_RASTER_SHADER_HANDLE ,
} ,
visibility_buffer_raster_node ::MeshletVisibilityBufferRasterPassNode ,
} ;
use crate ::{ graph ::NodePbr , Material } ;
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
use bevy_app ::{ App , Plugin , PostUpdate } ;
2024-03-25 19:08:27 +00:00
use bevy_asset ::{ load_internal_asset , AssetApp , Handle } ;
use bevy_core_pipeline ::{
core_3d ::{
graph ::{ Core3d , Node3d } ,
Camera3d ,
} ,
prepass ::{ DeferredPrepass , MotionVectorPrepass , NormalPrepass } ,
} ;
use bevy_ecs ::{
bundle ::Bundle ,
entity ::Entity ,
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
prelude ::With ,
2024-03-25 19:08:27 +00:00
query ::Has ,
schedule ::IntoSystemConfigs ,
system ::{ Commands , Query } ,
} ;
use bevy_render ::{
render_graph ::{ RenderGraphApp , ViewNodeRunner } ,
render_resource ::{ Shader , TextureUsages } ,
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
view ::{
check_visibility , prepare_view_targets , InheritedVisibility , Msaa , ViewVisibility ,
Visibility , VisibilitySystems ,
} ,
2024-03-25 19:08:27 +00:00
ExtractSchedule , Render , RenderApp , RenderSet ,
} ;
use bevy_transform ::components ::{ GlobalTransform , Transform } ;
const MESHLET_BINDINGS_SHADER_HANDLE : Handle < Shader > = Handle ::weak_from_u128 ( 1325134235233421 ) ;
const MESHLET_MESH_MATERIAL_SHADER_HANDLE : Handle < Shader > =
Handle ::weak_from_u128 ( 3325134235233421 ) ;
/// Provides a plugin for rendering large amounts of high-poly 3d meshes using an efficient GPU-driven method. See also [`MeshletMesh`].
///
/// Rendering dense scenes made of high-poly meshes with thousands or millions of triangles is extremely expensive in Bevy's standard renderer.
/// Once meshes are pre-processed into a [`MeshletMesh`], this plugin can render these kinds of scenes very efficiently.
///
/// In comparison to Bevy's standard renderer:
/// * Minimal rendering work is done on the CPU. All rendering is GPU-driven.
/// * Much more efficient culling. Meshlets can be culled individually, instead of all or nothing culling for entire meshes at a time.
/// Additionally, occlusion culling can eliminate meshlets that would cause overdraw.
/// * Much more efficient batching. All geometry can be rasterized in a single indirect draw.
/// * Scales better with large amounts of dense geometry and overdraw. Bevy's standard renderer will bottleneck sooner.
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
/// * Near-seamless level of detail (LOD).
2024-03-25 19:08:27 +00:00
/// * Much greater base overhead. Rendering will be slower than Bevy's standard renderer with small amounts of geometry and overdraw.
/// * Much greater memory usage.
/// * Requires preprocessing meshes. See [`MeshletMesh`] for details.
/// * More limitations on the kinds of materials you can use. See [`MeshletMesh`] for details.
///
/// This plugin is not compatible with [`Msaa`], and adding this plugin will disable it.
///
/// This plugin does not work on the WebGL2 backend.
///
2024-04-28 07:20:16 +00:00
/// ![A render of the Stanford dragon as a `MeshletMesh`](https://raw.githubusercontent.com/bevyengine/bevy/main/crates/bevy_pbr/src/meshlet/meshlet_preview.png)
2024-03-25 19:08:27 +00:00
pub struct MeshletPlugin ;
impl Plugin for MeshletPlugin {
fn build ( & self , app : & mut App ) {
load_internal_asset! (
app ,
MESHLET_BINDINGS_SHADER_HANDLE ,
" meshlet_bindings.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
super ::MESHLET_VISIBILITY_BUFFER_RESOLVE_SHADER_HANDLE ,
" visibility_buffer_resolve.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
MESHLET_CULLING_SHADER_HANDLE ,
" cull_meshlets.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
MESHLET_DOWNSAMPLE_DEPTH_SHADER_HANDLE ,
" downsample_depth.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
MESHLET_VISIBILITY_BUFFER_RASTER_SHADER_HANDLE ,
" visibility_buffer_raster.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
MESHLET_MESH_MATERIAL_SHADER_HANDLE ,
" meshlet_mesh_material.wgsl " ,
Shader ::from_wgsl
) ;
load_internal_asset! (
app ,
MESHLET_COPY_MATERIAL_DEPTH_SHADER_HANDLE ,
" copy_material_depth.wgsl " ,
Shader ::from_wgsl
) ;
app . init_asset ::< MeshletMesh > ( )
. register_asset_loader ( MeshletMeshSaverLoad )
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
. insert_resource ( Msaa ::Off )
. add_systems (
PostUpdate ,
2024-04-18 20:33:29 +00:00
check_visibility ::< WithMeshletMesh > . in_set ( VisibilitySystems ::CheckVisibility ) ,
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
) ;
2024-03-25 19:08:27 +00:00
}
fn finish ( & self , app : & mut App ) {
2024-03-31 03:16:10 +00:00
let Some ( render_app ) = app . get_sub_app_mut ( RenderApp ) else {
2024-03-25 19:08:27 +00:00
return ;
} ;
render_app
. add_render_graph_node ::< MeshletVisibilityBufferRasterPassNode > (
Core3d ,
NodeMeshlet ::VisibilityBufferRasterPass ,
)
. add_render_graph_node ::< ViewNodeRunner < MeshletPrepassNode > > (
Core3d ,
NodeMeshlet ::Prepass ,
)
. add_render_graph_node ::< ViewNodeRunner < MeshletDeferredGBufferPrepassNode > > (
Core3d ,
NodeMeshlet ::DeferredPrepass ,
)
. add_render_graph_node ::< ViewNodeRunner < MeshletMainOpaquePass3dNode > > (
Core3d ,
NodeMeshlet ::MainOpaquePass ,
)
. add_render_graph_edges (
Core3d ,
(
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
// TODO: Meshlet VisibilityBufferRaster should be after main pass when not using depth prepass
2024-03-25 19:08:27 +00:00
NodePbr ::ShadowPass ,
Node3d ::Prepass ,
Node3d ::DeferredPrepass ,
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
NodeMeshlet ::VisibilityBufferRasterPass ,
NodeMeshlet ::Prepass ,
NodeMeshlet ::DeferredPrepass ,
2024-03-25 19:08:27 +00:00
Node3d ::CopyDeferredLightingId ,
Node3d ::EndPrepasses ,
Node3d ::StartMainPass ,
Node3d ::MainOpaquePass ,
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
NodeMeshlet ::MainOpaquePass ,
2024-03-25 19:08:27 +00:00
Node3d ::EndMainPass ,
) ,
)
. init_resource ::< MeshletGpuScene > ( )
. init_resource ::< MeshletPipelines > ( )
. add_systems ( ExtractSchedule , extract_meshlet_meshes )
. add_systems (
Render ,
(
perform_pending_meshlet_mesh_writes . in_set ( RenderSet ::PrepareAssets ) ,
configure_meshlet_views
. after ( prepare_view_targets )
. in_set ( RenderSet ::ManageViews ) ,
prepare_meshlet_per_frame_resources . in_set ( RenderSet ::PrepareResources ) ,
prepare_meshlet_view_bind_groups . in_set ( RenderSet ::PrepareBindGroups ) ,
) ,
) ;
}
}
/// A component bundle for entities with a [`MeshletMesh`] and a [`Material`].
#[ derive(Bundle, Clone) ]
pub struct MaterialMeshletMeshBundle < M : Material > {
pub meshlet_mesh : Handle < MeshletMesh > ,
pub material : Handle < M > ,
pub transform : Transform ,
pub global_transform : GlobalTransform ,
/// User indication of whether an entity is visible
pub visibility : Visibility ,
/// Inherited visibility of an entity.
pub inherited_visibility : InheritedVisibility ,
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
pub view_visibility : ViewVisibility ,
}
impl < M : Material > Default for MaterialMeshletMeshBundle < M > {
fn default ( ) -> Self {
Self {
meshlet_mesh : Default ::default ( ) ,
material : Default ::default ( ) ,
transform : Default ::default ( ) ,
global_transform : Default ::default ( ) ,
visibility : Default ::default ( ) ,
inherited_visibility : Default ::default ( ) ,
view_visibility : Default ::default ( ) ,
}
}
}
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.
Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.
Fixes #12935.
## Changelog
### Changed
* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.
## Migration Guide
* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
/// A convenient alias for `With<Handle<MeshletMesh>>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithMeshletMesh = With < Handle < MeshletMesh > > ;
2024-03-25 19:08:27 +00:00
fn configure_meshlet_views (
mut views_3d : Query < (
Entity ,
& mut Camera3d ,
Has < NormalPrepass > ,
Has < MotionVectorPrepass > ,
Has < DeferredPrepass > ,
) > ,
mut commands : Commands ,
) {
for ( entity , mut camera_3d , normal_prepass , motion_vector_prepass , deferred_prepass ) in
& mut views_3d
{
let mut usages : TextureUsages = camera_3d . depth_texture_usages . into ( ) ;
usages | = TextureUsages ::TEXTURE_BINDING ;
camera_3d . depth_texture_usages = usages . into ( ) ;
if ! ( normal_prepass | | motion_vector_prepass | | deferred_prepass ) {
commands
. entity ( entity )
. insert ( MeshletViewMaterialsMainOpaquePass ::default ( ) ) ;
} else {
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.
Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.
Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".
References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html
![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)
![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)
---------
Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
// TODO: Should we add both Prepass and DeferredGBufferPrepass materials here, and in other systems/nodes?
2024-03-25 19:08:27 +00:00
commands . entity ( entity ) . insert ( (
MeshletViewMaterialsMainOpaquePass ::default ( ) ,
MeshletViewMaterialsPrepass ::default ( ) ,
MeshletViewMaterialsDeferredGBufferPrepass ::default ( ) ,
) ) ;
}
}
}