From 0df3735906445a653547b5639479fd8c2ec5b71e Mon Sep 17 00:00:00 2001 From: Robin KAY Date: Tue, 7 Mar 2023 23:46:58 +0000 Subject: [PATCH] Fix bad clipping of triangles behind the camera. --- examples/animated_fox.rs | 15 +++++++++------ src/outline.wgsl | 10 ++++------ src/pipeline.rs | 9 ++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/examples/animated_fox.rs b/examples/animated_fox.rs index cb2d921..68d738d 100644 --- a/examples/animated_fox.rs +++ b/examples/animated_fox.rs @@ -1,6 +1,6 @@ use std::f32::consts::PI; -use bevy::{prelude::*, window::close_on_esc}; +use bevy::{prelude::*, scene::SceneInstance, window::close_on_esc}; use bevy_mod_outline::{ AutoGenerateOutlineNormalsPlugin, OutlineBundle, OutlinePlugin, OutlineVolume, }; @@ -66,15 +66,17 @@ fn setup( // Once the scene is loaded, start the animation and add an outline fn setup_scene_once_loaded( mut commands: Commands, + scene_query: Query<&SceneInstance>, + scene_manager: Res, + mut player_query: Query<&mut AnimationPlayer>, animation: Res, - mut player: Query<&mut AnimationPlayer>, - entities: Query>>, mut done: Local, ) { if !*done { - if let Ok(mut player) = player.get_single_mut() { - player.play(animation.0.clone_weak()).repeat(); - for entity in entities.iter() { + if let (Ok(scene), Ok(mut player)) = + (scene_query.get_single(), player_query.get_single_mut()) + { + for entity in scene_manager.iter_instance_entities(**scene) { commands.entity(entity).insert(OutlineBundle { outline: OutlineVolume { visible: true, @@ -84,6 +86,7 @@ fn setup_scene_once_loaded( ..default() }); } + player.play(animation.0.clone_weak()).repeat(); *done = true; } } diff --git a/src/outline.wgsl b/src/outline.wgsl index a29e493..0993fc6 100644 --- a/src/outline.wgsl +++ b/src/outline.wgsl @@ -61,18 +61,16 @@ fn vertex(vertex: VertexInput) -> @builtin(position) vec4 { #endif let clip_pos = view.view_proj * (model * vec4(vertex.position, 1.0)); #ifdef FLAT_DEPTH - let ndc_pos = clip_pos.xy / clip_pos.w; - let out_zw = vec2(model_origin_z(vstage.origin, view.view_proj), 1.0); + let out_zw = vec2(model_origin_z(vstage.origin, view.view_proj) * clip_pos.w, clip_pos.w); #else - let ndc_pos = clip_pos.xy; - let out_zw = clip_pos.zw; + let out_zw = clip_pos.wz; #endif #ifdef OFFSET_ZERO - let out_xy = ndc_pos; + let out_xy = clip_pos.xy; #else let clip_norm = mat4to3(view.view_proj) * (mat4to3(model) * vertex.normal); let ndc_delta = vstage.offset * normalize(clip_norm.xy) * view_uniform.scale * out_zw.y; - let out_xy = ndc_pos + ndc_delta; + let out_xy = clip_pos.xy + ndc_delta; #endif return vec4(out_xy, out_zw); } diff --git a/src/pipeline.rs b/src/pipeline.rs index 20eda8b..1224c08 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -303,7 +303,14 @@ impl SpecializedMeshPipeline for OutlinePipeline { depth_write_enabled: true, depth_compare: CompareFunction::Greater, stencil: StencilState::default(), - bias: DepthBiasState::default(), + bias: DepthBiasState { + constant: if key.pass_type() == PassType::Stencil { + 2 // 1 is empirically not enough to prevent Z-fighting. + } else { + 0 + }, + ..default() + }, }), multisample: MultisampleState { count: key.msaa_samples(),