diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 537026524b51d..f96df74313834 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -74,6 +74,14 @@ pub trait Material: Asset + RenderAsset { &[] } + #[allow(unused_variables)] + #[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. + fn depth_bias(material: &::PreparedAsset) -> f32 { + 0.0 + } + /// Customizes the default [`RenderPipelineDescriptor`]. #[allow(unused_variables)] #[inline] @@ -125,11 +133,15 @@ impl SpecializedMaterial for M { ::fragment_shader(asset_server) } - #[allow(unused_variables)] #[inline] fn dynamic_uniform_indices(material: &::PreparedAsset) -> &[u32] { ::dynamic_uniform_indices(material) } + + #[inline] + fn depth_bias(material: &::PreparedAsset) -> f32 { + ::depth_bias(material) + } } /// Materials are used alongside [`MaterialPlugin`] and [`MaterialMeshBundle`](crate::MaterialMeshBundle) @@ -186,6 +198,14 @@ pub trait SpecializedMaterial: Asset + RenderAsset { fn dynamic_uniform_indices(material: &::PreparedAsset) -> &[u32] { &[] } + + #[allow(unused_variables)] + #[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. + fn depth_bias(material: &::PreparedAsset) -> f32 { + 0.0 + } } /// Adds the necessary ECS resources and render logic to enable rendering entities using the given [`SpecializedMaterial`] @@ -375,7 +395,8 @@ pub fn queue_material_meshes( // NOTE: row 2 of the inverse view matrix dotted with column 3 of the model matrix // gives the z component of translation of the mesh in view space - let mesh_z = inverse_view_row_2.dot(mesh_uniform.transform.col(3)); + let bias = M::depth_bias(material); + let mesh_z = inverse_view_row_2.dot(mesh_uniform.transform.col(3)) + bias; match alpha_mode { AlphaMode::Opaque => { opaque_phase.add(Opaque3d { diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 803960a647844..b1e90f8665a0a 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -59,6 +59,7 @@ pub struct StandardMaterial { pub cull_mode: Option, pub unlit: bool, pub alpha_mode: AlphaMode, + pub depth_bias: f32, } impl Default for StandardMaterial { @@ -88,6 +89,7 @@ impl Default for StandardMaterial { cull_mode: Some(Face::Back), unlit: false, alpha_mode: AlphaMode::Opaque, + depth_bias: 0.0, } } } @@ -163,6 +165,7 @@ pub struct GpuStandardMaterial { pub flags: StandardMaterialFlags, pub base_color_texture: Option>, pub alpha_mode: AlphaMode, + pub depth_bias: f32, pub cull_mode: Option, } @@ -331,6 +334,7 @@ impl RenderAsset for StandardMaterial { has_normal_map, base_color_texture: material.base_color_texture, alpha_mode: material.alpha_mode, + depth_bias: material.depth_bias, cull_mode: material.cull_mode, }) } @@ -497,4 +501,9 @@ impl SpecializedMaterial for StandardMaterial { fn alpha_mode(render_asset: &::PreparedAsset) -> AlphaMode { render_asset.alpha_mode } + + #[inline] + fn depth_bias(material: &::PreparedAsset) -> f32 { + material.depth_bias + } }