Skip to content

Commit

Permalink
Merge pull request #1 from JMS55/depth-prepass
Browse files Browse the repository at this point in the history
  • Loading branch information
IceSentry committed Oct 13, 2022
2 parents 9754bae + c0d528a commit 0b9f67b
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 174 deletions.
34 changes: 22 additions & 12 deletions crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,25 @@ use bevy_render::{
#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;

/// Add a `DepthPrepassSettings` component to a view to perform a depth prepass and use it in a main
/// pass to reduce overdraw for opaque meshes.
/// Add a `PrepassSettings` component to a view to perform a depth and/or normal prepass.
/// These textures are useful for reducing overdraw in the main pass, and screen-space effects.
#[derive(Clone, Component)]
pub struct DepthPrepassSettings {
/// if true then depth values will be copied to a separate texture available to the main pass
pub depth_resource: bool,
/// If true then vertex world normals will be output from the depth prepass for use in subsequent passes.
pub struct PrepassSettings {
/// If true then depth values will be copied to a separate texture available to the main pass.
pub output_depth: bool,
/// If true then vertex world normals will be copied to a separate texture available to the main pass
pub output_normals: bool,
}

impl Default for PrepassSettings {
fn default() -> Self {
Self {
output_depth: true,
output_normals: true,
}
}
}

use super::Camera3dDepthLoadOp;

pub struct MainPass3dNode {
Expand All @@ -36,7 +45,7 @@ pub struct MainPass3dNode {
&'static Camera3d,
&'static ViewTarget,
&'static ViewDepthTexture,
Option<&'static DepthPrepassSettings>,
Option<&'static PrepassSettings>,
),
With<ExtractedView>,
>,
Expand Down Expand Up @@ -76,7 +85,7 @@ impl Node for MainPass3dNode {
camera_3d,
target,
depth,
maybe_depth_prepass_settings,
maybe_prepass_settings,
) = match self.query.get_manual(world, view_entity) {
Ok(query) => query,
Err(_) => {
Expand Down Expand Up @@ -109,10 +118,11 @@ impl Node for MainPass3dNode {
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
depth_ops: Some(Operations {
// NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections.
load: if maybe_depth_prepass_settings.is_some() {
Camera3dDepthLoadOp::Load
} else {
camera_3d.depth_load_op.clone()
load: match maybe_prepass_settings {
Some(PrepassSettings {
output_depth: true, ..
}) => Camera3dDepthLoadOp::Load,
_ => camera_3d.depth_load_op.clone(),
}
.into(),
store: true,
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_core_pipeline/src/core_3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ pub fn prepare_core_3d_depth_textures(
msaa: Res<Msaa>,
render_device: Res<RenderDevice>,
views_3d: Query<
(Entity, &ExtractedCamera, Option<&DepthPrepassSettings>),
(Entity, &ExtractedCamera, Option<&PrepassSettings>),
(
With<RenderPhase<Opaque3d>>,
With<RenderPhase<AlphaMask3d>>,
Expand All @@ -243,7 +243,7 @@ pub fn prepare_core_3d_depth_textures(
.entry(camera.target.clone())
.or_insert_with(|| {
let mut usage = TextureUsages::RENDER_ATTACHMENT;
if maybe_prepass.map_or(false, |prepass_settings| prepass_settings.depth_resource) {
if maybe_prepass.map_or(false, |prepass_settings| prepass_settings.output_depth) {
usage |= TextureUsages::COPY_SRC;
}
texture_cache.get(
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ impl Plugin for PbrPlugin {
.register_type::<SpotLight>()
.add_plugin(MeshRenderPlugin)
.add_plugin(MaterialPlugin::<StandardMaterial>::default())
.add_plugin(DepthPrepassPlugin::<StandardMaterial>::default())
.register_type::<AmbientLight>()
.register_type::<DirectionalLightShadowMap>()
.register_type::<PointLightShadowMap>()
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
AlphaMode, DrawMesh, MeshPipeline, MeshPipelineKey, MeshUniform, SetMeshBindGroup,
SetMeshViewBindGroup,
AlphaMode, DrawMesh, MeshPipeline, MeshPipelineKey, MeshUniform, PrepassPlugin,
SetMeshBindGroup, SetMeshViewBindGroup,
};
use bevy_app::{App, Plugin};
use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
Expand Down Expand Up @@ -178,7 +178,8 @@ where
{
fn build(&self, app: &mut App) {
app.add_asset::<M>()
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible());
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible())
.add_plugin(PrepassPlugin::<M>::default());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_command::<Transparent3d, DrawMaterial<M>>()
Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,8 @@ bitflags::bitflags! {
pub struct MeshPipelineKey: u32 {
const NONE = 0;
const TRANSPARENT_MAIN_PASS = (1 << 0);
const DEPTH_PREPASS = (1 << 1);
const DEPTH_PREPASS_NORMALS = (1 << 2);
const PREPASS_DEPTH = (1 << 1);
const PREPASS_NORMALS = (1 << 2);
const ALPHA_MASK = (1 << 3);
const MSAA_RESERVED_BITS = MeshPipelineKey::MSAA_MASK_BITS << MeshPipelineKey::MSAA_SHIFT_BITS;
const PRIMITIVE_TOPOLOGY_RESERVED_BITS = MeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS << MeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
Expand Down Expand Up @@ -681,7 +681,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
// For the opaque and alpha mask passes, fragments that are closer will replace
// the current fragment value in the output and the depth is written to the
// depth buffer
depth_write_enabled = !key.contains(MeshPipelineKey::DEPTH_PREPASS);
depth_write_enabled = !key.contains(MeshPipelineKey::PREPASS_DEPTH);
}

Ok(RenderPipelineDescriptor {
Expand Down Expand Up @@ -714,7 +714,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
depth_stencil: Some(DepthStencilState {
format: TextureFormat::Depth32Float,
depth_write_enabled,
depth_compare: if key.contains(MeshPipelineKey::DEPTH_PREPASS) {
depth_compare: if key.contains(MeshPipelineKey::PREPASS_DEPTH) {
CompareFunction::Equal
} else {
CompareFunction::GreaterEqual
Expand Down Expand Up @@ -866,23 +866,23 @@ pub fn queue_mesh_view_bind_groups(
for (entity, view_shadow_bindings, view_cluster_bindings, maybe_prepass_textures) in &views
{
let depth_view = if let Some(ViewPrepassTextures {
depth: Some(depth_prepass),
depth: Some(prepass_depth_texture),
..
}) = &maybe_prepass_textures
{
&depth_prepass.default_view
&prepass_depth_texture.default_view
} else {
&fallback_depths
.image_for_samplecount(msaa.samples)
.texture_view
};

let normal_view = if let Some(ViewPrepassTextures {
normal: Some(normal_prepass),
normals: Some(prepass_normals_texture),
..
}) = &maybe_prepass_textures
{
&normal_prepass.default_view
&prepass_normals_texture.default_view
} else {
&fallback_images
.image_for_samplecount(msaa.samples)
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod depth_prepass;
mod light;
mod mesh;
mod prepass;

pub use depth_prepass::*;
pub use light::*;
pub use mesh::*;
pub use prepass::*;
Loading

0 comments on commit 0b9f67b

Please sign in to comment.