From 6beca135531368e8b26fb5f240e72b92545efc42 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Sat, 4 Mar 2023 12:29:09 +0000 Subject: [PATCH] add standard material depth bias to pipeline (#7847) # Objective the current depth bias only adjusts ordering, so it doesn't work for opaque meshes vs alpha-blend meshes, and it doesn't help when two meshes are infinitesimally offset from one another. ## Solution pass the material's depth bias into the pipeline depth stencil `constant` field. --- crates/bevy_pbr/src/material.rs | 4 +++- crates/bevy_pbr/src/pbr_material.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 82a477c57039d..9a2ead7c7232b 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -126,7 +126,8 @@ pub trait Material: AsBindGroup + Send + Sync + Clone + TypeUuid + Sized + 'stat #[inline] /// Add a bias to the view depth of the mesh which can be used to force a specific render order - /// for meshes with equal depth, to avoid z-fighting. + /// for meshes with similar depth, to avoid z-fighting. + /// The bias is in depth-texture units so large values may be needed to overcome small depth differences. fn depth_bias(&self) -> f32 { 0.0 } @@ -514,6 +515,7 @@ pub struct MaterialProperties { pub alpha_mode: AlphaMode, /// Add a bias to the view depth of the mesh which can be used to force a specific render order /// for meshes with equal depth, to avoid z-fighting. + /// The bias is in depth-texture units so large values may be needed to overcome small depth differences. pub depth_bias: f32, } diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index aa4519414f27e..a08a173a2801f 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -220,19 +220,14 @@ pub struct StandardMaterial { /// See [`AlphaMode`] for details. Defaults to [`AlphaMode::Opaque`]. pub alpha_mode: AlphaMode, - /// Re-arrange render ordering. + /// Adjust rendered depth. /// /// A material with a positive depth bias will render closer to the /// camera while negative values cause the material to render behind /// other objects. This is independent of the viewport. /// - /// `depth_bias` only affects render ordering. This means that for opaque materials, - /// `depth_bias` will only have any effect if two materials are overlapping, - /// which only serves as a [z-fighting] resolver. - /// - /// `depth_bias` can however reorder [`AlphaMode::Blend`] materials. - /// This is useful if your transparent materials are not rendering - /// in the expected order. + /// `depth_bias` affects render ordering and depth write operations + /// using the `wgpu::DepthBiasState::Constant` field. /// /// [z-fighting]: https://en.wikipedia.org/wiki/Z-fighting pub depth_bias: f32, @@ -420,6 +415,7 @@ impl AsBindGroupShaderType for StandardMaterial { pub struct StandardMaterialKey { normal_map: bool, cull_mode: Option, + depth_bias: i32, } impl From<&StandardMaterial> for StandardMaterialKey { @@ -427,6 +423,7 @@ impl From<&StandardMaterial> for StandardMaterialKey { StandardMaterialKey { normal_map: material.normal_map_texture.is_some(), cull_mode: material.cull_mode, + depth_bias: material.depth_bias as i32, } } } @@ -449,6 +446,9 @@ impl Material for StandardMaterial { if let Some(label) = &mut descriptor.label { *label = format!("pbr_{}", *label).into(); } + if let Some(depth_stencil) = descriptor.depth_stencil.as_mut() { + depth_stencil.bias.constant = key.bind_group_data.depth_bias; + } Ok(()) }