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.
This commit is contained in:
robtfm 2023-03-04 12:29:09 +00:00
parent 465fff2b01
commit 6beca13553
2 changed files with 11 additions and 9 deletions

View File

@ -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,
}

View File

@ -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<StandardMaterialUniform> for StandardMaterial {
pub struct StandardMaterialKey {
normal_map: bool,
cull_mode: Option<Face>,
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(())
}