chores: Import SnowEffect from shadertoy

This commit is contained in:
Zhe Fang
2025-11-16 20:26:31 -05:00
parent dc627bd1ef
commit 220e940bbb
12 changed files with 80 additions and 28 deletions

View File

@@ -90,7 +90,7 @@
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard Header="Discord Presence">
<dev:SettingsCard x:Uid="SettingsPageDiscordPresence">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsDiscordPresenceEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
@@ -261,7 +261,7 @@
<Paragraph>
<Run Text="{x:Bind ViewModel.MediaSessionsService.CurrentMediaSourceProviderInfo.DisplayName, Mode=OneWay}" />
<Run Text="(" />
<Run Text="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.PlayerId, Mode=OneWay}" />
<Run Text="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.PlayerId, TargetNullValue=N/A, Mode=OneWay}" />
<Run Text=")" />
</Paragraph>
</RichTextBlock>

View File

@@ -493,7 +493,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
AlbumArtists = songInfo.Artists.ToList(),
Artists = songInfo.Artists.ToList(),
Title = songInfo.Title,
}, searcher, Lyricify.Lyrics.Searchers.Helpers.CompareHelper.MatchType.VeryHigh);
}, searcher, Lyricify.Lyrics.Searchers.Helpers.CompareHelper.MatchType.PrettyHigh);
}
if (result != null)

View File

@@ -3,44 +3,49 @@ using ComputeSharp.D2D1;
namespace BetterLyrics.WinUI3.Shaders
{
/// <summary>
/// Ported from <see href="https://www.shadertoy.com/view/Mdt3Df"/>.
/// Credit/Copyright to the original author.
/// </summary>
/// <param name="time"></param>
/// <param name="dispatchSize"></param>
[D2DInputCount(0)]
[D2DShaderProfile(D2D1ShaderProfile.PixelShader50)]
[D2DGeneratedPixelShaderDescriptor]
[D2DRequiresScenePosition]
public readonly partial struct SnowEffect(float time, Float2 resolution) : ID2D1PixelShader
public readonly partial struct SnowEffect(float time, float2 dispatchSize) : ID2D1PixelShader
{
public Float4 Execute()
public float4 Execute()
{
Float2 fragCoord = D2D.GetScenePosition().XY;
int2 xy = (int2)D2D.GetScenePosition().XY;
float2 fragCoord = new(xy.X, dispatchSize.Y - xy.Y);
float snow = 0.0f;
for (int k = 0; k < 6; k++)
{
for (int i = 0; i < 12; i++)
for (int i = 1; i < 12; i++)
{
float cellSize = 2.0f + ((float)i * 3.0f);
float downSpeed = 0.3f + (Hlsl.Sin(time * 0.4f + (float)(k + i * 20)) + 1.0f) * 0.00008f;
downSpeed /= 10;
downSpeed *= -1;
float cellSize = 2.0f + (i * 3.0f);
float downSpeed = 0.3f + (Hlsl.Sin(time * 0.4f + (k + i * 20)) + 1.0f) * 0.00008f;
Float2 uv = (fragCoord / resolution.X) +
new Float2(
0.01f * Hlsl.Sin((time + (float)(k * 6185)) * 0.6f + (float)i) * (5.0f * i),
downSpeed * (time + (float)(k * 1352)) * i
float2 uv = (fragCoord / dispatchSize.X) +
new float2(
0.01f * Hlsl.Sin((time + (k * 6185)) * 0.6f + i) * (5.0f / i),
downSpeed * (time + (k * 1352)) * (1.0f / i)
);
Float2 uvStep = (Hlsl.Ceil(uv * cellSize - new Float2(0.5f, 0.5f)) / cellSize);
float2 uvStep = (Hlsl.Ceil(uv * cellSize - new float2(0.5f, 0.5f)) / cellSize);
float x = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new Float2(12.9898f + (float)k * 12.0f, 78.233f + (float)k * 315.156f))) * 43758.5453f + (float)k * 12.0f) - 0.5f;
float y = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new Float2(62.2364f + (float)k * 23.0f, 94.674f + (float)k * 95.0f))) * 62159.8432f + (float)k * 12.0f) - 0.5f;
float x = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new float2(12.9898f + k * 12.0f, 78.233f + k * 315.156f))) * 43758.5453f + k * 12.0f) - 0.5f;
float y = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new float2(62.2364f + k * 23.0f, 94.674f + k * 95.0f))) * 62159.8432f + k * 12.0f) - 0.5f;
float randomMagnitude1 = Hlsl.Sin(time * 2.5f) * 0.7f / cellSize;
float randomMagnitude2 = Hlsl.Cos(time * 2.5f) * 0.7f / cellSize;
float d = 5.0f * Hlsl.Distance((uvStep + new Float2(x * Hlsl.Sin(y), y) * randomMagnitude1 + new Float2(y, x) * randomMagnitude2), uv);
float d = 5.0f * Hlsl.Distance((uvStep + new float2(x * Hlsl.Sin(y), y) * randomMagnitude1 + new float2(y, x) * randomMagnitude2), uv);
float omiVal = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new Float2(32.4691f, 94.615f))) * 31572.1684f);
float omiVal = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(uvStep, new float2(32.4691f, 94.615f))) * 31572.1684f);
if (omiVal < 0.08f)
{
@@ -50,7 +55,7 @@ namespace BetterLyrics.WinUI3.Shaders
}
}
return (Float4)snow;
return (float4)snow;
}
}
}

