Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MAY_DISCARD shader def, enabling early depth tests for most cases #6697

Merged
merged 6 commits into from
May 29, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,14 @@ pub fn queue_material_meshes<M: Material>(
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
| view_key;
let alpha_mode = material.properties.alpha_mode;
if let AlphaMode::Blend = alpha_mode {
mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS;
match alpha_mode {
AlphaMode::Blend => {
mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS;
}
AlphaMode::Mask(_) => {
mesh_key |= MeshPipelineKey::MAY_DISCARD;
}
_ => {}
}

let pipeline_id = pipelines.specialize(
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ bitflags::bitflags! {
const HDR = (1 << 1);
const TONEMAP_IN_SHADER = (1 << 2);
const DEBAND_DITHER = (1 << 3);
const MAY_DISCARD = (1 << 4); // Guards shader codepaths that may discard, allowing early depth tests in most cases
// See: https://www.khronos.org/opengl/wiki/Early_Fragment_Test
const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS;
const PRIMITIVE_TOPOLOGY_RESERVED_BITS = Self::PRIMITIVE_TOPOLOGY_MASK_BITS << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
}
Expand Down Expand Up @@ -644,6 +646,10 @@ impl SpecializedMeshPipeline for MeshPipeline {
}
}

if key.contains(MeshPipelineKey::MAY_DISCARD) {
shader_defs.push("MAY_DISCARD".to_string());
}

let format = match key.contains(MeshPipelineKey::HDR) {
true => ViewTarget::TEXTURE_FORMAT_HDR,
false => TextureFormat::bevy_default(),
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ struct FragmentInput {
};

@fragment
// NOTE: in the future, if we do depth writes, we'll also need to disable
coreh marked this conversation as resolved.
Show resolved Hide resolved
// `@early_depth_test` for them, via a similar def (e.g. `MAY_DEPTH_WRITE`)
#ifndef MAY_DISCARD
@early_depth_test
#endif
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
var output_color: vec4<f32> = material.base_color;
#ifdef VERTEX_COLORS
Expand Down
10 changes: 7 additions & 3 deletions crates/bevy_pbr/src/render/pbr_functions.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ fn alpha_discard(material: StandardMaterial, output_color: vec4<f32>) -> vec4<f3
if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) {
// NOTE: If rendering as opaque, alpha should be ignored so set to 1.0
color.a = 1.0;
} else if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) {
}

#ifdef MAY_DISCARD
else if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) {
if (color.a >= material.alpha_cutoff) {
// NOTE: If rendering as masked alpha and >= the cutoff, render as fully opaque
color.a = 1.0;
} else {
// NOTE: output_color.a < in.material.alpha_cutoff should not is not rendered
// NOTE: This and any other discards mean that early-z testing cannot be done!
// NOTE: output_color.a < in.material.alpha_cutoff should not be rendered
discard;
}
}
#endif

return color;
}

Expand Down