aboutsummaryrefslogtreecommitdiff
path: root/adapters/fparkan-render-vulkan/src/ffi
diff options
context:
space:
mode:
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi')
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke.rs23
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs72
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/tests.rs2
3 files changed, 69 insertions, 28 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
index c45c331..ac359c2 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
@@ -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() {
@@ -1091,10 +1080,10 @@ impl VulkanSmokeRenderer {
.chain(additive_rgb)
.chain(overlay_directional_rgb.into_iter().flatten())
.chain(overlay_additive_rgb.into_iter().flatten())
- .any(|value| !value.is_finite() || value < 0.0)
+ .any(|value| !value.is_finite())
{
return Err(VulkanSmokeRendererError::InvalidStaticMesh {
- context: "dynamic material lighting must be finite and non-negative",
+ context: "dynamic material lighting must be finite",
});
}
let lighting = self.material_lighting.get_mut(material_index).ok_or(
@@ -1155,10 +1144,10 @@ impl VulkanSmokeRenderer {
if specular_rgb
.into_iter()
.chain(overlay_specular_rgb.into_iter().flatten())
- .any(|value| !value.is_finite() || value < 0.0)
+ .any(|value| !value.is_finite())
{
return Err(VulkanSmokeRendererError::InvalidStaticMesh {
- context: "dynamic material specular RGB must be finite and non-negative",
+ context: "dynamic material specular RGB must be finite",
});
}
let specular = self.material_specular.get_mut(material_index).ok_or(
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
index c41eff9..7a8837d 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
@@ -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.
@@ -622,9 +649,9 @@ pub(super) fn resolve_draw_texture_indices(
.chain(material.additive_rgb)
.chain(material.specular_rgb)
.chain(material.overlay_specular_rgb.into_iter().flatten())
- .any(|value| !value.is_finite() || value < 0.0)
+ .any(|value| !value.is_finite())
{
- return Err("static material lighting and specular RGB parameters must be finite and non-negative");
+ return Err("static material lighting and specular RGB parameters must be finite");
}
if material
.uv_transform
@@ -645,9 +672,9 @@ pub(super) fn resolve_draw_texture_indices(
.into_iter()
.flatten()
.chain(material.overlay_additive_rgb.into_iter().flatten())
- .any(|value| !value.is_finite() || value < 0.0)
+ .any(|value| !value.is_finite())
{
- return Err("static material overlay RGB parameters must be finite and non-negative");
+ return Err("static material overlay RGB parameters must be finite");
}
if material
.overlay_uv_transform
@@ -1012,15 +1039,15 @@ mod static_mesh_tests {
overlay_detail_texture: None,
diffuse_alpha: 1.0,
overlay_diffuse_alpha: None,
- directional_rgb: [1.0; 3],
- additive_rgb: [0.0; 3],
- specular_rgb: [0.0; 3],
+ directional_rgb: [-0.25; 3],
+ additive_rgb: [-0.5; 3],
+ specular_rgb: [-0.75; 3],
specular_power: 0,
- overlay_specular_rgb: None,
+ overlay_specular_rgb: Some([-1.0; 3]),
overlay_specular_power: None,
uv_transform: [0.0, 0.0, 1.0, 1.0],
- overlay_directional_rgb: None,
- overlay_additive_rgb: None,
+ overlay_directional_rgb: Some([-0.125; 3]),
+ overlay_additive_rgb: Some([-0.375; 3]),
detail_uv_transform: [0.0, 0.0, 1.0, 1.0],
overlay_uv_transform: None,
overlay_detail_uv_transform: None,
@@ -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,13 +1082,37 @@ 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])
);
+
+ let mut non_finite_base = materials.clone();
+ non_finite_base[0].specular_rgb[0] = f32::NAN;
+ assert_eq!(
+ resolve_draw_texture_indices(&ranges, &non_finite_base),
+ Err("static material lighting and specular RGB parameters must be finite")
+ );
+
+ let mut non_finite_overlay = materials.clone();
+ non_finite_overlay[0].overlay_additive_rgb = Some([f32::INFINITY, 0.0, 0.0]);
+ assert_eq!(
+ resolve_draw_texture_indices(&ranges, &non_finite_overlay),
+ Err("static material overlay RGB parameters must be finite")
+ );
}
#[test]
diff --git a/adapters/fparkan-render-vulkan/src/ffi/tests.rs b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
index b8a3d71..4ed61f7 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/tests.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
@@ -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()"));