From 99631b7740faec5f3364d4150f0a5fa1f09ae082 Mon Sep 17 00:00:00 2001 From: Peptide90 Date: Thu, 16 Jul 2026 11:29:55 +0100 Subject: [PATCH] sprite geometry clipping for water effect --- .../Components/Renderable/SpriteComponent.cs | 8 ++++++++ .../EntitySystems/SpriteSystem.Render.cs | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs index d1dbd6587c6..51380a85d1d 100644 --- a/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs +++ b/Robust.Client/GameObjects/Components/Renderable/SpriteComponent.cs @@ -214,6 +214,14 @@ public ShaderInstance? PostShader set; } + /// + /// Fraction of every normal sprite layer cropped from its bottom edge before rendering. + /// This is applied before layer and post shaders, allowing effects such as water immersion + /// without consuming the sprite's single post-shader slot. + /// + [ViewVariables(VVAccess.ReadWrite)] + public float BottomClipFraction { get; set; } + /// /// Whether to pass the screen texture to the . /// diff --git a/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs b/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs index e630ad93248..05845c5e785 100644 --- a/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs +++ b/Robust.Client/GameObjects/EntitySystems/SpriteSystem.Render.cs @@ -1,3 +1,4 @@ +using System; using System.Numerics; using Robust.Client.Graphics; using Robust.Client.Graphics.Clyde; @@ -146,6 +147,20 @@ private void RenderLayer(Layer layer, DrawingHandleWorld drawingHandle, ref Matr var layerColor = layer.Owner.Comp.color * layer.Color; var textureSize = texture.Size / (float) EyeManager.PixelsPerMeter; var quad = Box2.FromDimensions(textureSize / -2, textureSize); + UIBox2? subRegion = null; + + var bottomClip = Math.Clamp(layer.Owner.Comp.BottomClipFraction, 0f, 0.999f); + if (bottomClip > 0f) + { + // Crop the texture as well as its quad so the visible portion keeps its original scale. + // Texture sub-regions use a top-left origin while world quads use a bottom-left origin. + quad.Bottom = MathHelper.Lerp(quad.Bottom, quad.Top, bottomClip); + subRegion = new UIBox2( + 0f, + 0f, + texture.Width, + texture.Height * (1f - bottomClip)); + } if (layer.UnShaded) { @@ -158,7 +173,7 @@ private void RenderLayer(Layer layer, DrawingHandleWorld drawingHandle, ref Matr layerColor = new(new Vector4(-1) - layerColor.RGBA); } - drawingHandle.DrawTextureRectRegion(texture, quad, layerColor); + drawingHandle.DrawTextureRectRegion(texture, quad, layerColor, subRegion); if (layer.Shader != null) drawingHandle.UseShader(null);