Path: blob/main/crates/bevy_render/src/occlusion_culling/mod.rs
9354 views
//! GPU occlusion culling.1//!2//! See [`OcclusionCulling`] for a detailed description of occlusion culling in3//! Bevy.45use bevy_app::{App, Plugin};6use bevy_ecs::{component::Component, entity::Entity, prelude::ReflectComponent};7use bevy_reflect::{prelude::ReflectDefault, Reflect};8use bevy_shader::load_shader_library;910use crate::{extract_component::ExtractComponent, render_resource::TextureView};1112/// Enables GPU occlusion culling.13///14/// See [`OcclusionCulling`] for a detailed description of occlusion culling in15/// Bevy.16pub struct OcclusionCullingPlugin;1718impl Plugin for OcclusionCullingPlugin {19fn build(&self, app: &mut App) {20load_shader_library!(app, "mesh_preprocess_types.wgsl");21}22}2324/// Add this component to a view in order to enable GPU occlusion culling.25///26/// *Occlusion culling* allows Bevy to avoid rendering objects that are fully27/// behind other opaque or alpha tested objects. This is different from, and28/// complements, depth fragment rejection as the `DepthPrepass` enables. While29/// depth rejection allows Bevy to avoid rendering *pixels* that are behind30/// other objects, the GPU still has to examine those pixels to reject them,31/// which requires transforming the vertices of the objects and performing32/// skinning if the objects were skinned. Occlusion culling allows the GPU to go33/// a step further, avoiding even transforming the vertices of objects that it34/// can quickly prove to be behind other objects.35///36/// Occlusion culling inherently has some overhead, because Bevy must examine37/// the objects' bounding boxes, and create an acceleration structure38/// (hierarchical Z-buffer) to perform the occlusion tests. Therefore, occlusion39/// culling is disabled by default. Only enable it if you measure it to be a40/// speedup on your scene. Note that, because Bevy's occlusion culling runs on41/// the GPU and is quite efficient, it's rare for occlusion culling to result in42/// a significant slowdown.43///44/// Occlusion culling currently requires a `DepthPrepass`. If no depth prepass45/// is present on the view, the [`OcclusionCulling`] component will be ignored.46/// Additionally, occlusion culling is currently incompatible with deferred47/// shading; including both `DeferredPrepass` and [`OcclusionCulling`] results48/// in unspecified behavior.49///50/// The algorithm that Bevy uses is known as [*two-phase occlusion culling*].51/// When you enable occlusion culling, Bevy splits the depth prepass into two:52/// an *early* depth prepass and a *late* depth prepass. The early depth prepass53/// renders all the meshes that were visible last frame to produce a54/// conservative approximation of the depth buffer. Then, after producing an55/// acceleration structure known as a hierarchical Z-buffer or depth pyramid,56/// Bevy tests the bounding boxes of all meshes against that depth buffer. Those57/// that can be quickly proven to be behind the geometry rendered during the58/// early depth prepass are skipped entirely. The other potentially-visible59/// meshes are rendered during the late prepass, and finally all the visible60/// meshes are rendered as usual during the opaque, transparent, etc. passes.61///62/// Unlike other occlusion culling systems you may be familiar with, Bevy's63/// occlusion culling is fully dynamic and requires no baking step. The CPU64/// overhead is minimal. Large skinned meshes and other dynamic objects can65/// occlude other objects.66///67/// [*two-phase occlusion culling*]:68/// https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad50169#[derive(Component, ExtractComponent, Clone, Copy, Default, Reflect)]70#[reflect(Component, Default, Clone)]71pub struct OcclusionCulling;7273/// A render-world component that contains resources necessary to perform74/// occlusion culling on any view other than a camera.75///76/// Bevy automatically places this component on views created for shadow77/// mapping. You don't ordinarily need to add this component yourself.78#[derive(Clone, Component)]79pub struct OcclusionCullingSubview {80/// A texture view of the Z-buffer.81pub depth_texture_view: TextureView,82/// The size of the texture along both dimensions.83///84/// Because [`OcclusionCullingSubview`] is only currently used for shadow85/// maps, they're guaranteed to have sizes equal to a power of two, so we86/// don't have to store the two dimensions individually here.87pub depth_texture_size: u32,88}8990/// A render-world component placed on each camera that stores references to all91/// entities other than cameras that need occlusion culling.92///93/// Bevy automatically places this component on cameras that are drawing94/// shadows, when those shadows come from lights with occlusion culling enabled.95/// You don't ordinarily need to add this component yourself.96#[derive(Clone, Component)]97pub struct OcclusionCullingSubviewEntities(pub Vec<Entity>);9899100