View File

@@ -691,6 +691,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageDiscord.Content" xml:space="preserve">
<value>Discord</value>
</data>
<data name="SettingsPageDiscordPresence.Header" xml:space="preserve">
<value>Display listening status via Discord Presence</value>
</data>
<data name="SettingsPageDisplayTypeSwitcher.Header" xml:space="preserve">
<value>Layout mode</value>
</data>

View File

@@ -691,6 +691,9 @@
<data name="SettingsPageDiscord.Content" xml:space="preserve">
<value>Discord</value>
</data>
<data name="SettingsPageDiscordPresence.Header" xml:space="preserve">
<value>Discord Presenceでリスニングステータスを表示</value>
</data>
<data name="SettingsPageDisplayTypeSwitcher.Header" xml:space="preserve">
<value>レイアウトモード</value>
</data>

View File

@@ -691,6 +691,9 @@
<data name="SettingsPageDiscord.Content" xml:space="preserve">
<value>Discord</value>
</data>
<data name="SettingsPageDiscordPresence.Header" xml:space="preserve">
<value>Discord 프레즌스를 통해 청취 상태를 표시합니다</value>
</data>
<data name="SettingsPageDisplayTypeSwitcher.Header" xml:space="preserve">
<value>레이아웃 모드</value>
</data>

View File

@@ -691,6 +691,9 @@
<data name="SettingsPageDiscord.Content" xml:space="preserve">
<value>Discord</value>
</data>
<data name="SettingsPageDiscordPresence.Header" xml:space="preserve">
<value>通过 Discord Presence 显示收听状态</value>
</data>
<data name="SettingsPageDisplayTypeSwitcher.Header" xml:space="preserve">
<value>布局模式</value>
</data>

View File

@@ -691,6 +691,9 @@
<data name="SettingsPageDiscord.Content" xml:space="preserve">
<value>Discord</value>
</data>
<data name="SettingsPageDiscordPresence.Header" xml:space="preserve">
<value>透過 Discord Presence 顯示聆聽狀態</value>
</data>
<data name="SettingsPageDisplayTypeSwitcher.Header" xml:space="preserve">
<value>布局模式</value>
</data>

View File

@@ -405,14 +405,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private void DrawSnowEffect(ICanvasAnimatedControl control, CanvasDrawingSession ds)
{
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled)
if (_snowEffect != null && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled)
{
_snowEffect ??= new PixelShaderEffect<SnowEffect>();
var width = (float)control.ConvertDipsToPixels((float)control.Size.Width, CanvasDpiRounding.Round);
var height = (float)control.ConvertDipsToPixels((float)control.Size.Height, CanvasDpiRounding.Round);
_snowEffect?.ConstantBuffer = new SnowEffect((float)TotalTime.TotalSeconds, new(width, height));
ds.DrawImage(_snowEffect);
}
}

View File

@@ -278,5 +278,16 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_fluidEffect.Properties["color4"] = _albumArtAccentColor4Transition.Value.ToVector3RGB();
_fluidEffect.Properties["EnableLightWave"] = false;
}
private void DisposeSnowEffect()
{
_snowEffect?.Dispose();
_snowEffect = null;
}
private void RecreateSnowEffect()
{
_snowEffect = new();
}
}
}

View File

@@ -138,6 +138,10 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
_isFluidOverlayEnabledChanged = true;
}
else if (message.PropertyName == nameof(LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled))
{
_isSnowOverlayEnabledChanged = true;
}
}
}

View File

@@ -2,6 +2,7 @@
using BetterLyrics.WinUI3.Extensions;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Shaders;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Geometry;
using Microsoft.Graphics.Canvas.UI.Xaml;
@@ -57,6 +58,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private bool _isSpectrumOverlayEnabledChanged = true;
private bool _isFluidOverlayEnabledChanged = true;
private bool _isSnowOverlayEnabledChanged = true;
private bool _isLyrics3DMatrixChanged = true;
@@ -141,6 +143,27 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
}
}
if (_isDeviceChanged || _isLyricsWindowsStatusChanged || _isSnowOverlayEnabledChanged)
{
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled)
{
RecreateSnowEffect();
}
else
{
DisposeSnowEffect();
}
_isSnowOverlayEnabledChanged = false;
}
if (_snowEffect != null)
{
var width = (float)control.ConvertDipsToPixels((float)control.Size.Width, CanvasDpiRounding.Round);
var height = (float)control.ConvertDipsToPixels((float)control.Size.Height, CanvasDpiRounding.Round);
_snowEffect.ConstantBuffer = new SnowEffect((float)TotalTime.TotalSeconds, new(width, height));
}
// 检测播放行变更
var playingLineIndex = GetCurrentPlayingLineIndex();
_isPlayingLineChanged = _playingLineIndex != playingLineIndex;