1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Noise brush - Speed optimizations (broke it for now but no time to fix!)

This commit is contained in:
Robert 2020-02-14 19:57:05 +01:00
parent 9fa1ae14cb
commit 97250e62bf

View File

@ -9,20 +9,26 @@ namespace Artemis.Plugins.LayerBrushes.Noise
{
public class NoiseBrush : LayerBrush
{
private const float Scale = 0.12f;
private static readonly Random Rand = new Random();
private float _renderScale;
private readonly OpenSimplexNoise _noise;
private float _x;
private float _y;
private float _z;
private SKBitmap _bitmap;
public NoiseBrush(Layer layer, LayerBrushDescriptor descriptor) : base(layer, descriptor)
{
MainColorProperty = RegisterLayerProperty<SKColor>("Brush.MainColor", "Main color", "The main color of the noise.");
SecondaryColorProperty = RegisterLayerProperty<SKColor>("Brush.SecondaryColor", "Secondary color", "The secondary color of the noise.");
ScaleProperty = RegisterLayerProperty<SKSize>("Brush.Scale", "Scale", "The scale of the noise.");
ScrollSpeedProperty = RegisterLayerProperty<SKPoint>("Brush.ScrollSpeed", "Movement speed", "The speed at which the noise moves vertically and horizontally.");
AnimationSpeedProperty = RegisterLayerProperty<float>("Brush.AnimationSpeed", "Animation speed", "The speed at which the noise moves.");
ScaleProperty.InputAffix = "%";
_x = Rand.Next(0, 4096);
_y = Rand.Next(0, 4096);
_z = Rand.Next(0, 4096);
_noise = new OpenSimplexNoise(Rand.Next(0, 4096));
}
@ -30,16 +36,22 @@ namespace Artemis.Plugins.LayerBrushes.Noise
public LayerProperty<SKColor> MainColorProperty { get; set; }
public LayerProperty<SKColor> SecondaryColorProperty { get; set; }
public LayerProperty<SKSize> ScaleProperty { get; set; }
public LayerProperty<SKPoint> ScrollSpeedProperty { get; set; }
public LayerProperty<float> AnimationSpeedProperty { get; set; }
public override void Update(double deltaTime)
{
// TODO: Come up with a better way to use deltaTime
_x += ScrollSpeedProperty.CurrentValue.X / 500f / (float) deltaTime;
_y += ScrollSpeedProperty.CurrentValue.Y / 500f / (float) deltaTime;
_z += AnimationSpeedProperty.CurrentValue / 500f / 0.04f * (float) deltaTime;
if (_z >= float.MaxValue)
// A telltale sign of someone who can't do math very well
if (float.IsPositiveInfinity(_x) || float.IsNegativeInfinity(_x) || float.IsNaN(_x))
_x = 0;
if (float.IsPositiveInfinity(_y) || float.IsNegativeInfinity(_y) || float.IsNaN(_y))
_y = 0;
if (float.IsPositiveInfinity(_z) || float.IsNegativeInfinity(_z) || float.IsNaN(_z))
_z = 0;
base.Update(deltaTime);
}
@ -48,42 +60,50 @@ namespace Artemis.Plugins.LayerBrushes.Noise
var mainColor = MainColorProperty.CurrentValue;
var scale = ScaleProperty.CurrentValue;
// Scale down the render path to avoid computing a value for every pixel
var width = Math.Floor(path.Bounds.Width * Scale);
var height = Math.Floor(path.Bounds.Height * Scale);
var width = Math.Floor(path.Bounds.Width * RenderScale);
var height = Math.Floor(path.Bounds.Height * RenderScale);
CreateBitmap((int) width, (int) height);
var opacity = (float) Math.Round(mainColor.Alpha / 255.0, 2, MidpointRounding.AwayFromZero);
using (var bitmap = new SKBitmap(new SKImageInfo((int) width, (int) height)))
_bitmap.Erase(SKColor.Empty);
for (var x = 0; x < width; x++)
{
bitmap.Erase(SKColor.Empty);
for (var x = 0; x < width; x++)
var scrolledX = x + _x;
for (var y = 0; y < height; y++)
{
for (var y = 0; y < height; y++)
{
var v = _noise.Evaluate(0.1f * scale.Width * x / width, 0.1f * scale.Height * y / height, _z);
var alpha = (byte) Math.Max(0, Math.Min(255, v * 2000));
// var alpha = (byte) ((v + 1) * 127 * opacity);
// There's some fun stuff we can do here, like creating hard lines
// if (alpha > 128)
// alpha = 255;
// else
// alpha = 0;
bitmap.SetPixel(x, y, new SKColor(mainColor.Red, mainColor.Green, mainColor.Blue, alpha));
}
var scrolledY = y + _y;
var v = _noise.Evaluate(0.1f * scale.Width * scrolledX / width, 0.1f * scale.Height * scrolledY / height, _z);
var alpha = (byte) Math.Max(0, Math.Min(255, v * 1024));
_bitmap.SetPixel(x, y, new SKColor(mainColor.Red, mainColor.Green, mainColor.Blue, (byte) (alpha * opacity)));
}
}
var bitmapTransform = SKMatrix.Concat(
SKMatrix.MakeTranslation(path.Bounds.Left, path.Bounds.Top),
SKMatrix.MakeScale(1f / RenderScale, 1f / RenderScale)
);
using (var backgroundShader = SKShader.CreateColor(SecondaryColorProperty.CurrentValue))
using (var foregroundShader = SKShader.CreateBitmap(_bitmap, SKShaderTileMode.Clamp, SKShaderTileMode.Clamp, bitmapTransform))
{
canvas.ClipPath(path);
paint.Shader = backgroundShader;
canvas.DrawRect(path.Bounds, paint);
paint.Shader = foregroundShader;
canvas.DrawRect(path.Bounds, paint);
}
}
var makeTranslation = SKMatrix.MakeTranslation(path.Bounds.Left , path.Bounds.Top );
SKMatrix.Concat(ref makeTranslation, makeTranslation, SKMatrix.MakeScale(1f / Scale, 1f / Scale));
using (var sh = SKShader.CreateBitmap(bitmap, SKShaderTileMode.Mirror, SKShaderTileMode.Mirror, makeTranslation))
{
paint.FilterQuality = SKFilterQuality.Low;
paint.ImageFilter = SKImageFilter.CreateBlur(2,2);
paint.Shader = SKShader.CreateColor(SecondaryColorProperty.CurrentValue);
canvas.DrawPath(path, paint);
paint.Shader = sh;
canvas.DrawPath(path, paint);
}
private void CreateBitmap(int width, int height)
{
if (_bitmap == null)
{
_bitmap = new SKBitmap(new SKImageInfo(width, height));
}
else if (_bitmap.Width != width || _bitmap.Height != height)
{
_bitmap.Dispose();
_bitmap = new SKBitmap(new SKImageInfo(width, height));
}
}
}