From 93002270d5f40698c36fb3d8c984eaf5d7ed0581 Mon Sep 17 00:00:00 2001 From: Samuele Lorefice Date: Tue, 8 Apr 2025 21:39:06 +0200 Subject: [PATCH] Changed blur iterations to reuse buffers. Huge memory savings + speedup --- SDFMapCreator.sln.DotSettings.user | 2 ++ SDFMapCreator/Program.cs | 14 ++++++-------- SDFMapCreator/SdfKernels.Kernels.cs | 5 ++++- SDFMapCreator/SdfKernels.cs | 16 +++++++++------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/SDFMapCreator.sln.DotSettings.user b/SDFMapCreator.sln.DotSettings.user index 3766494..894dc10 100644 --- a/SDFMapCreator.sln.DotSettings.user +++ b/SDFMapCreator.sln.DotSettings.user @@ -10,6 +10,8 @@ ForceIncluded ForceIncluded ForceIncluded + 52428800 + 26214400 <AssemblyExplorer> <Assembly Path="/mnt/nvme2/Railgun/SDFMapCreator/SDFMapCreator/bin/Debug/net8.0/Magick.NET-Q16-HDRI-OpenMP-x64.dll" /> </AssemblyExplorer> \ No newline at end of file diff --git a/SDFMapCreator/Program.cs b/SDFMapCreator/Program.cs index 8320b5c..3509341 100644 --- a/SDFMapCreator/Program.cs +++ b/SDFMapCreator/Program.cs @@ -177,10 +177,8 @@ public static class Program { var sigma = options.BlurSigma; var totalMask = SelfMask(Images[^1].Pixels); if(options.Debug) totalMask.SaveImage($"{debugPath}{PSep}TotalMask.png"); - for (var i = 0; i < iterations; i++) { - Console.WriteLine($"Applying directional blur {i + 1}/{iterations}..."); - finalImage = DirectionalBlur(finalImage, totalMask, radius, step, sigma); - } + + finalImage = DirectionalBlur(finalImage, totalMask, iterations, radius, step, sigma); finalImage.SaveImage(options.OutputFile); Console.WriteLine("Done!"); @@ -237,15 +235,15 @@ public static class Program { return new(temp); } - static Vector3[,] DirectionalBlur(Vector3[,] image, Vector3[,] mask, float radius = 3f, float step = .5f, float sigma = 1f) { + static Vector3[,] DirectionalBlur(Vector3[,] image, Vector3[,] mask, int iterations, float radius = 3f, float step = .5f, float sigma = 1f) { var sw = new Stopwatch(); sw.Start(); - kernels.DirectionalBlur(image, mask, out var temp, radius, step, sigma); + kernels.DirectionalBlur(image, mask, out var temp, iterations, radius, step, sigma); Console.WriteLine( - $"Directional Blur Time: {sw.Elapsed.TotalSeconds:N4}s ({width * height / sw.Elapsed.TotalSeconds:N0} pixels/s)"); + $"Directional Blur Time: {sw.Elapsed.TotalSeconds:N4}s ({width * height * iterations / sw.Elapsed.TotalSeconds:N0} pixels/s)"); return temp; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] static float EuclideanDistance(Vector2 a, Vector2 b) => MathF.Sqrt(MathF.Pow(a.X - b.X, 2) + MathF.Pow(a.Y - b.Y, 2)); diff --git a/SDFMapCreator/SdfKernels.Kernels.cs b/SDFMapCreator/SdfKernels.Kernels.cs index ae8566b..550347d 100644 --- a/SDFMapCreator/SdfKernels.Kernels.cs +++ b/SDFMapCreator/SdfKernels.Kernels.cs @@ -137,10 +137,13 @@ public partial class SdfKernels { output[x, y] = value; return; } + + //clean up the buffer in case + output[index] = new(0f, 0f, 0f); gradient = Vector2.Normalize(gradient); float sum = 0; - + // now we follow the direction line and sample the image for length; for (var l = -radius; l <= radius; l += step) { var xOffset = (gradient.X * l); diff --git a/SDFMapCreator/SdfKernels.cs b/SDFMapCreator/SdfKernels.cs index 6186dc6..ae0c99c 100644 --- a/SDFMapCreator/SdfKernels.cs +++ b/SDFMapCreator/SdfKernels.cs @@ -170,8 +170,8 @@ public partial class SdfKernels { gradient = bufferGradient.GetAsArray2D(); } - - public void DirectionalBlur(Vector3[,] image, Vector3[,] mask, out Vector3[,] output, float radius = 3f, + + public void DirectionalBlur(Vector3[,] image, Vector3[,] mask, out Vector3[,] output, int iterations, float radius = 3f, float step = .5f, float sigma = 1f) { var width = image.GetLength(0); var height = image.GetLength(1); @@ -190,11 +190,13 @@ public partial class SdfKernels { ArrayView2D, ArrayView2D, float, float, float, int, int>(DirectionalBlurKernel); - - blurKernel(new(width, height), imageBuffer.View, maskBuffer.View, outputBuffer.View, - radius, step, sigma, width, height); - - accelerator.Synchronize(); + + var stream = accelerator.DefaultStream; + for (int i = 0; i < iterations; i++) { + if (i > 0) outputBuffer.CopyTo(stream, imageBuffer); + blurKernel(new(width, height), imageBuffer.View, maskBuffer.View, outputBuffer.View, radius, step, sigma, width, height); + accelerator.Synchronize(); + } output = outputBuffer.GetAsArray2D(); }