fix: preserve native sky sprite screen depth
Docs Deploy / Build and Deploy MkDocs (push) Successful in 33s

This commit is contained in:
Valentin Popov committed 2026-10-18 07:28:16 +04:00
1 parent d97c8d40bf
commit c77c078efe
7 files changed
+221 -28

No files matched your search

@@ -3,7 +3,7 @@
use ash::vk;
use fparkan_render::{LegacyDepthMode, LegacyPipelineState};
use super::smoke_types::resolve_draw_texture_indices;
use super::smoke_types::{resolve_draw_texture_indices, VulkanStaticMaterial};
use super::update_material_texture_descriptor;
use super::{
create_command_pool, create_frame_sync, create_index_buffer, create_static_mesh_index_buffer,
@@ -361,18 +361,7 @@ impl VulkanSmokeRenderer {
create_info
.materials
.iter()
.map(|material| {
let combiner_mode = if material.lightmap_mode {
3.0
} else if material.sky_nebula_stars {
2.0
} else if material.unlit {
1.0
} else {
0.0
};
combiner_mode + if material.sky_far_depth { 4.0 } else { 0.0 }
})
.map(VulkanStaticMaterial::encoded_material_mode)
.collect()
};
let material_specular = if create_info.materials.is_empty() {
@@ -505,6 +505,33 @@ pub struct VulkanStaticMaterial {
/// renderer projection choice; it is not a claim about the original D3D
/// depth-bit encoding.
pub sky_far_depth: bool,
/// Push material mode bit 8 and treat positions as Vulkan clip-space
/// `XYZRHW` vertices. Their x/y coordinates are converted from viewport
/// pixels by the caller and z retains the native `0.999` depth.
pub screen_tl: bool,
}
impl VulkanStaticMaterial {
pub(crate) fn encoded_material_mode(&self) -> f32 {
let combiner_mode = if self.screen_tl {
1.0
} else if self.lightmap_mode {
3.0
} else if self.sky_nebula_stars {
2.0
} else if self.unlit {
1.0
} else {
0.0
};
combiner_mode
+ if self.sky_far_depth && !self.screen_tl {
4.0
} else {
0.0
}
+ if self.screen_tl { 8.0 } else { 0.0 }
}
}
/// One authored RGBA8 mip level accepted by the Vulkan texture upload path.
@@ -1028,6 +1055,7 @@ mod static_mesh_tests {
sky_nebula_stars: false,
lightmap_mode: false,
sky_far_depth: false,
screen_tl: false,
},
VulkanStaticMaterial {
material_index: 7,
@@ -1054,9 +1082,19 @@ mod static_mesh_tests {
sky_nebula_stars: false,
lightmap_mode: false,
sky_far_depth: false,
screen_tl: false,
},
];
let mut screen_tl = materials[0].clone();
screen_tl.screen_tl = true;
screen_tl.sky_far_depth = true;
assert_eq!(screen_tl.encoded_material_mode(), 9.0);
let mut far_sky = materials[0].clone();
far_sky.unlit = true;
far_sky.sky_far_depth = true;
assert_eq!(far_sky.encoded_material_mode(), 5.0);
assert_eq!(
resolve_draw_texture_indices(&ranges, &materials),
Ok(vec![1, 0])
@@ -533,7 +533,7 @@ fn native_specular_reference_uses_squared_power_and_total_overflow_curve() {
fn shader_computes_radial_fog_per_vertex_and_interpolates_it() {
let vertex = include_str!("../../shaders/triangle.vert");
let fragment = include_str!("../../shaders/triangle.frag");
assert!(vertex.contains("out_fog_factor = native_fog_factor(in_position);"));
assert!(vertex.contains("out_fog_factor = screen_tl ? 0.0 : native_fog_factor(in_position);"));
assert!(fragment.contains("layout(location = 4) in float in_fog_factor;"));
assert!(!fragment.contains("distance(in_world_position"));
assert!(!fragment.contains("float fog_factor()"));