From c77c078efee9ece70c3f82793ed002f82a95eb85 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sun, 18 Oct 2026 07:28:16 +0400 Subject: fix: preserve native sky sprite screen depth --- apps/fparkan-game/src/main.rs | 156 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 145 insertions(+), 11 deletions(-) (limited to 'apps') diff --git a/apps/fparkan-game/src/main.rs b/apps/fparkan-game/src/main.rs index 438e345..9b5ea36 100644 --- a/apps/fparkan-game/src/main.rs +++ b/apps/fparkan-game/src/main.rs @@ -1261,6 +1261,7 @@ fn append_environment_material( sky_nebula_stars: false, lightmap_mode: false, sky_far_depth: matches!(fallback_row, 0..=2), + screen_tl: ENVIRONMENT_SPRITE_ROWS.contains(&fallback_row), }); phase_material_indices.push(index); } @@ -1321,6 +1322,7 @@ fn append_environment_gradient_material( sky_nebula_stars: false, lightmap_mode: false, sky_far_depth: true, + screen_tl: false, }); Ok(index) } @@ -1371,6 +1373,7 @@ fn append_shadow_material(materials: &mut Vec) -> Result [VulkanStaticVertex; 4] { + let width = viewport[0].max(1.0); + let height = viewport[1].max(1.0); + let half_width = half_width_pixels.max(0.0); + let half_height = half_height_pixels.max(0.0); + let pixel_corners = [ + [ + center_pixels[0] - half_width, + center_pixels[1] + half_height, + ], + [ + center_pixels[0] + half_width, + center_pixels[1] + half_height, + ], + [ + center_pixels[0] - half_width, + center_pixels[1] - half_height, + ], + [ + center_pixels[0] + half_width, + center_pixels[1] - half_height, + ], + ]; + // Positive-height Vulkan viewports map NDC -Y to top-down screen pixels. + let uv = [uv[1], uv[2], uv[0], uv[3]]; + std::array::from_fn(|index| { + let pixel = pixel_corners[index]; + let position = [ + pixel[0] * (2.0 / width) - 1.0, + pixel[1] * (2.0 / height) - 1.0, + 0.999, + ]; + environment_vertex_with_alpha(position, color, alpha, uv[index]) + }) +} + fn precipitation_quad_vertices( kind: PrecipitationKind, screen: &ScreenBillboard, @@ -4305,6 +4368,7 @@ fn static_preview_terrain_base_materials( sky_nebula_stars: false, lightmap_mode: false, sky_far_depth: false, + screen_tl: false, }); phase_material_indices.push(usize::from(preview_selector)); } @@ -4510,6 +4574,7 @@ fn static_preview_component_materials( sky_nebula_stars: false, lightmap_mode: false, sky_far_depth: false, + screen_tl: false, }); phase_material_indices.push(usize::from(preview_selector)); } @@ -7336,4 +7401,73 @@ mod tests { [uv[1], uv[2], uv[0], uv[3]] ); } + + #[test] + fn native_tl_sprite_pixels_use_current_viewport_and_preserve_depth_999() { + let uv = [[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]; + let small = screen_tl_quad_vertices_pixels( + [160.0, 120.0], + 40.0, + 30.0, + [640.0, 480.0], + [1.0; 3], + 1.0, + uv, + ); + let resized = screen_tl_quad_vertices_pixels( + [320.0, 240.0], + 80.0, + 60.0, + [1280.0, 960.0], + [1.0; 3], + 1.0, + uv, + ); + let wide = screen_tl_quad_vertices_pixels( + [640.0, 360.0], + 100.0, + 45.0, + [1280.0, 720.0], + [1.0; 3], + 1.0, + uv, + ); + + for (small, resized) in small.iter().zip(resized) { + for axis in 0..2 { + assert!((small.position[axis] - resized.position[axis]).abs() < 1.0e-6); + } + assert_eq!(small.position[2], 0.999); + assert_eq!(resized.position[2], 0.999); + } + assert_eq!(small[0].uv, [0.0, 1.0]); + assert_eq!(small[2].uv, [0.0, 0.0]); + for (actual, expected) in [ + (wide[0].position, [-0.15625, 0.125, 0.999]), + (wide[2].position, [-0.15625, -0.125, 0.999]), + ] { + for axis in 0..3 { + assert!((actual[axis] - expected[axis]).abs() < 1.0e-6); + } + } + } + + #[test] + fn native_tl_depth_999_is_nearer_than_opaque_geometry_at_320_units() { + let camera = FreeFlightCamera { + position: [0.0; 3], + yaw: 0.0, + pitch: 0.0, + horizontal_fov: 1.3, + near_plane: 0.5, + far_plane: 700.0, + move_speed: 1.0, + }; + let frame = camera.preview_frame(16.0 / 9.0); + let opaque_clip = row_vector_transform([320.0, 0.0, 0.0, 1.0], frame.clip_from_world); + let opaque_depth = opaque_clip[2] / opaque_clip[3]; + + assert!((opaque_depth - 0.999151_18).abs() < 1.0e-6); + assert!(0.999 < opaque_depth); + } } -- cgit v1.2.3