Skip to content

Commit

Permalink
Merge pull request #228 from sirdoombox/main
Browse files Browse the repository at this point in the history
Effect rendering improvements.
  • Loading branch information
kikipoulet authored Jun 27, 2024
2 parents b8339c0 + c6da2b3 commit a88da0d
Show file tree
Hide file tree
Showing 20 changed files with 845 additions and 584 deletions.
69 changes: 69 additions & 0 deletions SukiUI.Demo/Assets/glow.sksl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const float pi = 3.14159265358979323846;

float smoothstep(float a, float b, float x) {
float t = clamp((x - a) / (b - a), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}

float atan(float y, float x) {
// Constants for the series expansion
const float pi_2 = pi / 2.0;

// Handle special cases
if (x == 0.0) {
if (y > 0.0) return pi_2;
if (y < 0.0) return -pi_2;
return 0.0; // Undefined, but return 0
}

float abs_y = abs(y) + 1e-10; // Avoid division by zero

// Compute the arctangent of y/x
float angle;
if (abs(x) > abs_y) {
float z = y / x;
float zz = z * z;
angle = z * (0.999866 + zz * (-0.3302995 + zz * (0.180141 + zz * (-0.085133 + zz * 0.020835))));
if (x < 0.0) {
if (y < 0.0) {
angle -= pi;
} else {
angle += pi;
}
}
} else {
float z = x / y;
float zz = z * z;
angle = pi_2 - z * (0.999866 + zz * (-0.3302995 + zz * (0.180141 + zz * (-0.085133 + zz * 0.020835))));
if (y < 0.0) {
angle -= pi;
}
}

return angle;
}

vec4 main(vec2 fragCoord) {
float radius = 0.3;
float lineWidth = 2.0; // in pixels
float glowSize = 3.0; // in pixels

float pixelSize = 1.0 / min(iResolution.x, iResolution.y);
lineWidth *= pixelSize;
glowSize *= pixelSize;
glowSize *= 2.0;

vec2 uv = (fragCoord.xy / iResolution.xy) - 0.5;
uv.x *= iResolution.x / iResolution.y;

float len = length(uv);
float angle = atan(uv.y, uv.x);

float fallOff = fract(-0.5 * (angle / pi) - iTime * 0.5);

lineWidth = (lineWidth - pixelSize) * 0.5 * fallOff;
float color = smoothstep(pixelSize, 0.0, abs(radius - len) - lineWidth) * fallOff;
color += smoothstep(glowSize * fallOff, 0.0, abs(radius - len) - lineWidth) * fallOff * 0.5;

return vec4(color) * vec4(iAccent, iAlpha);
}
28 changes: 28 additions & 0 deletions SukiUI.Demo/Assets/pellets.sksl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
float smoothstep(float a, float b, float x) {
float t = clamp((x - a) / (b - a), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}

float A(vec2 p, float a) {
a *= 3.14159;\
vec2 s = vec2(sin(a), cos(a));
p.x = abs(p.x);
return ((s.y * p.x > s.x * p.y) ? length(p - s * .7) :
abs(length(p) - .7)) - .13;
}

mat2 D(float a) {
a *= 3.14159;\
vec2 s = vec2(sin(a), cos(a));
return mat2(s.y, -s.x, s.x, s.y);
}

vec4 main(vec2 fragCoord) {
vec2 r = iResolution.xy, p = (2. * fragCoord - r) / r.y;
float T = iTime * 1.,
d = A(p * D(1. - .125 * floor(T)), .4375), // distance to longest arc
i;
for (i = 0.; i < 1.; i += .5)
d = min(A(p * D(mix(-.5, .625, fract(T / 2. + i)) - .125 * T), .0625), d); // distance to shorter arcs ("pellets")
return vec4(smoothstep(.01, .0, d)) * vec4(iAccent, iAlpha);
}
74 changes: 74 additions & 0 deletions SukiUI.Demo/Controls/LoadingTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using SkiaSharp;
using SukiUI.Utilities.Effects;

namespace SukiUI.Demo.Controls
{
public class LoadingTest : Control
{
public static readonly StyledProperty<LoadingStyle> LoadingStyleProperty =
AvaloniaProperty.Register<LoadingTest, LoadingStyle>(nameof(LoadingStyle));

public LoadingStyle LoadingStyle
{
get => GetValue(LoadingStyleProperty);
set => SetValue(LoadingStyleProperty, value);
}

private static readonly IReadOnlyDictionary<LoadingStyle, SukiEffect> Effects =
new Dictionary<LoadingStyle, SukiEffect>()
{
{ LoadingStyle.Glow, SukiEffect.FromEmbeddedResource("glow") },
{ LoadingStyle.Pellets, SukiEffect.FromEmbeddedResource("pellets") }
};

private readonly LoadingEffectDraw _draw;

public LoadingTest()
{
Width = 50;
Height = 50;
_draw = new LoadingEffectDraw(Bounds);
}

public override void Render(DrawingContext context)
{
_draw.Bounds = Bounds;
_draw.Effect = Effects[LoadingStyle];
context.Custom(_draw);
}

public class LoadingEffectDraw : EffectDrawBase
{
public LoadingEffectDraw(Rect bounds) : base(bounds)
{
AnimationEnabled = true;
AnimationSpeedScale = 2f;
}

protected override void Render(SKCanvas canvas, SKRect rect)
{
canvas.Scale(1,-1);
canvas.Translate(0, (float)-Bounds.Height);
using var mainShaderPaint = new SKPaint();

if (Effect is not null)
{
using var shader = EffectWithUniforms();
mainShaderPaint.Shader = shader;
canvas.DrawRect(rect, mainShaderPaint);
}
canvas.Restore();
}
}
}

public enum LoadingStyle
{
Glow,
Pellets
}
}
15 changes: 15 additions & 0 deletions SukiUI.Demo/Features/ControlsLibrary/ProgressView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:SukiUI.Controls;assembly=SukiUI"
xmlns:controls1="clr-namespace:SukiUI.Demo.Controls"
xmlns:controlsLibrary="clr-namespace:SukiUI.Demo.Features.ControlsLibrary"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down Expand Up @@ -145,6 +146,20 @@
</controls:GroupBox>
</controls:GlassCard>


<controls:GlassCard>
<controls:GroupBox Header="Custom Loading Indicators">
<StackPanel Spacing="15">
<showMeTheXaml:XamlDisplay UniqueId="Loading3">
<controls1:LoadingTest />
</showMeTheXaml:XamlDisplay>
<showMeTheXaml:XamlDisplay UniqueId="Loading4">
<controls1:LoadingTest LoadingStyle="Pellets" />
</showMeTheXaml:XamlDisplay>
</StackPanel>
</controls:GroupBox>
</controls:GlassCard>

<controls:GlassCard Width="500">
<controls:GroupBox Header="Stepper">
<StackPanel Spacing="15">
Expand Down
2 changes: 2 additions & 0 deletions SukiUI.Demo/SukiUI.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Assets\glow.sksl" />
<EmbeddedResource Include="Assets\pellets.sksl" />
<EmbeddedResource Include="Assets\space.sksl" />
<EmbeddedResource Include="Assets\clouds.sksl" />
<EmbeddedResource Include="Assets\weird.sksl" />
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ vec4 main(vec2 fragCoord )
vec3 col = mix(iPrimary, iAccent, uv.x);
voronoi(uv * 4.0 - 1.0, col);
vec3 finalCol = blendOverlay(iBase, col);
return vec4(finalCol,iAlpha);
return vec4(finalCol, iAlpha);
}
16 changes: 8 additions & 8 deletions SukiUI/Controls/SukiBackground.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
using Avalonia.Media;
using Avalonia.Threading;
using SukiUI.Enums;
using SukiUI.Utilities.Background;
using SukiUI.Utilities;
using SukiUI.Utilities.Effects;

namespace SukiUI.Controls
{
Expand Down Expand Up @@ -88,13 +89,13 @@ public double TransitionTime
set => SetValue(TransitionTimeProperty, value);
}

private readonly ShaderBackgroundDraw _draw;
private readonly EffectBackgroundDraw _draw;
private readonly IDisposable _observables;

public SukiBackground()
{
IsHitTestVisible = false;
_draw = new ShaderBackgroundDraw(new Rect(0, 0, Bounds.Width, Bounds.Height));
_draw = new EffectBackgroundDraw(new Rect(0, 0, Bounds.Width, Bounds.Height));
var transEnabledObs = this.GetObservable(TransitionsEnabledProperty)
.Do(enabled => _draw.TransitionsEnabled = enabled)
.Select(_ => Unit.Default);
Expand All @@ -103,7 +104,7 @@ public SukiBackground()
.Select(_ => Unit.Default)
.Merge(transEnabledObs);
var animObs = this.GetObservable(AnimationEnabledProperty)
.Do(enabled => _draw.AnimEnabled = enabled)
.Do(enabled => _draw.AnimationEnabled = enabled)
.Select(_ => Unit.Default)
.Merge(transTime);
var bgStyleObs = this.GetObservable(StyleProperty)
Expand All @@ -124,17 +125,16 @@ public override void Render(DrawingContext context)
{
_draw.Bounds = Bounds;
context.Custom(_draw);
Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background);
}

private void HandleBackgroundStyleChanges()
{
if (ShaderFile is not null)
_draw.Effect = SukiBackgroundEffect.FromEmbeddedResource(ShaderFile);
_draw.Effect = SukiEffect.FromEmbeddedResource(ShaderFile);
else if (ShaderCode is not null)
_draw.Effect = SukiBackgroundEffect.FromString(ShaderCode);
_draw.Effect = SukiEffect.FromString(ShaderCode);
else
_draw.Effect = SukiBackgroundEffect.FromEmbeddedResource(Style.ToString());
_draw.Effect = SukiEffect.FromEmbeddedResource(Style.ToString());
}

protected override void OnUnloaded(RoutedEventArgs e)
Expand Down
2 changes: 1 addition & 1 deletion SukiUI/Controls/SukiWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using SukiUI.Enums;
using SukiUI.Utilities.Background;
using SukiUI.Utilities;

namespace SukiUI.Controls;

Expand Down
24 changes: 24 additions & 0 deletions SukiUI/Models/SukiColorTheme.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Avalonia.Media;
using SukiUI.Enums;

Expand All @@ -15,11 +16,19 @@ public record SukiColorTheme

public IBrush AccentBrush => new SolidColorBrush(Accent);

// Used in shaders to save calculating them per-frame.
internal Color BackgroundPrimary { get; }
internal Color BackgroundAccent { get; }
internal Color Background { get; }

public SukiColorTheme(string displayName, Color primary, Color accent)
{
DisplayName = displayName;
Primary = primary;
Accent = accent;
Background = GetBackgroundColor(Primary);
BackgroundPrimary = new Color(primary.A, (byte)(primary.R / 1.3), (byte)(primary.G / 1.3), (byte)(primary.B / 1.3));
BackgroundAccent = new Color(accent.A, (byte)(accent.R / 1.3), (byte)(accent.G / 1.3), (byte)(accent.B / 1.3));
}

public override int GetHashCode()
Expand All @@ -38,6 +47,21 @@ public override string ToString()
{
return DisplayName;
}

private static Color GetBackgroundColor(Color input)
{
int r = input.R;
int g = input.G;
int b = input.B;

var minValue = Math.Min(Math.Min(r, g), b);
var maxValue = Math.Max(Math.Max(r, g), b);

r = (r == minValue) ? 37 : ((r == maxValue) ? 37 : 26);
g = (g == minValue) ? 37 : ((g == maxValue) ? 37 : 26);
b = (b == minValue) ? 37 : ((b == maxValue) ? 37 : 26);
return new Color(255, (byte)r, (byte)g, (byte)b);
}
}

internal record DefaultSukiColorTheme : SukiColorTheme
Expand Down
8 changes: 4 additions & 4 deletions SukiUI/SukiUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Content\Shaders\flat.sksl" />
<EmbeddedResource Include="Content\Shaders\waves.sksl" />
<EmbeddedResource Include="Content\Shaders\gradient.sksl" />
<EmbeddedResource Include="Content\Shaders\cells.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\cells.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\flat.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\gradient.sksl" />
<EmbeddedResource Include="Content\Shaders\Background\waves.sksl" />
</ItemGroup>

</Project>
Loading

0 comments on commit a88da0d

Please sign in to comment.