Fix Z-fighting between overlay and stencil with OpenGL wgpu back-end.
This commit is contained in:
parent
4a8d4409fe
commit
35032e05a3
@ -20,6 +20,7 @@ bevy = { version = "0.10", default-features = false, features = [
|
||||
bitfield = "0.14"
|
||||
interpolation = "0.2"
|
||||
thiserror = "1.0"
|
||||
wgpu-types = "0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
bevy = { version = "0.10", default-features = false, features = [
|
||||
|
11
src/draw.rs
11
src/draw.rs
@ -3,7 +3,9 @@ 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};
|
||||
@ -32,6 +34,7 @@ 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>,
|
||||
@ -52,7 +55,8 @@ pub(crate) fn queue_outline_stencil_mesh(
|
||||
|
||||
let base_key = PipelineKey::new()
|
||||
.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() {
|
||||
let rangefinder = view.rangefinder3d();
|
||||
@ -105,6 +109,7 @@ 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>,
|
||||
@ -129,7 +134,9 @@ pub(crate) fn queue_outline_volume_mesh(
|
||||
.get_id::<DrawOutline>()
|
||||
.unwrap();
|
||||
|
||||
let base_key = PipelineKey::new().with_msaa(*msaa);
|
||||
let base_key = PipelineKey::new()
|
||||
.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() {
|
||||
let view_mask = view_mask.copied().unwrap_or_default();
|
||||
|
@ -1,24 +1,32 @@
|
||||
#ifdef VOLUME
|
||||
struct FragmentOutput {
|
||||
@location(0) colour: vec4<f32>,
|
||||
#ifdef OPENGL_WORKAROUND
|
||||
@builtin(frag_depth) frag_depth: f32,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OutlineFragmentUniform {
|
||||
@align(16)
|
||||
colour: vec4<f32>,
|
||||
};
|
||||
|
||||
#ifdef VOLUME
|
||||
@group(3) @binding(1)
|
||||
var<uniform> fstage: OutlineFragmentUniform;
|
||||
|
||||
@fragment
|
||||
fn fragment() -> @location(0) vec4<f32> {
|
||||
return fstage.colour;
|
||||
}
|
||||
|
||||
#else
|
||||
// Stencil
|
||||
|
||||
@fragment
|
||||
fn fragment() {
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@fragment
|
||||
#ifdef OPENGL_WORKAROUND
|
||||
fn fragment(@location(0) normalised_depth: f32) -> FragmentOutput {
|
||||
#else
|
||||
fn fragment() -> FragmentOutput {
|
||||
#endif
|
||||
var out: FragmentOutput;
|
||||
#ifdef VOLUME
|
||||
out.colour = fstage.colour;
|
||||
#endif
|
||||
#ifdef OPENGL_WORKAROUND
|
||||
out.frag_depth = normalised_depth;
|
||||
#endif
|
||||
return out;
|
||||
}
|
@ -12,6 +12,13 @@ struct VertexInput {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) position: vec4<f32>,
|
||||
#ifdef OPENGL_WORKAROUND
|
||||
@location(0) normalised_depth: f32,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OutlineViewUniform {
|
||||
@align(16)
|
||||
scale: vec2<f32>,
|
||||
@ -53,7 +60,7 @@ fn model_origin_z(plane: vec3<f32>, view_proj: mat4x4<f32>) -> f32 {
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
|
||||
fn vertex(vertex: VertexInput) -> VertexOutput {
|
||||
#ifdef SKINNED
|
||||
let model = skin_model(vertex.joint_indexes, vertex.joint_weights);
|
||||
#else
|
||||
@ -72,5 +79,10 @@ fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
|
||||
let ndc_delta = vstage.offset * normalize(clip_norm.xy) * view_uniform.scale * clip_pos.w;
|
||||
let out_xy = clip_pos.xy + ndc_delta;
|
||||
#endif
|
||||
return vec4<f32>(out_xy, out_z, clip_pos.w);
|
||||
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);
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
@ -56,6 +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(crate) fn new() -> Self {
|
||||
@ -129,6 +130,11 @@ impl PipelineKey {
|
||||
self.set_hdr_format(hdr_format);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn with_opengl_workaround(mut self, opengl_workaround: bool) -> Self {
|
||||
self.set_opengl_workaround(opengl_workaround);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
@ -294,6 +300,11 @@ 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![mesh_layout.get_layout(&buffer_attrs)?];
|
||||
Ok(RenderPipelineDescriptor {
|
||||
vertex: VertexState {
|
||||
|
Loading…
Reference in New Issue
Block a user