Browse Source

Added offset to noise and fixed math node no context

flabbet 1 year ago
parent
commit
18c477edc6

+ 23 - 14
src/PixiEditor.ChangeableDocument/Changeables/Graph/Context/FuncContext.cs

@@ -124,11 +124,14 @@ public class FuncContext
 
     public Float1 GetValue(FuncInputProperty<Float1> getFrom)
     {
-        if (getFrom.Connection == null || !IsFuncType(getFrom))
+        if (HasContext)
         {
-            string uniformName = $"float_{Builder.GetUniqueNameNumber()}";
-            Builder.AddUniform(uniformName, (float)getFrom.Value(this).ConstantValue);
-            return new Float1(uniformName);
+            if (getFrom.Connection == null || !IsFuncType(getFrom))
+            {
+                string uniformName = $"float_{Builder.GetUniqueNameNumber()}";
+                Builder.AddUniform(uniformName, (float)getFrom.Value(this).ConstantValue);
+                return new Float1(uniformName);
+            }
         }
 
         return getFrom.Value(this);
@@ -156,12 +159,15 @@ public class FuncContext
 
     public ShaderExpressionVariable GetValue(FuncInputProperty<Half4> getFrom)
     {
-        if (getFrom.Connection == null || !IsFuncType(getFrom))
+        if (HasContext)
         {
-            Half4 color = getFrom.Value(this);
-            color.VariableName = $"color_{Builder.GetUniqueNameNumber()}";
-            Builder.AddUniform(color.VariableName, color.ConstantValue);
-            return color;
+            if (getFrom.Connection == null || !IsFuncType(getFrom))
+            {
+                Half4 color = getFrom.Value(this);
+                color.VariableName = $"color_{Builder.GetUniqueNameNumber()}";
+                Builder.AddUniform(color.VariableName, color.ConstantValue);
+                return color;
+            }
         }
 
         return getFrom.Value(this);
@@ -169,12 +175,15 @@ public class FuncContext
 
     public Float2 GetValue(FuncInputProperty<Float2> getFrom)
     {
-        if (getFrom.Connection == null || !IsFuncType(getFrom))
+        if (HasContext)
         {
-            Float2 value = getFrom.Value(this);
-            value.VariableName = $"float2_{Builder.GetUniqueNameNumber()}";
-            Builder.AddUniform(value.VariableName, value.ConstantValue);
-            return value;
+            if (getFrom.Connection == null || !IsFuncType(getFrom))
+            {
+                Float2 value = getFrom.Value(this);
+                value.VariableName = $"float2_{Builder.GetUniqueNameNumber()}";
+                Builder.AddUniform(value.VariableName, value.ConstantValue);
+                return value;
+            }
         }
 
         return getFrom.Value(this);

+ 34 - 15
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/MathNode.cs

@@ -34,26 +34,45 @@ public class MathNode : Node
     {
         var (x, y) = GetValues(context);
 
-        var result = Mode.Value switch
+        if (context.HasContext)
         {
-            MathNodeMode.Add => ShaderMath.Add(x, y),
-            MathNodeMode.Subtract => ShaderMath.Subtract(x, y),
-            MathNodeMode.Multiply => ShaderMath.Multiply(x, y),
-            MathNodeMode.Divide => ShaderMath.Divide(x, y),
-            MathNodeMode.Sin => ShaderMath.Sin(x),
-            MathNodeMode.Cos => ShaderMath.Cos(x),
-            MathNodeMode.Tan => ShaderMath.Tan(x),
-        };
+            var result = Mode.Value switch
+            {
+                MathNodeMode.Add => ShaderMath.Add(x, y),
+                MathNodeMode.Subtract => ShaderMath.Subtract(x, y),
+                MathNodeMode.Multiply => ShaderMath.Multiply(x, y),
+                MathNodeMode.Divide => ShaderMath.Divide(x, y),
+                MathNodeMode.Sin => ShaderMath.Sin(x),
+                MathNodeMode.Cos => ShaderMath.Cos(x),
+                MathNodeMode.Tan => ShaderMath.Tan(x),
+            };
 
-        if (Clamp.Value)
-        {
-            result = ShaderMath.Clamp(result, (Float1)0, (Float1)1);
+            if (Clamp.Value)
+            {
+                result = ShaderMath.Clamp(result, (Float1)0, (Float1)1);
+            }
+
+            return context.NewFloat1(result);
         }
-        
-        return context.NewFloat1(result);
+
+        var xConst = x.ConstantValue;
+        var yConst = y.ConstantValue;
+            
+        var constValue = Mode.Value switch
+        {
+            MathNodeMode.Add => xConst + yConst,
+            MathNodeMode.Subtract => xConst - yConst,
+            MathNodeMode.Multiply => xConst * yConst,
+            MathNodeMode.Divide => xConst / yConst,
+            MathNodeMode.Sin => Math.Sin(xConst),
+            MathNodeMode.Cos => Math.Cos(xConst),
+            MathNodeMode.Tan => Math.Tan(xConst),
+        };
+            
+        return new Float1(string.Empty) { ConstantValue = constValue };
     }
 
-    private (Float1 x, Float1 y) GetValues(FuncContext context)
+    private (Float1 xConst, Float1 y) GetValues(FuncContext context)
     {
         return (context.GetValue(X), context.GetValue(Y));
     }

+ 15 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/NoiseNode.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Shaders;
 using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
@@ -15,6 +16,7 @@ public class NoiseNode : Node
     private double previousSeed = double.NaN;
     private NoiseType previousNoiseType = Nodes.NoiseType.FractalPerlin;
     private int previousOctaves = -1;
+    private VecD previousOffset = new VecD(0d, 0d);
 
     private Paint paint = new();
 
@@ -26,6 +28,8 @@ public class NoiseNode : Node
     public InputProperty<NoiseType> NoiseType { get; }
     public InputProperty<VecI> Size { get; }
 
+    public InputProperty<VecD> Offset { get; }
+    
     public InputProperty<double> Scale { get; }
 
     public InputProperty<int> Octaves { get; }
@@ -44,6 +48,8 @@ public class NoiseNode : Node
                 )
             );
 
+        Offset = CreateInput(nameof(Offset), "OFFSET", new VecD(0d, 0d));
+        
         Scale = CreateInput(nameof(Scale), "SCALE", 10d).WithRules(v => v.Min(0.1));
         Octaves = CreateInput(nameof(Octaves), "OCTAVES", 1)
             .WithRules(validator => validator.Min(1));
@@ -57,6 +63,7 @@ public class NoiseNode : Node
             || previousSeed != Seed.Value
             || previousOctaves != Octaves.Value
             || previousNoiseType != NoiseType.Value
+            || previousOffset != Offset.Value
             || double.IsNaN(previousScale))
         {
             if (Scale.Value < 0.000001)
@@ -76,7 +83,7 @@ public class NoiseNode : Node
 
             // Define a grayscale color filter to apply to the image
             paint.ColorFilter = grayscaleFilter;
-
+            
             previousScale = Scale.Value;
             previousSeed = Seed.Value;
             previousOctaves = Octaves.Value;
@@ -93,7 +100,12 @@ public class NoiseNode : Node
 
         var workingSurface = RequestTexture(0, size);
 
+        workingSurface.DrawingSurface.Canvas.Save();
+        workingSurface.DrawingSurface.Canvas.Translate(-(float)Offset.Value.X, -(float)Offset.Value.Y);
+        
         workingSurface.DrawingSurface.Canvas.DrawPaint(paint);
+        
+        workingSurface.DrawingSurface.Canvas.Restore();
 
         Noise.Value = workingSurface;
 
@@ -110,7 +122,8 @@ public class NoiseNode : Node
                 (float)(1d / Scale.Value), octaves, (float)Seed.Value),
             Nodes.NoiseType.FractalPerlin => Shader.CreatePerlinFractalNoise(
                 (float)(1d / Scale.Value),
-                (float)(1d / Scale.Value), octaves, (float)Seed.Value),
+                (float)(1d / Scale.Value),
+                octaves, (float)Seed.Value),
             _ => null
         };
 

