Fix noisy depth values in flat mode.
This commit is contained in:
parent
3740766157
commit
613e1ddde7
11
src/draw.rs
11
src/draw.rs
|
@ -3,9 +3,7 @@ use bevy::prelude::*;
|
||||||
use bevy::render::render_asset::RenderAssets;
|
use bevy::render::render_asset::RenderAssets;
|
||||||
use bevy::render::render_phase::{DrawFunctions, RenderPhase, SetItemPipeline};
|
use bevy::render::render_phase::{DrawFunctions, RenderPhase, SetItemPipeline};
|
||||||
use bevy::render::render_resource::{PipelineCache, SpecializedMeshPipelines};
|
use bevy::render::render_resource::{PipelineCache, SpecializedMeshPipelines};
|
||||||
use bevy::render::renderer::RenderAdapterInfo;
|
|
||||||
use bevy::render::view::{ExtractedView, RenderLayers};
|
use bevy::render::view::{ExtractedView, RenderLayers};
|
||||||
use wgpu_types::Backend;
|
|
||||||
|
|
||||||
use crate::node::{OpaqueOutline, StencilOutline, TransparentOutline};
|
use crate::node::{OpaqueOutline, StencilOutline, TransparentOutline};
|
||||||
use crate::pipeline::{OutlinePipeline, PassType, PipelineKey};
|
use crate::pipeline::{OutlinePipeline, PassType, PipelineKey};
|
||||||
|
@ -34,7 +32,6 @@ pub(crate) fn queue_outline_stencil_mesh(
|
||||||
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
|
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
|
||||||
pipeline_cache: Res<PipelineCache>,
|
pipeline_cache: Res<PipelineCache>,
|
||||||
render_meshes: Res<RenderAssets<Mesh>>,
|
render_meshes: Res<RenderAssets<Mesh>>,
|
||||||
adapter_info: Res<RenderAdapterInfo>,
|
|
||||||
material_meshes: Query<(
|
material_meshes: Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Handle<Mesh>,
|
&Handle<Mesh>,
|
||||||
|
@ -55,8 +52,7 @@ pub(crate) fn queue_outline_stencil_mesh(
|
||||||
|
|
||||||
let base_key = PipelineKey::new()
|
let base_key = PipelineKey::new()
|
||||||
.with_msaa(*msaa)
|
.with_msaa(*msaa)
|
||||||
.with_pass_type(PassType::Stencil)
|
.with_pass_type(PassType::Stencil);
|
||||||
.with_opengl_workaround(adapter_info.0.backend == Backend::Gl);
|
|
||||||
|
|
||||||
for (view, mut stencil_phase, view_mask) in views.iter_mut() {
|
for (view, mut stencil_phase, view_mask) in views.iter_mut() {
|
||||||
let rangefinder = view.rangefinder3d();
|
let rangefinder = view.rangefinder3d();
|
||||||
|
@ -112,7 +108,6 @@ pub(crate) fn queue_outline_volume_mesh(
|
||||||
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
|
mut pipelines: ResMut<SpecializedMeshPipelines<OutlinePipeline>>,
|
||||||
pipeline_cache: Res<PipelineCache>,
|
pipeline_cache: Res<PipelineCache>,
|
||||||
render_meshes: Res<RenderAssets<Mesh>>,
|
render_meshes: Res<RenderAssets<Mesh>>,
|
||||||
adapter_info: Res<RenderAdapterInfo>,
|
|
||||||
material_meshes: Query<(
|
material_meshes: Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&Handle<Mesh>,
|
&Handle<Mesh>,
|
||||||
|
@ -137,9 +132,7 @@ pub(crate) fn queue_outline_volume_mesh(
|
||||||
.get_id::<DrawOutline>()
|
.get_id::<DrawOutline>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let base_key = PipelineKey::new()
|
let base_key = PipelineKey::new().with_msaa(*msaa);
|
||||||
.with_msaa(*msaa)
|
|
||||||
.with_opengl_workaround(adapter_info.0.backend == Backend::Gl);
|
|
||||||
|
|
||||||
for (view, mut opaque_phase, mut transparent_phase, view_mask) in views.iter_mut() {
|
for (view, mut opaque_phase, mut transparent_phase, view_mask) in views.iter_mut() {
|
||||||
let view_mask = view_mask.copied().unwrap_or_default();
|
let view_mask = view_mask.copied().unwrap_or_default();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
struct FragmentOutput {
|
struct FragmentOutput {
|
||||||
@location(0) colour: vec4<f32>,
|
@location(0) colour: vec4<f32>,
|
||||||
#ifdef OPENGL_WORKAROUND
|
#ifdef FLAT_DEPTH
|
||||||
@builtin(frag_depth) frag_depth: f32,
|
@builtin(frag_depth) frag_depth: f32,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -16,8 +16,8 @@ var<uniform> fstage: OutlineFragmentUniform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
#ifdef OPENGL_WORKAROUND
|
#ifdef FLAT_DEPTH
|
||||||
fn fragment(@location(0) normalised_depth: f32) -> FragmentOutput {
|
fn fragment(@location(0) @interpolate(flat) flat_depth: f32) -> FragmentOutput {
|
||||||
#else
|
#else
|
||||||
fn fragment() -> FragmentOutput {
|
fn fragment() -> FragmentOutput {
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,8 +25,8 @@ fn fragment() -> FragmentOutput {
|
||||||
#ifdef VOLUME
|
#ifdef VOLUME
|
||||||
out.colour = fstage.colour;
|
out.colour = fstage.colour;
|
||||||
#endif
|
#endif
|
||||||
#ifdef OPENGL_WORKAROUND
|
#ifdef FLAT_DEPTH
|
||||||
out.frag_depth = normalised_depth;
|
out.frag_depth = flat_depth;
|
||||||
#endif
|
#endif
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
|
@ -20,8 +20,8 @@ struct Vertex {
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position) position: vec4<f32>,
|
@builtin(position) position: vec4<f32>,
|
||||||
#ifdef OPENGL_WORKAROUND
|
#ifdef FLAT_DEPTH
|
||||||
@location(0) normalised_depth: f32,
|
@location(0) @interpolate(flat) flat_depth: f32,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,11 +93,6 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
|
||||||
let model = mesh.model;
|
let model = mesh.model;
|
||||||
#endif
|
#endif
|
||||||
let clip_pos = view.view_proj * (model * vec4<f32>(vertex.position, 1.0));
|
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
|
#ifdef OFFSET_ZERO
|
||||||
let out_xy = clip_pos.xy;
|
let out_xy = clip_pos.xy;
|
||||||
#else
|
#else
|
||||||
|
@ -106,9 +101,9 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
|
||||||
let out_xy = clip_pos.xy + ndc_delta;
|
let out_xy = clip_pos.xy + ndc_delta;
|
||||||
#endif
|
#endif
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.position = vec4<f32>(out_xy, out_z, clip_pos.w);
|
out.position = vec4<f32>(out_xy, clip_pos.zw);
|
||||||
#ifdef OPENGL_WORKAROUND
|
#ifdef FLAT_DEPTH
|
||||||
out.normalised_depth = 0.5 + 0.5 * (out_z / clip_pos.w);
|
out.flat_depth = model_origin_z(vstage.origin, view.view_proj);
|
||||||
#endif
|
#endif
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,7 @@ impl PipelineKey {
|
||||||
depth_mode_int, set_depth_mode_int: 12, 11;
|
depth_mode_int, set_depth_mode_int: 12, 11;
|
||||||
pub offset_zero, set_offset_zero: 13;
|
pub offset_zero, set_offset_zero: 13;
|
||||||
pub hdr_format, set_hdr_format: 14;
|
pub hdr_format, set_hdr_format: 14;
|
||||||
pub opengl_workaround, set_opengl_workaround: 15;
|
pub morph_targets, set_morph_targets: 15;
|
||||||
pub morph_targets, set_morph_targets: 16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
|
@ -132,11 +131,6 @@ impl PipelineKey {
|
||||||
self
|
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 {
|
pub(crate) fn with_morph_targets(mut self, morph_targets: bool) -> Self {
|
||||||
self.set_morph_targets(morph_targets);
|
self.set_morph_targets(morph_targets);
|
||||||
self
|
self
|
||||||
|
@ -269,7 +263,9 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
||||||
bind_layouts.push(self.outline_view_bind_group_layout.clone());
|
bind_layouts.push(self.outline_view_bind_group_layout.clone());
|
||||||
let cull_mode;
|
let cull_mode;
|
||||||
if key.depth_mode() == DepthMode::Flat {
|
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);
|
cull_mode = Some(Face::Back);
|
||||||
} else if key.pass_type() == PassType::Stencil {
|
} else if key.pass_type() == PassType::Stencil {
|
||||||
cull_mode = Some(Face::Back);
|
cull_mode = Some(Face::Back);
|
||||||
|
@ -311,11 +307,6 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
||||||
bind_layouts.push(self.outline_volume_bind_group_layout.clone());
|
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)?];
|
let buffers = vec![layout.get_layout(&buffer_attrs)?];
|
||||||
Ok(RenderPipelineDescriptor {
|
Ok(RenderPipelineDescriptor {
|
||||||
vertex: VertexState {
|
vertex: VertexState {
|
||||||
|
@ -345,17 +336,7 @@ impl SpecializedMeshPipeline for OutlinePipeline {
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::Greater,
|
depth_compare: CompareFunction::Greater,
|
||||||
stencil: StencilState::default(),
|
stencil: StencilState::default(),
|
||||||
bias: if key.depth_mode() == DepthMode::Flat && key.pass_type() == PassType::Stencil
|
bias: DepthBiasState::default(),
|
||||||
{
|
|
||||||
DepthBiasState {
|
|
||||||
// Values determined empirically
|
|
||||||
constant: 3,
|
|
||||||
slope_scale: 1.0,
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
default()
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
multisample: MultisampleState {
|
multisample: MultisampleState {
|
||||||
count: key.msaa().samples(),
|
count: key.msaa().samples(),
|
||||||
|
|
Loading…
Reference in New Issue