Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_render/src/experimental/occlusion_culling/mod.rs
6598 views
1
//! GPU occlusion culling.
2
//!
3
//! See [`OcclusionCulling`] for a detailed description of occlusion culling in
4
//! Bevy.
5
6
use bevy_app::{App, Plugin};
7
use bevy_ecs::{component::Component, entity::Entity, prelude::ReflectComponent};
8
use bevy_reflect::{prelude::ReflectDefault, Reflect};
9
use bevy_shader::load_shader_library;
10
11
use crate::{extract_component::ExtractComponent, render_resource::TextureView};
12
13
/// Enables GPU occlusion culling.
14
///
15
/// See [`OcclusionCulling`] for a detailed description of occlusion culling in
16
/// Bevy.
17
pub struct OcclusionCullingPlugin;
18
19
impl Plugin for OcclusionCullingPlugin {
20
fn build(&self, app: &mut App) {
21
load_shader_library!(app, "mesh_preprocess_types.wgsl");
22
}
23
}
24
25
/// Add this component to a view in order to enable experimental GPU occlusion
26
/// culling.
27
///
28
/// *Bevy's occlusion culling is currently marked as experimental.* There are
29
/// known issues whereby, in rare circumstances, occlusion culling can result in
30
/// meshes being culled that shouldn't be (i.e. meshes that turn invisible).
31
/// Please try it out and report issues.
32
///
33
/// *Occlusion culling* allows Bevy to avoid rendering objects that are fully
34
/// behind other opaque or alpha tested objects. This is different from, and
35
/// complements, depth fragment rejection as the `DepthPrepass` enables. While
36
/// depth rejection allows Bevy to avoid rendering *pixels* that are behind
37
/// other objects, the GPU still has to examine those pixels to reject them,
38
/// which requires transforming the vertices of the objects and performing
39
/// skinning if the objects were skinned. Occlusion culling allows the GPU to go
40
/// a step further, avoiding even transforming the vertices of objects that it
41
/// can quickly prove to be behind other objects.
42
///
43
/// Occlusion culling inherently has some overhead, because Bevy must examine
44
/// the objects' bounding boxes, and create an acceleration structure
45
/// (hierarchical Z-buffer) to perform the occlusion tests. Therefore, occlusion
46
/// culling is disabled by default. Only enable it if you measure it to be a
47
/// speedup on your scene. Note that, because Bevy's occlusion culling runs on
48
/// the GPU and is quite efficient, it's rare for occlusion culling to result in
49
/// a significant slowdown.
50
///
51
/// Occlusion culling currently requires a `DepthPrepass`. If no depth prepass
52
/// is present on the view, the [`OcclusionCulling`] component will be ignored.
53
/// Additionally, occlusion culling is currently incompatible with deferred
54
/// shading; including both `DeferredPrepass` and [`OcclusionCulling`] results
55
/// in unspecified behavior.
56
///
57
/// The algorithm that Bevy uses is known as [*two-phase occlusion culling*].
58
/// When you enable occlusion culling, Bevy splits the depth prepass into two:
59
/// an *early* depth prepass and a *late* depth prepass. The early depth prepass
60
/// renders all the meshes that were visible last frame to produce a
61
/// conservative approximation of the depth buffer. Then, after producing an
62
/// acceleration structure known as a hierarchical Z-buffer or depth pyramid,
63
/// Bevy tests the bounding boxes of all meshes against that depth buffer. Those
64
/// that can be quickly proven to be behind the geometry rendered during the
65
/// early depth prepass are skipped entirely. The other potentially-visible
66
/// meshes are rendered during the late prepass, and finally all the visible
67
/// meshes are rendered as usual during the opaque, transparent, etc. passes.
68
///
69
/// Unlike other occlusion culling systems you may be familiar with, Bevy's
70
/// occlusion culling is fully dynamic and requires no baking step. The CPU
71
/// overhead is minimal. Large skinned meshes and other dynamic objects can
72
/// occlude other objects.
73
///
74
/// [*two-phase occlusion culling*]:
75
/// https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501
76
#[derive(Component, ExtractComponent, Clone, Copy, Default, Reflect)]
77
#[reflect(Component, Default, Clone)]
78
pub struct OcclusionCulling;
79
80
/// A render-world component that contains resources necessary to perform
81
/// occlusion culling on any view other than a camera.
82
///
83
/// Bevy automatically places this component on views created for shadow
84
/// mapping. You don't ordinarily need to add this component yourself.
85
#[derive(Clone, Component)]
86
pub struct OcclusionCullingSubview {
87
/// A texture view of the Z-buffer.
88
pub depth_texture_view: TextureView,
89
/// The size of the texture along both dimensions.
90
///
91
/// Because [`OcclusionCullingSubview`] is only currently used for shadow
92
/// maps, they're guaranteed to have sizes equal to a power of two, so we
93
/// don't have to store the two dimensions individually here.
94
pub depth_texture_size: u32,
95
}
96
97
/// A render-world component placed on each camera that stores references to all
98
/// entities other than cameras that need occlusion culling.
99
///
100
/// Bevy automatically places this component on cameras that are drawing
101
/// shadows, when those shadows come from lights with occlusion culling enabled.
102
/// You don't ordinarily need to add this component yourself.
103
#[derive(Clone, Component)]
104
pub struct OcclusionCullingSubviewEntities(pub Vec<Entity>);
105
106