ソースを参照

Fixed tiling rendering and centered some node previews

Krzysztof Krysiński 1 週間 前
コミット
d389ff8a2b

+ 3 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/OutputNode.cs

@@ -45,10 +45,13 @@ public class OutputNode : Node, IRenderInput
             int saved = texture.DrawingSurface.Canvas.Save();
 
             VecD scaling = PreviewUtility.CalculateUniformScaling(context.DocumentSize, texture.Size);
+            VecD offset = PreviewUtility.CalculateCenteringOffset(context.DocumentSize, texture.Size, scaling);
+            texture.DrawingSurface.Canvas.Translate((float)offset.X, (float)offset.Y);
             texture.DrawingSurface.Canvas.Scale((float)scaling.X, (float)scaling.Y);
             var previewCtx =
                 PreviewUtility.CreatePreviewContext(context, scaling, context.RenderOutputSize, texture.Size);
 
+            texture.DrawingSurface.Canvas.Clear();
             Input.Value?.Paint(previewCtx, texture.DrawingSurface);
             texture.DrawingSurface.Canvas.RestoreToCount(saved);
         }

+ 4 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/RenderNode.cs

@@ -106,10 +106,12 @@ public abstract class RenderNode : Node, IHighDpiRenderNode
             int saved = preview.Texture.DrawingSurface.Canvas.Save();
             preview.Texture.DrawingSurface.Canvas.Clear();
 
-            VecD scaling = PreviewUtility.CalculateUniformScaling(ctx.DocumentSize, preview.Texture.Size);
+            VecD scaling = PreviewUtility.CalculateUniformScaling(ctx.RenderOutputSize, preview.Texture.Size);
+            VecD offset = PreviewUtility.CalculateCenteringOffset(ctx.RenderOutputSize, preview.Texture.Size, scaling);
             RenderContext adjusted =
-                PreviewUtility.CreatePreviewContext(ctx, scaling, ctx.DocumentSize, preview.Texture.Size);
+                PreviewUtility.CreatePreviewContext(ctx, scaling, ctx.RenderOutputSize, preview.Texture.Size);
 
+            preview.Texture.DrawingSurface.Canvas.Translate((float)offset.X, (float)offset.Y);
             preview.Texture.DrawingSurface.Canvas.Scale((float)scaling.X, (float)scaling.Y);
 
             RenderPreview(preview.Texture.DrawingSurface, adjusted, preview.ElementToRender);

+ 3 - 2
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/ShaderNode.cs

@@ -24,7 +24,6 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
     private string lastShaderCode;
     private Paint paint;
 
-    private VecI lastDocumentSize;
     private List<Shader> lastCustomImageShaders = new();
 
     private Dictionary<string, (InputProperty prop, UniformValueType valueType)> uniformInputs = new();
@@ -75,7 +74,6 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
             shader = shader.WithUpdatedUniforms(uniforms);
         }
 
-        lastDocumentSize = context.DocumentSize;
         paint.Shader = shader;
     }
 
@@ -209,7 +207,10 @@ public class ShaderNode : RenderNode, IRenderInput, ICustomShaderNode
 
     public override void RenderPreview(DrawingSurface renderOn, RenderContext context, string elementToRenderName)
     {
+        int saved = renderOn.Canvas.Save();
+        renderOn.Canvas.Scale((float)context.ChunkResolution.InvertedMultiplier());
         OnPaint(context, renderOn);
+        renderOn.Canvas.RestoreToCount(saved);
     }
 
     public override Node CreateCopy()

+ 9 - 0
src/PixiEditor.ChangeableDocument/Rendering/PreviewUtility.cs

@@ -28,6 +28,15 @@ public static class PreviewUtility
         return new VecD(uniformScale, uniformScale);
     }
 
+    public static VecD CalculateCenteringOffset(VecD originalSize, VecD targetSize, VecD scaling)
+    {
+        if (originalSize.X == 0 || originalSize.Y == 0)
+            return VecD.Zero;
+
+        VecD scaledOriginal = originalSize.Multiply(scaling);
+        return (targetSize - scaledOriginal) / 2;
+    }
+
     public static RenderContext CreatePreviewContext(RenderContext ctx, VecD scaling, VecD renderSize, VecD textureSize)
     {
         var clone = ctx.Clone();

+ 8 - 5
src/PixiEditor/Models/Rendering/SceneRenderer.cs

@@ -75,7 +75,6 @@ internal class SceneRenderer : IDisposable
         /*TODO:
          - [ ] Onion skinning
          - [ ] Previews generation
-         - [ ] Panning doesn't rerender in cases where it should
          - [ ] Rendering optimizer
          - [?] Render thread and proper locking/synchronization
          */
@@ -92,7 +91,7 @@ internal class SceneRenderer : IDisposable
 
         IReadOnlyNodeGraph finalGraph = RenderingUtils.SolveFinalNodeGraph(targetOutput, Document);
         bool shouldRerender =
-            ShouldRerender(renderTargetSize, targetMatrix, resolution, viewportId, targetOutput, finalGraph, previewTextures);
+            ShouldRerender(renderTargetSize, targetMatrix, resolution, viewportId, targetOutput, finalGraph, previewTextures, visibleDocumentRegion);
 
         if (shouldRerender)
         {
@@ -182,7 +181,8 @@ internal class SceneRenderer : IDisposable
     private bool ShouldRerender(VecI targetSize, Matrix3X3 matrix, ChunkResolution resolution,
         Guid viewportId,
         string targetOutput,
-        IReadOnlyNodeGraph finalGraph, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures)
+        IReadOnlyNodeGraph finalGraph, Dictionary<Guid, List<PreviewRenderRequest>>? previewTextures,
+        RectI? visibleDocumentRegion)
     {
         if (!DocumentViewModel.SceneTextures.TryGetValue(viewportId, out var cachedTexture) || cachedTexture == null ||
             cachedTexture.IsDisposed)
@@ -206,7 +206,8 @@ internal class SceneRenderer : IDisposable
             ChunkResolution = resolution,
             HighResRendering = HighResRendering,
             TargetOutput = targetOutput,
-            GraphCacheHash = finalGraph.GetCacheHash()
+            GraphCacheHash = finalGraph.GetCacheHash(),
+            VisibleDocumentRegion = (RectD?)visibleDocumentRegion ?? new RectD(0, 0, Document.Size.X, Document.Size.Y)
         };
 
         if (lastRenderedStates.TryGetValue(viewportId, out var lastState))
@@ -349,10 +350,12 @@ struct RenderState
     public bool HighResRendering { get; set; }
     public string TargetOutput { get; set; }
     public int GraphCacheHash { get; set; }
+    public RectD VisibleDocumentRegion { get; set; }
 
     public bool Equals(RenderState other)
     {
         return ChunkResolution.Equals(other.ChunkResolution) && HighResRendering == other.HighResRendering &&
-               TargetOutput == other.TargetOutput && GraphCacheHash == other.GraphCacheHash;
+               TargetOutput == other.TargetOutput && GraphCacheHash == other.GraphCacheHash &&
+               VisibleDocumentRegion == other.VisibleDocumentRegion;
     }
 }

+ 3 - 2
src/PixiEditor/Views/Rendering/Scene.cs

@@ -347,8 +347,9 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         DrawOverlays(texture, bounds, OverlayRenderSorting.Background);
         try
         {
-            var tex = Document.SceneTextures[ViewportId];
-
+            if(Document == null || Document.SceneTextures.TryGetValue(ViewportId, out var tex) == false)
+                return;
+            
             bool hasSaved = false;
             int saved = -1;