Fix noisy depth values in flat mode.

This commit is contained in:
Robin KAY 2023-11-02 00:33:09 +00:00
parent 3740766157
commit 613e1ddde7
4 changed files with 17 additions and 48 deletions

View File

@ -3,9 +3,7 @@ use bevy::prelude::*;
use bevy::render::render_asset::RenderAssets;
use bevy::render::render_phase::{DrawFunctions, RenderPhase, SetItemPipeline};
use bevy::render::render_resource::{PipelineCache, SpecializedMeshPipelines};
use bevy::render::renderer::RenderAdapterInfo;
use bevy::render::view::{ExtractedView, RenderLayers};
use wgpu_types::Backend;
use crate::node::{OpaqueOutline, StencilOutline, TransparentOutline};
use crate::pipeline::{OutlinePipeline, PassType, PipelineKey};
@ -34,7 +32,6 @@ pub(crate) fn queue_outline_stencil_mesh(
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
pipeline_cache: Res<PipelineCache>,
render_meshes: Res<RenderAssets<Mesh>>,
adapter_info: Res<RenderAdapterInfo>,
material_meshes: Query<(
Entity,
&Handle<Mesh>,
@ -55,8 +52,7 @@ pub(crate) fn queue_outline_stencil_mesh(
let base_key = PipelineKey::new()
.with_msaa(*msaa)
.with_pass_type(PassType::Stencil)
.with_opengl_workaround(adapter_info.0.backend == Backend::Gl);
.with_pass_type(PassType::Stencil);
for (view, mut stencil_phase, view_mask) in views.iter_mut() {
let rangefinder = view.rangefinder3d();
@ -112,7 +108,6 @@ pub(crate) fn queue_outline_volume_mesh(
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
pipeline_cache: Res<PipelineCache>,
render_meshes: Res<RenderAssets<Mesh>>,
adapter_info: Res<RenderAdapterInfo>,
material_meshes: Query<(
Entity,
&Handle<Mesh>,
@ -137,9 +132,7 @@ pub(crate) fn queue_outline_volume_mesh(
.get_id::<DrawOutline>()
.unwrap();
let base_key = PipelineKey::new()
.with_msaa(*msaa)
.with_opengl_workaround(adapter_info.0.backend == Backend::Gl);
let base_key = PipelineKey::new().with_msaa(*msaa);
for (view, mut opaque_phase, mut transparent_phase, view_mask) in views.iter_mut() {
let view_mask = view_mask.copied().unwrap_or_default();

View File

@ -1,6 +1,6 @@
struct FragmentOutput {
@location(0) colour: vec4<f32>,
#ifdef OPENGL_WORKAROUND
#ifdef FLAT_DEPTH
@builtin(frag_depth) frag_depth: f32,
#endif
};
@ -16,8 +16,8 @@ var<uniform> fstage: OutlineFragmentUniform;
#endif
@fragment
#ifdef OPENGL_WORKAROUND
fn fragment(@location(0) normalised_depth: f32) -> FragmentOutput {
#ifdef FLAT_DEPTH
fn fragment(@location(0) @interpolate(flat) flat_depth: f32) -> FragmentOutput {
#else
fn fragment() -> FragmentOutput {
#endif
@ -25,8 +25,8 @@ fn fragment() -> FragmentOutput {
#ifdef VOLUME
out.colour = fstage.colour;
#endif
#ifdef OPENGL_WORKAROUND
out.frag_depth = normalised_depth;
#ifdef FLAT_DEPTH
out.frag_depth = flat_depth;
#endif
return out;
}

View File

@ -20,8 +20,8 @@ struct Vertex {
struct VertexOutput {
@builtin(position) position: vec4<f32>,
#ifdef OPENGL_WORKAROUND
@location(0) normalised_depth: f32,
#ifdef FLAT_DEPTH
@location(0) @interpolate(flat) flat_depth: f32,
#endif
};
@ -93,11 +93,6 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
let model = mesh.model;
#endif
let clip_pos = view.view_proj * (model * vec4<f32>(vertex.position, 1.0));
#ifdef FLAT_DEPTH
let out_z = model_origin_z(vstage.origin, view.view_proj) * clip_pos.w;
#else
let out_z = clip_pos.z;
#endif
#ifdef OFFSET_ZERO
let out_xy = clip_pos.xy;
#else
@ -106,9 +101,9 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
let out_xy = clip_pos.xy + ndc_delta;
#endif
var out: VertexOutput;
out.position = vec4<f32>(out_xy, out_z, clip_pos.w);
#ifdef OPENGL_WORKAROUND
out.normalised_depth = 0.5 + 0.5 * (out_z / clip_pos.w);
out.position = vec4<f32>(out_xy, clip_pos.zw);
#ifdef FLAT_DEPTH
out.flat_depth = model_origin_z(vstage.origin, view.view_proj);
#endif
return out;
}

View File

@ -56,8 +56,7 @@ impl PipelineKey {
depth_mode_int, set_depth_mode_int: 12, 11;
pub offset_zero, set_offset_zero: 13;
pub hdr_format, set_hdr_format: 14;
pub opengl_workaround, set_opengl_workaround: 15;
pub morph_targets, set_morph_targets: 16;
pub morph_targets, set_morph_targets: 15;
}
pub(crate) fn new() -> Self {
@ -132,11 +131,6 @@ impl PipelineKey {
self
}
pub(crate) fn with_opengl_workaround(mut self, opengl_workaround: bool) -> Self {
self.set_opengl_workaround(opengl_workaround);
self
}
pub(crate) fn with_morph_targets(mut self, morph_targets: bool) -> Self {
self.set_morph_targets(morph_targets);
self
@ -269,7 +263,9 @@ impl SpecializedMeshPipeline for OutlinePipeline {
bind_layouts.push(self.outline_view_bind_group_layout.clone());
let cull_mode;
if key.depth_mode() == DepthMode::Flat {
vertex_defs.push(ShaderDefVal::from("FLAT_DEPTH"));
let val = ShaderDefVal::from("FLAT_DEPTH");
vertex_defs.push(val.clone());
fragment_defs.push(val);
cull_mode = Some(Face::Back);
} else if key.pass_type() == PassType::Stencil {
cull_mode = Some(Face::Back);
@ -311,11 +307,6 @@ impl SpecializedMeshPipeline for OutlinePipeline {
bind_layouts.push(self.outline_volume_bind_group_layout.clone());
}
}
if key.opengl_workaround() {
let val = ShaderDefVal::from("OPENGL_WORKAROUND");
vertex_defs.push(val.clone());
fragment_defs.push(val);
}
let buffers = vec![layout.get_layout(&buffer_attrs)?];
Ok(RenderPipelineDescriptor {
vertex: VertexState {
@ -345,17 +336,7 @@ impl SpecializedMeshPipeline for OutlinePipeline {
depth_write_enabled: true,
depth_compare: CompareFunction::Greater,
stencil: StencilState::default(),
bias: if key.depth_mode() == DepthMode::Flat && key.pass_type() == PassType::Stencil
{
DepthBiasState {
// Values determined empirically
constant: 3,
slope_scale: 1.0,
..default()
}
} else {
default()
},
bias: DepthBiasState::default(),
}),
multisample: MultisampleState {
count: key.msaa().samples(),