add depth_bias to SpecializedMaterial (#4101)

# Objective

allow meshes with equal z-depth to be rendered in a chosen order / avoid z-fighting

## Solution

add a depth_bias to SpecializedMaterial that is added to the mesh depth used for render-ordering.
This commit is contained in:
robtfm 2022-05-31 02:02:49 +00:00
parent f000c2b951
commit ee4bcbea3c
2 changed files with 32 additions and 2 deletions

View file

@ -74,6 +74,14 @@ pub trait Material: Asset + RenderAsset + Sized {
&[]
}
#[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: &<Self as RenderAsset>::PreparedAsset) -> f32 {
0.0
}
/// Customizes the default [`RenderPipelineDescriptor`].
#[allow(unused_variables)]
#[inline]
@ -127,11 +135,15 @@ impl<M: Material> SpecializedMaterial for M {
<M as Material>::fragment_shader(asset_server)
}
#[allow(unused_variables)]
#[inline]
fn dynamic_uniform_indices(material: &<Self as RenderAsset>::PreparedAsset) -> &[u32] {
<M as Material>::dynamic_uniform_indices(material)
}
#[inline]
fn depth_bias(material: &<Self as RenderAsset>::PreparedAsset) -> f32 {
<M as Material>::depth_bias(material)
}
}
/// Materials are used alongside [`MaterialPlugin`] and [`MaterialMeshBundle`](crate::MaterialMeshBundle)
@ -189,6 +201,14 @@ pub trait SpecializedMaterial: Asset + RenderAsset + Sized {
fn dynamic_uniform_indices(material: &<Self as RenderAsset>::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: &<Self as RenderAsset>::PreparedAsset) -> f32 {
0.0
}
}
/// Adds the necessary ECS resources and render logic to enable rendering entities using the given [`SpecializedMaterial`]
@ -378,7 +398,8 @@ pub fn queue_material_meshes<M: SpecializedMaterial>(
// 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 {

View file

@ -59,6 +59,7 @@ pub struct StandardMaterial {
pub cull_mode: Option<Face>,
pub unlit: bool,
pub alpha_mode: AlphaMode,
pub depth_bias: f32,
}
impl Default for StandardMaterial {
@ -89,6 +90,7 @@ impl Default for StandardMaterial {
cull_mode: Some(Face::Back),
unlit: false,
alpha_mode: AlphaMode::Opaque,
depth_bias: 0.0,
}
}
}
@ -171,6 +173,7 @@ pub struct GpuStandardMaterial {
pub flags: StandardMaterialFlags,
pub base_color_texture: Option<Handle<Image>>,
pub alpha_mode: AlphaMode,
pub depth_bias: f32,
pub cull_mode: Option<Face>,
}
@ -361,6 +364,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,
})
}
@ -526,4 +530,9 @@ impl SpecializedMaterial for StandardMaterial {
fn alpha_mode(render_asset: &<Self as RenderAsset>::PreparedAsset) -> AlphaMode {
render_asset.alpha_mode
}
#[inline]
fn depth_bias(material: &<Self as RenderAsset>::PreparedAsset) -> f32 {
material.depth_bias
}
}