From ffe4ea24ab8db0380f36013cc0ad4bf10693f4de Mon Sep 17 00:00:00 2001 From: vladislavbelov Date: Mon, 6 Jun 2022 20:48:18 +0000 Subject: [PATCH] Fixes LOS flickering because of float precision. Fixes #6546 Tested By: Langbart Differential Revision: https://code.wildfiregames.com/D4684 This was SVN commit r26922. --- .../data/mods/public/shaders/arb/model_common.fp | 2 ++ .../data/mods/public/shaders/arb/overlayline.fp | 2 ++ binaries/data/mods/public/shaders/arb/particle.fp | 2 ++ .../data/mods/public/shaders/arb/terrain_common.fp | 2 ++ .../data/mods/public/shaders/arb/water_simple.fp | 2 ++ source/graphics/LOSTexture.cpp | 14 ++++++++------ source/graphics/LOSTexture.h | 1 + 7 files changed, 19 insertions(+), 6 deletions(-) diff --git a/binaries/data/mods/public/shaders/arb/model_common.fp b/binaries/data/mods/public/shaders/arb/model_common.fp index ba9376e2f9..0f5c23394a 100644 --- a/binaries/data/mods/public/shaders/arb/model_common.fp +++ b/binaries/data/mods/public/shaders/arb/model_common.fp @@ -149,6 +149,8 @@ TEX tex, v_tex, texture[0], 2D; #if !IGNORE_LOS // Multiply everything by the LOS texture TEX tex.r, v_los, texture[2], 2D; + SUB tex.r, tex.r, 0.03; + MUL tex.r, tex.r, 0.97; MUL color.rgb, color, tex.r; #endif diff --git a/binaries/data/mods/public/shaders/arb/overlayline.fp b/binaries/data/mods/public/shaders/arb/overlayline.fp index f6f96c641f..df2cd21eba 100644 --- a/binaries/data/mods/public/shaders/arb/overlayline.fp +++ b/binaries/data/mods/public/shaders/arb/overlayline.fp @@ -19,6 +19,8 @@ TEX mask, fragment.texcoord[0], texture[1], 2D; // Multiply RGB by LOS texture (red channel) TEMP los; TEX los, fragment.texcoord[1], texture[2], 2D; + SUB los.r, los.r, 0.03; + MUL los.r, los.r, 0.97; MUL result.color.rgb, color, los.r; #endif diff --git a/binaries/data/mods/public/shaders/arb/particle.fp b/binaries/data/mods/public/shaders/arb/particle.fp index ed12b5051c..fc35a3eedc 100644 --- a/binaries/data/mods/public/shaders/arb/particle.fp +++ b/binaries/data/mods/public/shaders/arb/particle.fp @@ -17,6 +17,8 @@ MUL color.rgb, color, tex; // Multiply everything by the LOS texture TEX losTex, v_los, texture[1], 2D; +SUB losTex.r, losTex.r, 0.03; +MUL losTex.r, losTex.r, 0.97; MUL result.color.rgb, color, losTex.r; MUL result.color.a, tex, fragment.color; diff --git a/binaries/data/mods/public/shaders/arb/terrain_common.fp b/binaries/data/mods/public/shaders/arb/terrain_common.fp index 37044d3270..4ebf96530b 100644 --- a/binaries/data/mods/public/shaders/arb/terrain_common.fp +++ b/binaries/data/mods/public/shaders/arb/terrain_common.fp @@ -88,6 +88,8 @@ TEX color, fragment.texcoord[0], texture[0], 2D; // Multiply everything by the LOS texture TEX tex.r, fragment.texcoord[3], texture[3], 2D; +SUB tex.r, tex.r, 0.03; +MUL tex.r, tex.r, 0.97; MUL color.rgb, color, tex.r; #if DECAL diff --git a/binaries/data/mods/public/shaders/arb/water_simple.fp b/binaries/data/mods/public/shaders/arb/water_simple.fp index 48865547c5..5611840262 100644 --- a/binaries/data/mods/public/shaders/arb/water_simple.fp +++ b/binaries/data/mods/public/shaders/arb/water_simple.fp @@ -11,6 +11,8 @@ MUL diffuse, diffuse, color; TEMP los; TEX los, v_losCoords, texture[1], 2D; +SUB los.r, los.r, 0.03; +MUL los.r, los.r, 0.97; MUL diffuse, diffuse, los.r; MOV result.color, diffuse; diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index 7380b7f5c4..50f3c3f30e 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -22,6 +22,8 @@ #include "graphics/ShaderManager.h" #include "lib/bits.h" #include "lib/config2.h" +#include "lib/timer.h" +#include "maths/MathUtil.h" #include "ps/CLogger.h" #include "ps/CStrInternStatic.h" #include "ps/Game.h" @@ -132,6 +134,8 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::IDeviceCommandContext* devic if (m_Dirty) { RecomputeTexture(deviceCommandContext); + m_LastTextureRecomputeTime = timer_Time(); + m_WhichTexture = 1u - m_WhichTexture; m_Dirty = false; } @@ -150,11 +154,11 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::IDeviceCommandContext* devic deviceCommandContext->SetTexture( shader->GetBindingSlot(str_losTex1), m_Texture.get()); deviceCommandContext->SetTexture( - shader->GetBindingSlot(str_losTex2), m_SmoothTextures[m_WhichTexture].get()); + shader->GetBindingSlot(str_losTex2), m_SmoothTextures[1u - m_WhichTexture].get()); - deviceCommandContext->SetUniform( - shader->GetBindingSlot(str_delta), - static_cast(g_Renderer.GetTimeManager().GetFrameDelta() * 4.0f)); + const float delta = Clamp( + (timer_Time() - m_LastTextureRecomputeTime) * 2.0f, 0.0f, 1.0f); + deviceCommandContext->SetUniform(shader->GetBindingSlot(str_delta), delta); const SViewPort oldVp = g_Renderer.GetViewport(); const SViewPort vp = @@ -208,8 +212,6 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::IDeviceCommandContext* devic deviceCommandContext->SetFramebuffer( deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); - - m_WhichTexture = 1u - m_WhichTexture; } diff --git a/source/graphics/LOSTexture.h b/source/graphics/LOSTexture.h index e090503e09..6c963a78f1 100644 --- a/source/graphics/LOSTexture.h +++ b/source/graphics/LOSTexture.h @@ -98,6 +98,7 @@ private: m_Texture, m_SmoothTextures[2]; uint32_t m_WhichTexture = 0; + double m_LastTextureRecomputeTime = 0.0; // We update textures once a frame, so we change a Framebuffer once a frame. // That allows us to use two ping-pong FBOs instead of checking completeness