Cleanup and added formatting rules. Reformatted
This commit is contained in:
15
SDFMapCreator.sln.DotSettings
Normal file
15
SDFMapCreator.sln.DotSettings
Normal file
@@ -0,0 +1,15 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseVar</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_LOCK/@EntryValue">NotRequired</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_REDUNDANT/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue">ExpressionBody</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/MODIFIERS_ORDER/@EntryValue">public private protected internal file new static abstract virtual override readonly sealed extern unsafe volatile async required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_EXPR_METHOD_ON_SINGLE_LINE/@EntryValue">IF_OWNER_IS_SINGLE_LINE</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALLOW_COMMENT_AFTER_LBRACE/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_INVOCABLE/@EntryValue">1</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FOR_STMT/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_ARROW_WITH_EXPRESSIONS/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">151</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_OBJECT_AND_COLLECTION_INITIALIZER_STYLE/@EntryValue">WRAP_IF_LONG</s:String></wpf:ResourceDictionary>
|
||||
@@ -18,14 +18,14 @@ public static class ImageUtil {
|
||||
|
||||
static T[,] ProcessPixelsRgba64<T>(this Image<Rgba64> image) where T : struct, IEquatable<T> {
|
||||
var max = 65535f;
|
||||
int width = image.Width;
|
||||
int height = image.Height;
|
||||
var width = image.Width;
|
||||
var height = image.Height;
|
||||
var result = new T[image.Width, image.Height];
|
||||
image.ProcessPixelRows(accessor => {
|
||||
//we use Y as the row index and X as the column index
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var span = accessor.GetRowSpan(y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
switch (result) {
|
||||
case float[,] f:
|
||||
f[x, y] = span[x].R / max * (span[x].A / max);
|
||||
@@ -37,7 +37,7 @@ public static class ImageUtil {
|
||||
f[x, y] = new Vector3(span[x].R / max, span[x].G / max, span[x].B / max) * new Vector3(span[x].A / max);
|
||||
break;
|
||||
case Vector4[,] f:
|
||||
f[x, y] = new Vector4(span[x].R / max, span[x].G / max, span[x].B / max, span[x].A / max);
|
||||
f[x, y] = new(span[x].R / max, span[x].G / max, span[x].B / max, span[x].A / max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -48,14 +48,14 @@ public static class ImageUtil {
|
||||
|
||||
static T[,] ProcessPixelsRgb24<T>(this Image<Rgb24> image) where T : struct, IEquatable<T> {
|
||||
var max = 255f;
|
||||
int width = image.Width;
|
||||
int height = image.Height;
|
||||
var width = image.Width;
|
||||
var height = image.Height;
|
||||
var result = new T[image.Width, image.Height];
|
||||
image.ProcessPixelRows(accessor => {
|
||||
//we use Y as the row index and X as the column index
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var span = accessor.GetRowSpan(y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
switch (result) {
|
||||
case float[,] f:
|
||||
f[x, y] = span[x].R / max;
|
||||
@@ -78,14 +78,14 @@ public static class ImageUtil {
|
||||
|
||||
static T[,] ProcessPixelsRgba32<T>(this Image<Rgba32> image) where T : struct, IEquatable<T> {
|
||||
var max = 255f;
|
||||
int width = image.Width;
|
||||
int height = image.Height;
|
||||
var width = image.Width;
|
||||
var height = image.Height;
|
||||
var result = new T[image.Width, image.Height];
|
||||
image.ProcessPixelRows(accessor => {
|
||||
//we use Y as the row index and X as the column index
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var span = accessor.GetRowSpan(y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
switch (result) {
|
||||
case float[,] f:
|
||||
f[x, y] = span[x].R / max * (span[x].A / max);
|
||||
@@ -97,7 +97,7 @@ public static class ImageUtil {
|
||||
f[x, y] = new Vector3(span[x].R / max, span[x].G / max, span[x].B / max) * new Vector3(span[x].A / max);
|
||||
break;
|
||||
case Vector4[,] f:
|
||||
f[x, y] = new Vector4(span[x].R / max, span[x].G / max, span[x].B / max, span[x].A / max);
|
||||
f[x, y] = new(span[x].R / max, span[x].G / max, span[x].B / max, span[x].A / max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -108,14 +108,14 @@ public static class ImageUtil {
|
||||
|
||||
static T[,] ProcessPixelsRgb48<T>(this Image<Rgb48> image) where T : struct, IEquatable<T> {
|
||||
var max = 65535f;
|
||||
int width = image.Width;
|
||||
int height = image.Height;
|
||||
var width = image.Width;
|
||||
var height = image.Height;
|
||||
var result = new T[image.Width, image.Height];
|
||||
image.ProcessPixelRows(accessor => {
|
||||
//we use Y as the row index and X as the column index
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var span = accessor.GetRowSpan(y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
switch (result) {
|
||||
case float[,] f:
|
||||
f[x, y] = span[x].R / max;
|
||||
@@ -149,21 +149,21 @@ public static class ImageUtil {
|
||||
Console.Write($"Writing image {path}...");
|
||||
using Image<Rgb48> image = new(width, height);
|
||||
image.ProcessPixelRows(accessor => {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var span = accessor.GetRowSpan(y);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (var x = 0; x < width; x++) {
|
||||
switch (array) {
|
||||
case float[,] f:
|
||||
span[x] = new Rgb48((ushort)(f[x, y] * 65535), (ushort)(f[x, y] * 65535), (ushort)(f[x,y] * 65535));
|
||||
span[x] = new((ushort)(f[x, y] * 65535), (ushort)(f[x, y] * 65535), (ushort)(f[x, y] * 65535));
|
||||
break;
|
||||
case Vector2[,] f:
|
||||
span[x] = new Rgb48((ushort)(f[x,y].X * 65535), (ushort)(f[x,y].Y * 65535), 0);
|
||||
span[x] = new((ushort)(f[x, y].X * 65535), (ushort)(f[x, y].Y * 65535), 0);
|
||||
break;
|
||||
case Vector3[,] f:
|
||||
span[x] = new Rgb48((ushort)(f[x,y].X * 65535), (ushort)(f[x,y].Y * 65535), (ushort)(f[x,y].Z * 65535));
|
||||
span[x] = new((ushort)(f[x, y].X * 65535), (ushort)(f[x, y].Y * 65535), (ushort)(f[x, y].Z * 65535));
|
||||
break;
|
||||
case Vector4[,] f:
|
||||
span[x] = new Rgb48((ushort)(f[x,y].X * 65535), (ushort)(f[x,y].Y * 65535), (ushort)(f[x,y].Z * 65535));
|
||||
span[x] = new((ushort)(f[x, y].X * 65535), (ushort)(f[x, y].Y * 65535), (ushort)(f[x, y].Z * 65535));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public static class ImageUtil {
|
||||
image.Save(path);
|
||||
}
|
||||
|
||||
private static void ImageData(SixLabors.ImageSharp.Image image1, string path) {
|
||||
static void ImageData(SixLabors.ImageSharp.Image image1, string path) {
|
||||
Console.WriteLine(
|
||||
$"""
|
||||
Image file: {path}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using SDFMapCreator;
|
||||
|
||||
public class Program {
|
||||
private const float MAX = 1f;
|
||||
private const float MIN = 0f;
|
||||
private static readonly int MAX_THREADS = Environment.ProcessorCount - 2;
|
||||
private static bool debug = true;
|
||||
namespace SDFMapCreator;
|
||||
|
||||
public static class Program {
|
||||
const float MAX = 1f;
|
||||
const float MIN = 0f;
|
||||
static readonly int MAX_THREADS = Environment.ProcessorCount - 2;
|
||||
static bool debug = true;
|
||||
static readonly ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = MAX_THREADS };
|
||||
static List<Image> Images = new();
|
||||
static List<MaskData> ImageMasks = new();
|
||||
@@ -29,7 +30,7 @@ public class Program {
|
||||
}
|
||||
|
||||
var imagesPath = "images";
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (var i = 0; i < 8; i++) {
|
||||
var pixels = ImageUtil.LoadImage<Vector3>($"./{imagesPath}{Path.DirectorySeparatorChar}{i + 1:00}.png");
|
||||
Images.Add(new(pixels, pixels.GetLength(0), pixels.GetLength(1)));
|
||||
}
|
||||
@@ -54,7 +55,7 @@ public class Program {
|
||||
height = (uint)Images[0].Height;
|
||||
|
||||
Console.WriteLine("Creating masks...");
|
||||
for (int i = 0; i < Images.Count; i++) { //for each image pair, create a mask
|
||||
for (var i = 0; i < Images.Count; i++) { //for each image pair, create a mask
|
||||
var selfMask = SelfMask(Images[i].Pixels);
|
||||
ImageMasks.Add(new(selfMask, Images[i], new()));
|
||||
if (debug) selfMask.SaveImage($"Debug/selfMask{i}.png");
|
||||
@@ -71,7 +72,9 @@ public class Program {
|
||||
ConsoleUpdateLine($"Edge detecting mask {ImageMasks.IndexOf(mask)}...");
|
||||
EdgeDetect(mask);
|
||||
}
|
||||
if (debug) for (int i = 0; i < TransitionMasks.Count; i++) ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png");
|
||||
if (debug)
|
||||
for (var i = 0; i < TransitionMasks.Count; i++)
|
||||
ImageMasks[i].Mask.SaveImage($"Debug/mask{i}.png");
|
||||
|
||||
Console.WriteLine("Creating SDFs...");
|
||||
for (var i = 0; i < ImageMasks.Count; i++) {
|
||||
@@ -91,11 +94,11 @@ public class Program {
|
||||
// generate final image
|
||||
var finalImage = new Vector3[width, height];
|
||||
var currStep = 0f;
|
||||
var stepIncrement = MAX / (Gradients.Count);
|
||||
var stepIncrement = MAX / Gradients.Count;
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
for (int y = 0; y < height; y++)
|
||||
finalImage[x, y] = new Vector3(Images[0].Pixels[x, y].X);
|
||||
for (var x = 0; x < width; x++)
|
||||
for (var y = 0; y < height; y++)
|
||||
finalImage[x, y] = new(Images[0].Pixels[x, y].X);
|
||||
|
||||
for (var i = 0; i < Gradients.Count; i++) {
|
||||
var mask = ImageMasks[i + 1];
|
||||
@@ -117,8 +120,7 @@ public class Program {
|
||||
var radius = 3f;
|
||||
var step = .5f;
|
||||
var sigma = 1f;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
for (var i = 0; i < iterations; i++) {
|
||||
Console.WriteLine($"Applying directional blur {i + 1}/{iterations}...");
|
||||
finalImage = DirectionalBlur(finalImage, ImageMasks[0].Mask, radius, step, sigma);
|
||||
}
|
||||
@@ -127,7 +129,7 @@ public class Program {
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
private static void EdgeDetect(MaskData maskData) {
|
||||
static void EdgeDetect(MaskData maskData) {
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
Console.WriteLine("Running edge detection...");
|
||||
@@ -145,7 +147,6 @@ public class Program {
|
||||
}
|
||||
|
||||
static Vector3[,] Gradient(TransitionMaskData mask, SDFData sdfA, SDFData sdfB) {
|
||||
int iterCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
/*Vector3[,] temp = new Vector3[width, height];
|
||||
@@ -177,35 +178,24 @@ public class Program {
|
||||
}
|
||||
|
||||
static SDFData SDF(MaskData mask) {
|
||||
int iterCount = 0;
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
kernels.Sdf(mask.Edges.ToArray(), (int)width, (int)height, out var temp);
|
||||
|
||||
Console.WriteLine($"\nSDF Generation Time: {sw.Elapsed.TotalSeconds:N4}s ({width * height / sw.Elapsed.TotalSeconds:N0} pixels/s)");
|
||||
|
||||
return new(temp);
|
||||
}
|
||||
|
||||
static Vector3[,] DirectionalBlur(Vector3[,] image, Vector3[,] mask, float radius = 3f, float step = .5f, float sigma = 1f) {
|
||||
var width = (uint)image.GetLength(0);
|
||||
var height = (uint)image.GetLength(1);
|
||||
var output = new Vector3[width, height];
|
||||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
kernels.DirectionalBlur(image, mask, out var temp, radius, step, sigma);
|
||||
|
||||
Console.WriteLine(
|
||||
$"Directional Blur Time: {sw.Elapsed.TotalSeconds:N4}s ({width * height / sw.Elapsed.TotalSeconds:N0} pixels/s)");
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static float EuclideanDistance(Vector2 a, Vector2 b) =>
|
||||
static float EuclideanDistance(Vector2 a, Vector2 b) =>
|
||||
MathF.Sqrt(MathF.Pow(a.X - b.X, 2) + MathF.Pow(a.Y - b.Y, 2));
|
||||
|
||||
static Vector3[,] GetABMask(Vector3[,] A, Vector3[,] B) {
|
||||
@@ -222,7 +212,7 @@ public class Program {
|
||||
where T : INumber<T>, IMultiplyOperators<T, float, T>, IAdditionOperators<T, T, T>
|
||||
=> a * (1 - t) + b * t;
|
||||
|
||||
public static T Remap<T>(T value, T min, T max, T newMin, T newMax)
|
||||
static T Remap<T>(T value, T min, T max, T newMin, T newMax)
|
||||
where T : INumber<T>, ISubtractionOperators<T, T, T>, IMultiplyOperators<T, T, T>, IAdditionOperators<T, T, T>
|
||||
=> (value - min) / (max - min) * (newMax - newMin) + newMin;
|
||||
}
|
||||
@@ -3,10 +3,12 @@ using System.Numerics;
|
||||
namespace SDFMapCreator;
|
||||
|
||||
public record Image(Vector3[,] Pixels, int Width, int Height);
|
||||
|
||||
public record MaskData(Vector3[,] Mask, Image Image, List<Vector2> Edges) {
|
||||
public Vector3[,] Mask { get; set; } = Mask;
|
||||
public List<Vector2> Edges { get; set; } = Edges;
|
||||
}
|
||||
|
||||
public record SDFData(Vector3[,] SDF);
|
||||
|
||||
public record TransitionMaskData(Vector3[,] Mask, Image ImageA, Image ImageB);
|
||||
@@ -5,43 +5,43 @@ using ILGPU.Runtime;
|
||||
namespace SDFMapCreator;
|
||||
|
||||
public partial class SdfKernels {
|
||||
private static void SelfMaskKernel(Index2D index, ArrayView2D<Vector3, Stride2D.DenseX> input, ArrayView2D<Vector3, Stride2D.DenseX> mask) {
|
||||
int x = index.X;
|
||||
int y = index.Y;
|
||||
Vector3 value = input[x, y];
|
||||
float lumaA = (value.X + value.Y + value.Z)/3f;
|
||||
float r = lumaA > 0.99f ? 1f : 0f;
|
||||
static void SelfMaskKernel(Index2D index, ArrayView2D<Vector3, Stride2D.DenseX> input, ArrayView2D<Vector3, Stride2D.DenseX> mask) {
|
||||
var x = index.X;
|
||||
var y = index.Y;
|
||||
var value = input[x, y];
|
||||
var lumaA = (value.X + value.Y + value.Z) / 3f;
|
||||
var r = lumaA > 0.99f ? 1f : 0f;
|
||||
mask[x, y] = new(r, 0f, 0f);
|
||||
}
|
||||
|
||||
private static void ABMaskKernel(Index2D index,
|
||||
static void ABMaskKernel(Index2D index,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> A,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> B,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> mask
|
||||
) {
|
||||
int x = index.X;
|
||||
int y = index.Y;
|
||||
Vector3 valueA = A[x, y];
|
||||
Vector3 valueB = B[x, y];
|
||||
float lumaA = (valueA.X + valueA.Y + valueA.Z) / 3f;
|
||||
float lumaB = (valueB.X + valueB.Y + valueB.Z) / 3f;
|
||||
float r = lumaA > 0.99f && lumaB > 0.99f ? 1f : 0f;
|
||||
var x = index.X;
|
||||
var y = index.Y;
|
||||
var valueA = A[x, y];
|
||||
var valueB = B[x, y];
|
||||
var lumaA = (valueA.X + valueA.Y + valueA.Z) / 3f;
|
||||
var lumaB = (valueB.X + valueB.Y + valueB.Z) / 3f;
|
||||
var r = lumaA > 0.99f && lumaB > 0.99f ? 1f : 0f;
|
||||
mask[x, y] = new(r, 0f, 0f);
|
||||
}
|
||||
|
||||
private static void EdgeKernel(Index2D index,
|
||||
static void EdgeKernel(Index2D index,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> mask,
|
||||
uint width, uint height
|
||||
) { // early exit if not on mask
|
||||
if (mask[index].X == 0f) return;
|
||||
int x = index.X;
|
||||
int y = index.Y;
|
||||
var x = index.X;
|
||||
var y = index.Y;
|
||||
//if we are on the edge of the image, return false
|
||||
if (x == 0 || y == 0 || x == width - 1 || y == height - 1) return;
|
||||
|
||||
//check the 3x3 kernel
|
||||
for (int xi = x - 1; xi <= x + 1; xi++) {
|
||||
for (int yi = y - 1; yi <= y + 1; yi++) {
|
||||
for (var xi = x - 1; xi <= x + 1; xi++) {
|
||||
for (var yi = y - 1; yi <= y + 1; yi++) {
|
||||
if (xi < 0 || xi >= width || yi < 0 || yi >= height)
|
||||
continue; //skip out of bounds pixels
|
||||
if (mask[xi, yi].X == 0f)
|
||||
@@ -50,18 +50,18 @@ public partial class SdfKernels {
|
||||
}
|
||||
}
|
||||
|
||||
private static void SdfKernel(Index2D index,
|
||||
static void SdfKernel(Index2D index,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> sdf,
|
||||
ArrayView1D<Vector2, Stride1D.Dense> edges,
|
||||
int width, int height
|
||||
) {
|
||||
Vector2 pos = new((float)index.X / width, (float)index.Y / height);
|
||||
float minDist = 2f;
|
||||
int count = edges.IntExtent.Size;
|
||||
var minDist = 2f;
|
||||
var count = edges.IntExtent.Size;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
Vector2 edgeNrm = new(edges[i].X / width, edges[i].Y / height);
|
||||
float dist = Vector2.Distance(pos, edgeNrm);
|
||||
var dist = Vector2.Distance(pos, edgeNrm);
|
||||
if (dist < minDist) minDist = dist;
|
||||
}
|
||||
|
||||
@@ -70,47 +70,44 @@ public partial class SdfKernels {
|
||||
sdf[index] = new(minDist);
|
||||
}
|
||||
|
||||
private static void GradientKernel(Index2D index,
|
||||
static void GradientKernel(Index2D index,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> mask,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> sdfa,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> sdfb,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> gradient
|
||||
) { //early exit if not on mask
|
||||
if(mask[index].X == 0f || mask[index].Y == 0f) return;
|
||||
float a = sdfa[index].X; float b = sdfb[index].X;
|
||||
if (mask[index].X == 0f || mask[index].Y > 0f) return;
|
||||
var a = sdfa[index].X;
|
||||
var b = sdfb[index].X;
|
||||
gradient[index] = new(a / (a + b));
|
||||
}
|
||||
|
||||
private static void DirectionalBlurKernel(Index2D index,
|
||||
static void DirectionalBlurKernel(Index2D index,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> image,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> mask,
|
||||
ArrayView2D<Vector3, Stride2D.DenseX> output,
|
||||
float radius, float step, float sigma,
|
||||
int width, int height
|
||||
)
|
||||
{
|
||||
int x = index.X;
|
||||
int y = index.Y;
|
||||
Vector3 value = image[x, y];
|
||||
Vector3 maskValue = mask[x, y];
|
||||
if (maskValue.X == 0f)
|
||||
{
|
||||
) {
|
||||
var x = index.X;
|
||||
var y = index.Y;
|
||||
var value = image[x, y];
|
||||
var maskValue = mask[x, y];
|
||||
if (maskValue.X == 0f) {
|
||||
output[x, y] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
var gradient = Vector2.Zero;
|
||||
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
{
|
||||
for (int dy = -1; dy <= 1; dy++)
|
||||
{
|
||||
for (var dx = -1; dx <= 1; dx++) {
|
||||
for (var dy = -1; dy <= 1; dy++) {
|
||||
if (x + dx < 0 || x + dx >= width || y + dy < 0 || y + dy >= height) continue;
|
||||
gradient += new Vector2(dx, dy) * image[x + dx, y + dy].X;
|
||||
}
|
||||
}
|
||||
|
||||
if (gradient == Vector2.Zero)
|
||||
{
|
||||
if (gradient == Vector2.Zero) {
|
||||
output[x, y] = value;
|
||||
return;
|
||||
}
|
||||
@@ -119,17 +116,16 @@ public partial class SdfKernels {
|
||||
float sum = 0;
|
||||
|
||||
// now we follow the direction line and sample the image for length;
|
||||
for (float l = -radius; l <= radius; l += step)
|
||||
{
|
||||
int xOffset = (int)(gradient.X * l);
|
||||
int yOffset = (int)(gradient.Y * l);
|
||||
int xSample = x + xOffset;
|
||||
int ySample = y + yOffset;
|
||||
for (var l = -radius; l <= radius; l += step) {
|
||||
var xOffset = (int)(gradient.X * l);
|
||||
var yOffset = (int)(gradient.Y * l);
|
||||
var xSample = x + xOffset;
|
||||
var ySample = y + yOffset;
|
||||
|
||||
if (xSample < 0 || xSample >= width || ySample < 0 || ySample >= height) continue;
|
||||
|
||||
Vector3 sampleValue = image[xSample, ySample];
|
||||
float weight = MathF.Exp(-l * l / (2f * sigma * sigma));
|
||||
var sampleValue = image[xSample, ySample];
|
||||
var weight = MathF.Exp(-l * l / (2f * sigma * sigma));
|
||||
output[x, y] += sampleValue * weight;
|
||||
sum += weight;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using ILGPU.Algorithms;
|
||||
namespace SDFMapCreator;
|
||||
|
||||
public partial class SdfKernels {
|
||||
private Context gpuContext;
|
||||
Context gpuContext;
|
||||
|
||||
public SdfKernels() {
|
||||
// Initialize the GPU context
|
||||
@@ -24,30 +24,29 @@ public partial class SdfKernels {
|
||||
|
||||
Console.WriteLine("Reading available accelerators (CUDA only)...");
|
||||
foreach (var device in gpuContext.GetCudaDevices()) {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
using var accelerator = device.CreateAccelerator(gpuContext);
|
||||
Console.WriteLine($"{GetInfoString(accelerator)}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Reading available accelerators (OpenCL only)...");
|
||||
foreach (var device in gpuContext.GetCLDevices()) {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
using var accelerator = device.CreateAccelerator(gpuContext);
|
||||
Console.WriteLine($"{GetInfoString(accelerator)}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Reading available accelerators (CPU only)...");
|
||||
foreach (var device in gpuContext.GetCPUDevices()) {
|
||||
using Accelerator accelerator = device.CreateAccelerator(gpuContext);
|
||||
using var accelerator = device.CreateAccelerator(gpuContext);
|
||||
Console.WriteLine($"{GetInfoString(accelerator)}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SelfMask(Vector3[,] input, out Vector3[,] mask) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = input.GetLength(0);
|
||||
int height = input.GetLength(1);
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
var width = input.GetLength(0);
|
||||
var height = input.GetLength(1);
|
||||
mask = new Vector3[width, height];
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var buffer = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
buffer.CopyFromCPU(input);
|
||||
@@ -65,11 +64,11 @@ public partial class SdfKernels {
|
||||
}
|
||||
|
||||
public void ABMask(Vector3[,] A, Vector3[,] B, out Vector3[,] mask) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = A.GetLength(0);
|
||||
int height = A.GetLength(1);
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
var width = A.GetLength(0);
|
||||
var height = A.GetLength(1);
|
||||
mask = new Vector3[width, height];
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var bufferA = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
bufferA.CopyFromCPU(A);
|
||||
@@ -92,11 +91,11 @@ public partial class SdfKernels {
|
||||
}
|
||||
|
||||
public void EdgeDetect(Vector3[,] mask, out Vector3[,] edge) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = mask.GetLength(0);
|
||||
int height = mask.GetLength(1);
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
var width = mask.GetLength(0);
|
||||
var height = mask.GetLength(1);
|
||||
edge = new Vector3[width, height];
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var buffer = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
buffer.CopyFromCPU(mask);
|
||||
@@ -112,8 +111,8 @@ public partial class SdfKernels {
|
||||
}
|
||||
|
||||
public void Sdf(Vector2[] edges, int width, int height, out Vector3[,] sdf) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var buffer = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
|
||||
@@ -133,11 +132,11 @@ public partial class SdfKernels {
|
||||
}
|
||||
|
||||
public void Gradient(Vector3[,] mask, Vector3[,] sdfa, Vector3[,] sdfb, out Vector3[,] gradient) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = mask.GetLength(0);
|
||||
int height = mask.GetLength(1);
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
var width = mask.GetLength(0);
|
||||
var height = mask.GetLength(1);
|
||||
gradient = new Vector3[width, height];
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var bufferMask = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
bufferMask.CopyFromCPU(mask);
|
||||
@@ -161,13 +160,15 @@ public partial class SdfKernels {
|
||||
accelerator.Synchronize();
|
||||
|
||||
gradient = bufferGradient.GetAsArray2D();
|
||||
}
|
||||
|
||||
public void DirectionalBlur(Vector3[,] image, Vector3[,] mask, out Vector3[,] output, float radius = 3f, float step = .5f, float sigma = 1f) {
|
||||
var dev = gpuContext.GetPreferredDevice(preferCPU:false);
|
||||
int width = image.GetLength(0);
|
||||
int height = image.GetLength(1);
|
||||
public void DirectionalBlur(Vector3[,] image, Vector3[,] mask, out Vector3[,] output, float radius = 3f,
|
||||
float step = .5f, float sigma = 1f) {
|
||||
var dev = gpuContext.GetPreferredDevice(false);
|
||||
var width = image.GetLength(0);
|
||||
var height = image.GetLength(1);
|
||||
output = new Vector3[width, height];
|
||||
using Accelerator accelerator = dev.CreateAccelerator(gpuContext);
|
||||
using var accelerator = dev.CreateAccelerator(gpuContext);
|
||||
|
||||
using var imageBuffer = accelerator.Allocate2DDenseX<Vector3>(new(width, height));
|
||||
imageBuffer.CopyFromCPU(image);
|
||||
@@ -191,9 +192,8 @@ public partial class SdfKernels {
|
||||
output = outputBuffer.GetAsArray2D();
|
||||
}
|
||||
|
||||
private static string GetInfoString(Accelerator a)
|
||||
{
|
||||
StringWriter infoString = new StringWriter();
|
||||
static string GetInfoString(Accelerator a) {
|
||||
var infoString = new StringWriter();
|
||||
a.PrintInformation(infoString);
|
||||
return infoString.ToString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user