Fix bad clipping of triangles behind the camera.

This commit is contained in:
Robin KAY 2023-03-07 23:46:58 +00:00
parent 5f06c32bcf
commit 0df3735906
3 changed files with 21 additions and 13 deletions

View File

@ -1,6 +1,6 @@
use std::f32::consts::PI; 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::{ use bevy_mod_outline::{
AutoGenerateOutlineNormalsPlugin, OutlineBundle, OutlinePlugin, OutlineVolume, AutoGenerateOutlineNormalsPlugin, OutlineBundle, OutlinePlugin, OutlineVolume,
}; };
@ -66,15 +66,17 @@ fn setup(
// Once the scene is loaded, start the animation and add an outline // Once the scene is loaded, start the animation and add an outline
fn setup_scene_once_loaded( fn setup_scene_once_loaded(
mut commands: Commands, mut commands: Commands,
scene_query: Query<&SceneInstance>,
scene_manager: Res<SceneSpawner>,
mut player_query: Query<&mut AnimationPlayer>,
animation: Res<Fox>, animation: Res<Fox>,
mut player: Query<&mut AnimationPlayer>,
entities: Query<Entity, With<Handle<Mesh>>>,
mut done: Local<bool>, mut done: Local<bool>,
) { ) {
if !*done { if !*done {
if let Ok(mut player) = player.get_single_mut() { if let (Ok(scene), Ok(mut player)) =
player.play(animation.0.clone_weak()).repeat(); (scene_query.get_single(), player_query.get_single_mut())
for entity in entities.iter() { {
for entity in scene_manager.iter_instance_entities(**scene) {
commands.entity(entity).insert(OutlineBundle { commands.entity(entity).insert(OutlineBundle {
outline: OutlineVolume { outline: OutlineVolume {
visible: true, visible: true,
@ -84,6 +86,7 @@ fn setup_scene_once_loaded(
..default() ..default()
}); });
} }
player.play(animation.0.clone_weak()).repeat();
*done = true; *done = true;
} }
} }

View File

@ -61,18 +61,16 @@ fn vertex(vertex: VertexInput) -> @builtin(position) vec4<f32> {
#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 #ifdef FLAT_DEPTH
let ndc_pos = clip_pos.xy / clip_pos.w; let out_zw = vec2<f32>(model_origin_z(vstage.origin, view.view_proj) * clip_pos.w, clip_pos.w);
let out_zw = vec2<f32>(model_origin_z(vstage.origin, view.view_proj), 1.0);
#else #else
let ndc_pos = clip_pos.xy; let out_zw = clip_pos.wz;
let out_zw = clip_pos.zw;
#endif #endif
#ifdef OFFSET_ZERO #ifdef OFFSET_ZERO
let out_xy = ndc_pos; let out_xy = clip_pos.xy;
#else #else
let clip_norm = mat4to3(view.view_proj) * (mat4to3(model) * vertex.normal); 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 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 #endif
return vec4<f32>(out_xy, out_zw); return vec4<f32>(out_xy, out_zw);
} }

View File

@ -303,7 +303,14 @@ 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: 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 { multisample: MultisampleState {
count: key.msaa_samples(), count: key.msaa_samples(),