+ 2 - 0
src/PixiEditor.DrawingApi.Core/Bridge/NativeObjectsImpl/IShaderImplementation.cs

@@ -1,5 +1,6 @@
 using System;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Shaders;
 using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
@@ -17,4 +18,5 @@ public interface IShaderImplementation
     public Shader CreatePerlinFractalNoise(float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed);
     public object GetNativeShader(IntPtr objectPointer);
     public Shader WithUpdatedUniforms(IntPtr objectPointer, Uniforms uniforms);
+    public void SetLocalMatrix(IntPtr objectPointer, Matrix3X3 matrix);
 }

+ 6 - 0
src/PixiEditor.DrawingApi.Core/Shaders/Shader.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.Bridge;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Exceptions;
+using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surfaces;
 using PixiEditor.Numerics;
 
@@ -57,4 +58,9 @@ public class Shader : NativeObject
     {
         return DrawingBackendApi.Current.ShaderImplementation.CreatePerlinFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed);
     }
+
+    public void SetLocalMatrix(Matrix3X3 matrix)
+    {
+        DrawingBackendApi.Current.ShaderImplementation.SetLocalMatrix(ObjectPointer, matrix);
+    }
 }

+ 11 - 0
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaShaderImplementation.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Shaders;
 using PixiEditor.DrawingApi.Core.Surfaces.PaintImpl;
 using PixiEditor.Numerics;
