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

Native unclipped depth on supported platforms #16095

Merged
merged 11 commits into from
Dec 3, 2024
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
21 changes: 18 additions & 3 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ pub struct PrepassPipeline<M: Material> {
pub deferred_material_vertex_shader: Option<Handle<Shader>>,
pub deferred_material_fragment_shader: Option<Handle<Shader>>,
pub material_pipeline: MaterialPipeline<M>,
pub depth_clip_control_supported: bool,
_marker: PhantomData<M>,
}

Expand Down Expand Up @@ -289,6 +290,10 @@ impl<M: Material> FromWorld for PrepassPipeline<M> {

let mesh_pipeline = world.resource::<MeshPipeline>();

let depth_clip_control_supported = render_device
.features()
.contains(WgpuFeatures::DEPTH_CLIP_CONTROL);

PrepassPipeline {
view_layout_motion_vectors,
view_layout_no_motion_vectors,
Expand All @@ -315,6 +320,7 @@ impl<M: Material> FromWorld for PrepassPipeline<M> {
},
material_layout: M::bind_group_layout(render_device),
material_pipeline: world.resource::<MaterialPipeline<M>>().clone(),
depth_clip_control_supported,
_marker: PhantomData,
}
}
Expand All @@ -328,7 +334,7 @@ where

fn specialize(
&self,
key: Self::Key,
mut key: Self::Key,
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
layout: &MeshVertexBufferLayoutRef,
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
let mut bind_group_layouts = vec![if key
Expand All @@ -341,6 +347,15 @@ where
}];
let mut shader_defs = Vec::new();
let mut vertex_attributes = Vec::new();
let mut unclipped_depth = false;

// Remove depth clamp in fragment shader if GPU supports it natively
if key.mesh_key.contains(MeshPipelineKey::DEPTH_CLAMP_ORTHO)
&& self.depth_clip_control_supported
{
key.mesh_key.remove(MeshPipelineKey::DEPTH_CLAMP_ORTHO);
unclipped_depth = true;
}

// Let the shader code know that it's running in a prepass pipeline.
// (PBR code will use this to detect that it's running in deferred mode,
Expand Down Expand Up @@ -489,7 +504,7 @@ where

// The fragment shader is only used when the normal prepass or motion vectors prepass
// is enabled or the material uses alpha cutoff values and doesn't rely on the standard
// prepass shader or we are clamping the orthographic depth.
// prepass shader or we are clamping the orthographic depth in the fragment shader.
let fragment_required = !targets.is_empty()
|| key.mesh_key.contains(MeshPipelineKey::DEPTH_CLAMP_ORTHO)
|| (key.mesh_key.contains(MeshPipelineKey::MAY_DISCARD)
Expand Down Expand Up @@ -544,7 +559,7 @@ where
strip_index_format: None,
front_face: FrontFace::Ccw,
cull_mode: None,
unclipped_depth: false,
unclipped_depth,
polygon_mode: PolygonMode::Fill,
conservative: false,
},
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/prepass/prepass.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
out.world_position = mesh_functions::mesh_position_local_to_world(world_from_local, vec4<f32>(vertex.position, 1.0));
out.position = position_world_to_clip(out.world_position.xyz);
#ifdef DEPTH_CLAMP_ORTHO
out.clip_position_unclamped = out.position;
out.clip_z_unclamped = out.position.z;
out.position.z = min(out.position.z, 1.0);
#endif // DEPTH_CLAMP_ORTHO

Expand Down Expand Up @@ -174,7 +174,7 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
#endif

#ifdef DEPTH_CLAMP_ORTHO
out.frag_depth = in.clip_position_unclamped.z;
out.frag_depth = in.clip_z_unclamped;
#endif // DEPTH_CLAMP_ORTHO

#ifdef MOTION_VECTOR_PREPASS
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/prepass/prepass_io.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct VertexOutput {
#endif

#ifdef DEPTH_CLAMP_ORTHO
@location(6) clip_position_unclamped: vec4<f32>,
@location(6) clip_z_unclamped: f32,
#endif // DEPTH_CLAMP_ORTHO
#ifdef VERTEX_OUTPUT_INSTANCE_INDEX
@location(7) instance_index: u32,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/render/pbr_prepass.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn fragment(
var out: prepass_io::FragmentOutput;

#ifdef DEPTH_CLAMP_ORTHO
out.frag_depth = in.clip_position_unclamped.z;
out.frag_depth = in.clip_z_unclamped;
#endif // DEPTH_CLAMP_ORTHO

#ifdef NORMAL_PREPASS
Expand Down