Skip to content

Instantly share code, notes, and snippets.

@stelabouras
Forked from Donnotron666/EdgeMapUtils.cs
Created October 10, 2023 16:29
Show Gist options
  • Save stelabouras/1bf80b252044db7974c57dd6dabee9af to your computer and use it in GitHub Desktop.
Save stelabouras/1bf80b252044db7974c57dd6dabee9af to your computer and use it in GitHub Desktop.

Revisions

  1. @Donnotron666 Donnotron666 created this gist Sep 24, 2023.
    127 changes: 127 additions & 0 deletions EdgeMapUtils.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEditor;
    using UnityEngine;

    namespace Editor.Utility
    {
    public static class EdgeMapUtils
    {
    public const int EDGE_SIZE = 2;

    public static void Update(IEnumerable<Sprite> spr)
    {
    foreach (var s in spr)
    Update(s);
    }

    private static void Update(Sprite s)
    {
    //aaahaha, ok, oh boy. Yeah, scan the sprite on the cpu, look for edges and plug those into a texture
    //make sprite readable
    var test = s.texture;
    var path = AssetDatabase.GetAssetPath(s);
    var spriteTi = (TextureImporter)TextureImporter.GetAtPath(path);
    spriteTi.isReadable = true;
    AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

    //DO STUFF
    var edges = BuildEdgeTexture(s);
    var savedEdgePath = SaveEdges(s, path, edges);

    //link it to sprite as a secondary map
    SpriteUtils.TryAddSecondaryTexture(spriteTi, "_EdgeMap", savedEdgePath);

    //put sprite back the way it was.
    spriteTi.isReadable = false;


    }

    private static string SaveEdges(Sprite s, string path, Texture2D edges)
    {
    var folder = path.Remove(path.LastIndexOf(s.name) - 1);

    EditorUtils.LazyCreateFolder(folder, "EdgeMaps");

    var edgePath = $"{folder}/EdgeMaps/{s.name}_edges.png";

    var bytes = edges.EncodeToPNG();
    System.IO.File.WriteAllBytes(edgePath, bytes);
    AssetDatabase.ImportAsset(edgePath, ImportAssetOptions.ForceSynchronousImport);
    //AssetDatabase.CreateAsset(edges, edgePath);

    var ti = AssetImporter.GetAtPath(edgePath) as TextureImporter;
    ti.textureType = TextureImporterType.Sprite;
    ti.filterMode = FilterMode.Point;
    ti.textureCompression = TextureImporterCompression.Uncompressed;
    ti.mipmapEnabled = false;
    ti.alphaIsTransparency = false;
    EditorUtility.SetDirty(ti);
    ti.SaveAndReimport();

    return edgePath;
    }


    private static Texture2D BuildEdgeTexture(Sprite s)
    {
    var edges = new Texture2D(s.texture.width, s.texture.height, TextureFormat.RGBA32, false);
    for (int x = 0; x < s.texture.width; x++)
    {
    for (int y = 0; y < s.texture.height; y++)
    {
    edges.SetPixel(x, y, GetEdge(s, x, y));
    }
    }
    edges.Apply();

    return edges;
    }

    //encodes edge information into 1 channel of the texture
    private static Color GetEdge(Sprite s, int x, int y)
    {
    //MY COUNTERPART IS CustomRenderGraphBlock.hlsl.getSpriteEdges_float
    var col = new Color(0, 0, 0, 0);
    var px = s.texture.GetPixel(x, y);
    if (px.a < 1)
    {
    return col;
    }
    else
    {
    for (int edgeTest = EDGE_SIZE; edgeTest >= 0; edgeTest--)
    {
    float edgeAlpha = 1f - (float)edgeTest / ((float)EDGE_SIZE + 1f);
    //test up
    if (IsEdge(s, x, y + edgeTest))
    col.r = edgeAlpha;

    //test right
    if (IsEdge(s, x + edgeTest, y))
    col.g = edgeAlpha;

    //test left
    if (IsEdge(s, x - edgeTest, y))
    col.b = edgeAlpha;

    //test bot
    if (IsEdge(s, x, y - edgeTest))
    col.a = edgeAlpha;
    }

    }
    return col;

    }

    private static bool IsEdge(Sprite s, int x, int y)
    {
    if (x < 0 || y < 0 || x >= s.texture.width || y >= s.texture.height)
    return true;
    else return s.texture.GetPixel(x, y).a == 0f;
    }
    }
    }