@@ -122,6 +123,16 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             return new Shader(newShader.Handle);
         }
 
+        public void SetLocalMatrix(IntPtr objectPointer, Matrix3X3 matrix)
+        {
+            if (!ManagedInstances.TryGetValue(objectPointer, out var shader))
+            {
+                throw new InvalidOperationException("Shader does not exist");
+            }
+            
+            shader.WithLocalMatrix(matrix.ToSkMatrix());
+        }
+
         public void Dispose(IntPtr shaderObjPointer)
         {
             if (!ManagedInstances.TryGetValue(shaderObjPointer, out var shader)) return;

+ 2 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -728,5 +728,6 @@
   "CHANGE_ACTIVE_FRAME_PREVIOUS": "Change active frame to previous",
   "CHANGE_ACTIVE_FRAME_NEXT": "Change active frame to next",
   "TOGGLE_ANIMATION": "Toggle animation",
-  "NEW_FROM_CLIPBOARD": "New from clipboard"
+  "NEW_FROM_CLIPBOARD": "New from clipboard",
+  "OFFSET": "Offset"
 }

+ 19 - 16
src/PixiEditor/Views/Visuals/TextureControl.cs

@@ -22,7 +22,7 @@ public class TextureControl : Control
         nameof(Stretch), Stretch.Uniform);
 
     public static readonly StyledProperty<IBrush> BackgroundProperty = AvaloniaProperty.Register<TextureControl, IBrush>
-    (nameof(Background));
+        (nameof(Background));
 
     public Stretch Stretch
     {
@@ -100,12 +100,12 @@ public class TextureControl : Control
         {
             context.FillRectangle(Background, new Rect(Bounds.Size));
         }
-        
+
         if (Texture == null || Texture.IsDisposed)
         {
             return;
         }
-        
+
         Texture texture = Texture;
         texture.DrawingSurface.Flush();
         ICustomDrawOperation drawOperation = new DrawTextureOperation(
@@ -115,20 +115,20 @@ public class TextureControl : Control
 
         context.Custom(drawOperation);
     }
-    
+
     private void OnTextureChanged(AvaloniaPropertyChangedEventArgs<Texture> args)
     {
         if (args.OldValue.Value != null)
         {
             args.OldValue.Value.Changed -= TextureOnChanged;
         }
-        
+
         if (args.NewValue.Value != null)
         {
             args.NewValue.Value.Changed += TextureOnChanged;
         }
     }
-    
+
     private void TextureOnChanged(RectD? changedRect)
     {
         Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Render);
@@ -153,19 +153,22 @@ internal class DrawTextureOperation : SkiaDrawOperation
 
     public override void Render(ISkiaSharpApiLease lease)
     {
-        if (Texture == null || Texture.IsDisposed)
+        lock (Texture)
         {
-            return;
-        }
-        
-        SKCanvas canvas = lease.SkCanvas;
+            if (Texture == null || Texture.IsDisposed)
+            {
+                return;
+            }
 
-        using var ctx = DrawingBackendApi.Current.RenderOnDifferentGrContext(lease.GrContext);
+            SKCanvas canvas = lease.SkCanvas;
 
-        canvas.Save();
-        ScaleCanvas(canvas);
-        canvas.DrawSurface(Texture.DrawingSurface.Native as SKSurface, 0, 0, Paint?.Native as SKPaint ?? null);
-        canvas.Restore();
+            using var ctx = DrawingBackendApi.Current.RenderOnDifferentGrContext(lease.GrContext);
+
+            canvas.Save();
+            ScaleCanvas(canvas);
+            canvas.DrawSurface(Texture.DrawingSurface.Native as SKSurface, 0, 0, Paint?.Native as SKPaint ?? null);
+            canvas.Restore();
+        }
     }
 
     private void ScaleCanvas(SKCanvas canvas)