Skip to content

Commit

Permalink
add standard material depth bias to pipeline (#7847)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
robtfm committed Mar 4, 2023
1 parent 465fff2 commit 6beca13
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
4 changes: 3 additions & 1 deletion crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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,
}

Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -420,13 +415,15 @@ impl AsBindGroupShaderType<StandardMaterialUniform> for StandardMaterial {
pub struct StandardMaterialKey {
normal_map: bool,
cull_mode: Option<Face>,
depth_bias: i32,
}

impl From<&StandardMaterial> for StandardMaterialKey {
fn from(material: &StandardMaterial) -> Self {
StandardMaterialKey {
normal_map: material.normal_map_texture.is_some(),
cull_mode: material.cull_mode,
depth_bias: material.depth_bias as i32,
}
}
}
Expand All @@ -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(())
}

Expand Down

0 comments on commit 6beca13

Please sign in to comment.