aboutsummaryrefslogtreecommitdiff
path: root/crates/fparkan-render/src/water.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-11-01 13:39:37 +0300
committerValentin Popov <valentin@popov.link>2026-11-01 13:39:37 +0300
commit55e98d7ff6224aa3bf4b5d4260a594705ee2133f (patch)
tree828a6ea2ad0ebf7cc127e20fb8a0a03673636a35 /crates/fparkan-render/src/water.rs
parentbbd31fc25336d6a2e6c5927ad4d7101696f8bd78 (diff)
downloadfparkan-55e98d7ff6224aa3bf4b5d4260a594705ee2133f.tar.xz
fparkan-55e98d7ff6224aa3bf4b5d4260a594705ee2133f.zip
fix(render): draw translucent water into planar reflectionstrunk
Diffstat (limited to 'crates/fparkan-render/src/water.rs')
-rw-r--r--crates/fparkan-render/src/water.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/crates/fparkan-render/src/water.rs b/crates/fparkan-render/src/water.rs
index 58a2817..7a5ccbd 100644
--- a/crates/fparkan-render/src/water.rs
+++ b/crates/fparkan-render/src/water.rs
@@ -7,6 +7,21 @@ pub const EMBM_BUMP_TILE: f32 = 100.0;
/// Native diagonal bump matrix, without luminance modulation.
pub const EMBM_COEFFICIENTS: [f32; 2] = [0.01, 0.01];
+/// Terrain draws ordinary textured water into its reflection with this alpha.
+pub const REFLECTED_WATER_ALPHA: f32 = 0.1;
+
+/// Native packet category 4 enables source-alpha blending without changing depth.
+#[must_use]
+pub fn legacy_reflected_water_pipeline(
+ state: crate::LegacyPipelineState,
+) -> crate::LegacyPipelineState {
+ crate::LegacyPipelineState {
+ blend: crate::LegacyBlendMode::SourceAlpha,
+ alpha_test: true,
+ ..state
+ }
+}
+
/// Square reflection size chosen by Terrain.dll RVA 0x27FC7 from renderer dimensions.
#[must_use]
pub fn legacy_embm_reflection_size(extent: [u32; 2]) -> u32 {
@@ -128,6 +143,28 @@ mod tests {
use super::*;
#[test]
+ fn reflected_water_blends_material_alpha_and_preserves_depth_and_cull() {
+ use crate::{LegacyBlendMode, LegacyCullMode, LegacyDepthMode, LegacyPipelineState};
+ for depth in [
+ LegacyDepthMode::Disabled,
+ LegacyDepthMode::TestWrite,
+ LegacyDepthMode::TestReadOnly,
+ ] {
+ let original = LegacyPipelineState {
+ depth,
+ cull: LegacyCullMode::FrontFace,
+ ..LegacyPipelineState::default()
+ };
+ let fallback = legacy_reflected_water_pipeline(original);
+ assert_eq!(fallback.blend, LegacyBlendMode::SourceAlpha);
+ assert!(fallback.alpha_test);
+ assert_eq!(fallback.depth, original.depth);
+ assert_eq!(fallback.cull, original.cull);
+ }
+ assert_eq!(REFLECTED_WATER_ALPHA.to_bits(), 0x3dcc_cccd);
+ }
+
+ #[test]
fn reflection_size_matches_native_renderer_dimension_vectors() {
for (extent, expected) in [
([1280, 1024], 1024),