From d269d8b3dadb3717b4102e0cfb0bdfd996febcd3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 9 Apr 2026 15:48:48 +0300 Subject: [PATCH] [thanos] Added particle shrink and fade-out during Thanos dissolution. --- .../ui/effects/thanos_effect_renderer.cpp | 19 +++++++++++++++++++ Telegram/shaders/thanos.vert | 8 ++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/ui/effects/thanos_effect_renderer.cpp b/Telegram/SourceFiles/ui/effects/thanos_effect_renderer.cpp index cbaa265494..ee161beec9 100644 --- a/Telegram/SourceFiles/ui/effects/thanos_effect_renderer.cpp +++ b/Telegram/SourceFiles/ui/effects/thanos_effect_renderer.cpp @@ -30,6 +30,9 @@ constexpr auto kTimeStepMultiplier = 1.0f; constexpr auto kAccelerationStartPhase = 1.0f; constexpr auto kAccelerationRampPhase = 2.5f; constexpr auto kAccelerationMaxMultiplier = 2.2f; +constexpr auto kDisappearStartPhase = kMaxPhaseDuration * 0.15f; +constexpr auto kDisappearDuration + = kMaxPhaseDuration - kDisappearStartPhase; constexpr auto kMaxParticleCount = uint32_t(120000); const float kQuadVertices[kQuadVertexCount * 2] = { @@ -61,6 +64,7 @@ struct alignas(16) RenderUniforms { float rect[4]; float size[2]; uint32_t particleResolution[2]; + float scale[4]; }; static_assert(sizeof(RenderUniforms) % 16 == 0); @@ -77,6 +81,15 @@ static_assert(sizeof(RenderUniforms) % 16 == 0); + ((kAccelerationMaxMultiplier - 1.0f) * smooth); } +[[nodiscard]] float DisappearProgress(float phase) { + const auto t = std::clamp( + (phase - kDisappearStartPhase) / kDisappearDuration, + 0.0f, + 1.0f); + const auto oneMinus = 1.0f - t; + return 1.0f - (oneMinus * oneMinus * oneMinus); +} + [[nodiscard]] QShader LoadShader(const QString &name) { return Rhi::ShaderFromFile(u":/shaders/"_q + name + u".qsb"_q); } @@ -367,6 +380,12 @@ void ThanosEffectRenderer::render( uni.size[1] = float(item.rect.height()); uni.particleResolution[0] = item.particleCountX; uni.particleResolution[1] = item.particleCountY; + const auto disappearProgress = DisappearProgress(item.phase); + const auto inverseDisappear = 1.0f - disappearProgress; + uni.scale[0] = inverseDisappear; + uni.scale[1] = 0.0f; + uni.scale[2] = inverseDisappear; + uni.scale[3] = 0.0f; renderRub->updateDynamicBuffer( item.renderUniformBuffer, diff --git a/Telegram/shaders/thanos.vert b/Telegram/shaders/thanos.vert index a5f468cb2a..795ea641c9 100644 --- a/Telegram/shaders/thanos.vert +++ b/Telegram/shaders/thanos.vert @@ -12,6 +12,7 @@ layout(std140, binding = 0) uniform Params { vec4 rect; vec2 size; uvec2 particleResolution; + vec4 scale; }; void main() { @@ -25,7 +26,10 @@ void main() { v_texcoord = (topLeft + inQuadPos * particleSize) / size; topLeft += inOffset; - vec2 position = topLeft + inQuadPos * particleSize; + float scaleFactor = scale.x; + vec2 center = topLeft + (particleSize * 0.5); + vec2 position + = center + ((inQuadPos - vec2(0.5)) * particleSize * scaleFactor); vec2 ndc; ndc.x = rect.x + position.x / size.x * rect.z; @@ -35,5 +39,5 @@ void main() { gl_Position = vec4(ndc, 0.0, 1.0); - v_alpha = clamp(inLifetime / 0.6, 0.0, 1.0); + v_alpha = clamp(inLifetime / 0.6, 0.0, 1.0) * scale.z; }