Generierung einer Unity-Lärmkarte (Editor-Erweiterung)

Kürzlich habe ich festgestellt, dass viele Shader im Projekt Rauschkarten benötigen. (Shadergraph verfügt über eine eigene Rauschkartengenerierung.) Wenn eine Rauschkarte benötigt wird, ist es sehr mühsam, sie zu finden, also habe ich die Informationen im Internet gelesen und geschrieben eine erweiterte Unity-Lärmkartengenerierung.

Perlin-Geräusch

Perlin-Rauschen ist ein 1983 von Ken Perlin erfundener Gradientenrauschalgorithmus zur Erzeugung zufälliger Texturen mit kontinuierlichen und sanften Änderungen in Computergrafiken. Es wird häufig verwendet, um natürliche Formen wie Berge, Wolken, Wasserwellen usw. zu simulieren. Es kann auch verwendet werden, um Texturen Details und Realismus zu verleihen.

Perlin-Rauschen wird erzeugt, indem
der Raum in eine Reihe regelmäßiger Gitterzellen (normalerweise Quadrate oder Würfel) unterteilt wird.

Generieren Sie zufällig einen Gradientenvektor (normalerweise 2D oder 3D) an der Scheitelpunktposition jeder Gitterzelle.

Für jeden Raumpunkt wird seine Position innerhalb der Gitterzelle berechnet und die Interpolation zwischen ihm und den Gitterscheitelpunkten wird basierend auf dem Gradientenvektor und der Position berechnet. Für die Interpolation können verschiedene Methoden verwendet werden, z. B. lineare Interpolation, kubische Interpolation usw.

Die Interpolationswerte verschiedener Gitterzellen werden gewichtet und addiert, um den endgültigen Perlin-Rauschenwert zu erhalten.
In Unity sind Mathematikbibliotheken verfügbar

Mathf.PerlinNoise(xCoord, yCoord)

Er verwendete einen zweidimensionalen Zufallsvektor, um den ursprünglichen Zufallswert zu ersetzen, sodass zwischen jedem Punkt eine bestimmte Gradiententransformation erzeugt wurde, sodass die erzeugte Rauschkarte kaum eine offensichtliche Blockhaftigkeit spürt.
Fügen Sie hier eine Bildbeschreibung ein

Rufen Sie einfach direkt an

Einfacher Lärm

Simple Noise, auch Value Noise genannt, ist ein relativ einfacher Noise-Algorithmus. Es ist einfacher als Perlin-Rauschen und beinhaltet keine Berechnung von Gradientenvektoren, sondern generiert Zufallswerte an diskreten Gitterpunkten und verwendet dann einen Interpolationsalgorithmus, um Rauschwerte zwischen diesen Zufallswerten zu erhalten.

Der Erzeugungsprozess von einfachem Rauschen ist wie folgt:

Teilen Sie einen Raum in eine Reihe regelmäßiger Gitterzellen (normalerweise Quadrate oder Würfel) auf.

Erzeugt zufällig einen Zufallswert (normalerweise zwischen 0 und 1) an der Scheitelpunktposition jeder Gitterzelle.

Für jeden Raumpunkt wird seine Position innerhalb der Gitterzelle berechnet und basierend auf den Zufallswerten der Eckpunkte interpoliert. Für die Interpolation können verschiedene Methoden verwendet werden, z. B. lineare Interpolation, kubische Interpolation usw.

Ermitteln Sie den Rauschwert an diesem Punkt als Teil einer einfachen Rauschtextur.

Einfaches Rauschen lässt sich schneller berechnen als Perlin-Rauschen, da keine komplexen Gradientenberechnungen erforderlich sind. Das einfache Rauschen zeigt jedoch möglicherweise deutlichere Kanten und Trennlinien in der generierten Textur, da die Interpolationsmethode relativ einfach ist, was dazu führt, dass die Änderung des Rauschens nicht gleichmäßig genug ist.

   //线性差值 1接近Y 0接近X
    float mix(float x, float y, float level)
    {
    
    
        return x * (1 - level) + y * level;
    }
    float value_noise(Vector2 coord)
    {
    
    
        Vector2 i = floor(coord);
        Vector2 f = fract(coord);

        // 4 corners of a rectangle surrounding our point
        float tl = rand(i);
        float tr = rand(i + new Vector2(1.0f, 0.0f));
        float bl = rand(i + new Vector2(0.0f, 1.0f));
        float br = rand(i + new Vector2(1.0f, 1.0f));

        Vector2 cubic = f * f * (new Vector2(3.0f, 3.0f) - 2.0f * f);

        float topmix = mix(tl, tr, cubic.x);
        float botmix = mix(bl, br, cubic.x);
        float wholemix = mix(topmix, botmix, cubic.y);

        return wholemix;

    }

„Blockiges Gefühl“
Fügen Sie hier eine Bildbeschreibung ein

Mobilfunklärm

Es handelt sich um einen Rauscherzeugungsalgorithmus, der die Zellstruktur simuliert. Es wird häufig in der Computergrafik- und Spieleentwicklung verwendet, um Texturen mit feinen Partikeln, Flecken, Löchern und gleichmäßiger Verteilung zu erzeugen. Das Prinzip des Zellrauschens besteht darin, den Raum in viele regelmäßige oder unregelmäßige Zellen zu unterteilen, in jeder Zelle zufällig einen Punkt zu generieren und dann den Abstand von anderen Punkten zum nächstgelegenen Punkt zu berechnen. Diese Entfernungen werden zur Erstellung von Lärmkarten verwendet.

Der Entstehungsprozess von Zellrauschen ist wie folgt:

Teilen Sie den Raum in eine Reihe regelmäßiger oder unregelmäßiger Zellen.

In jeder Zelle wird zufällig ein Punkt generiert, der als „Feature Point“ bezeichnet wird.

Berechnen Sie für jeden Raumpunkt seinen Abstand zum nächstgelegenen Merkmalspunkt. Die Entfernung wird normalerweise anhand der euklidischen Entfernung, der Manhattan-Entfernung usw. berechnet.

Rauschwerte können basierend auf der Entfernung generiert werden, beispielsweise mithilfe von Funktionen wie dem Kehrwert der Entfernung oder dem Kehrquadrat der Entfernung.

Zellrauschen wird häufig verwendet, um fleckige Texturen, gleichmäßig verteilte Partikel, Hauttexturen, Gelände und andere Effekte zu simulieren. Es kann Texturen erzeugen, die sich organisch und natürlich anfühlen, da es auf zellähnlichen Strukturen und nicht auf einfachen Zufallswerten basiert. Zellulares Rauschen ist ein sehr nützliches Werkzeug in der Spieleentwicklung und Computergrafik und kann zur Verbesserung visueller Effekte und zur Erhöhung der Komplexität von Texturen verwendet werden.

float cellular_noise(Vector2 coord)
    {
    
    
        Vector2 i = floor(coord);
        Vector2 f = fract(coord);

        float min_dist = 99999.0f;
        // going through the current tile and the tiles surrounding it
        for (float x = -1.0f; x <= 1.0; x++)
        {
    
    
            for (float y = -1.0f; y <= 1.0; y++)
            {
    
    

                // generate a random point in each tile,
                // but also account for whether it's a farther, neighbouring tile
                Vector2 node = rand2(i + new Vector2(x, y)) + new Vector2(x, y);

                // check for distance to the point in that tile
                // decide whether it's the minimum
                float dist = Mathf.Sqrt((f - node).x * (f - node).x + (f - node).y * (f - node).y);
                min_dist = Mathf.Min(min_dist, dist);
            }
        }
        return min_dist;
    }

Zelle
Fügen Sie hier eine Bildbeschreibung ein

Zufällig pseudozufällig generiert, alle Codes werden später veröffentlicht.

FBM

Fraktales Brownsches Bewegungsrauschen ist ein Algorithmus zur Rauscherzeugung, der auf fraktaler Technologie basiert. Es erzeugt komplexe Textureffekte durch das Stapeln mehrerer Rauschschichten mit unterschiedlichen Frequenzen und Amplituden. FBM-Rauschen wird häufig verwendet, um Texturen mit einem bestimmten Detaillierungsgrad wie Wolken, Flammen, Wellen und anderen Effekten zu erzeugen.

Der Erzeugungsprozess von FBM-Rauschen ist wie folgt:

Teilen Sie einen Raum in eine Reihe regelmäßiger oder unregelmäßiger Gitterzellen (normalerweise Quadrate oder Würfel) auf.

Erzeugt zufällig einen Rauschwert (normalerweise zwischen 0 und 1) an der Scheitelpunktposition jeder Gitterzelle.

Für jeden Raumpunkt wird seine Position innerhalb der Gitterzelle berechnet und basierend auf dem Rauschwert des Scheitelpunkts interpoliert. Für die Interpolation können verschiedene Methoden verwendet werden, z. B. lineare Interpolation, kubische Interpolation usw.

Die Interpolationswerte verschiedener Gitterzellen werden gewichtet, addiert und mit einem Skalierungsfaktor multipliziert, um den endgültigen FBM-Rauschwert zu erhalten.

Das Merkmal von FBM-Rauschen besteht darin, dass die Details und Rauheit der Textur durch Anpassen der Frequenz und Amplitude verschiedener Schichten gesteuert werden können. Durch Erhöhen der Anzahl der Ebenen und Skalierungsfaktoren können Sie Texturen komplexer und natürlicher erscheinen lassen. FBM-Rauschen kann viele komplexe Phänomene in der Natur simulieren, wodurch die erzeugten Texturen realistischer und detaillierter aussehen.

loat fbm(Vector2 coord)
    {
    
    
        int OCTAVES = 4;

        float normalize_factor = 0.0f;
        float value = 0.0f;
        float scale = 0.5f;

        for (int i = 0; i < OCTAVES; i++)
        {
    
    
            value += Mathf.PerlinNoise(coord.x, coord.y) * scale;
            normalize_factor += scale;
            coord *= 2.0f;
            scale *= 0.5f;
        }
        return value / normalize_factor;
    }

FBM-Rauschen wird durch mehrfaches Überlagern von Perlin-Rauschenschichten mit unterschiedlichen Frequenzen erzeugt, sodass komplexere und vielfältigere Texturen mit reicheren Detaillierungsgraden erzeugt werden können. Einige Mathematikbibliotheken werden von
Perlin oft verwendet
Fügen Sie hier eine Bildbeschreibung ein

  Vector2 mod(Vector2 coord, float a)
    {
    
    
        return new Vector2(coord.x % a, coord.y % a);
    }
    float fract(float x)
    {
    
    
        return x - Mathf.Floor(x);
    }
    Vector2 fract(Vector2 x)
    {
    
    
        return new Vector2(x.x - Mathf.Floor(x.x), x.y - Mathf.Floor(x.y));
    }
    Vector2 floor(Vector2 x)
    {
    
    
        return new Vector2(Mathf.Floor(x.x), Mathf.Floor(x.y));
    }
    float rand(Vector2 coord)
    {
    
    
        // prevents randomness decreasing from coordinates too large
        coord = mod(coord, 10000.0f);
        // returns "random" float between 0 and 1
        return fract(Mathf.Sin(Vector2.Dot(coord, new Vector2(12.9898f, 78.233f))) * 43758.5453f);
    }
   //线性差值 1接近Y 0接近X
    float mix(float x, float y, float level)
    {
    
    
        return x * (1 - level) + y * level;
    }
    Vector2 rand2(Vector2 coord)
    {
    
    
        // prevents randomness decreasing from coordinates too large
        coord = mod(coord, 10000.0f);
        // returns "random" vec2 with x and y between 0 and 1
        return fract((new Vector2(Mathf.Sin(Vector2.Dot(coord, new Vector2(127.1f, 311.7f))), Mathf.Sin(Vector2.Dot(coord, new Vector2(269.5f, 183.3f))))) * 43758.5453f);
    }

Nehmen Sie die Modulo-Operation, nehmen Sie den Dezimalteil, nehmen Sie den ganzzahligen Teil, Pseudozufallscode,
um selbst eine Zufallsfunktion zu implementieren, und diese Zufallsfunktion ist „steuerbar“, und dieselbe Eingabe sollte dieselbe Ausgabe erhalten.

 void SaveTexture(Texture2D texture)
    {
    
    
        byte[] bytes = texture.EncodeToPNG();//读取图像为PNG
        var dirPath = Application.dataPath + "/" + AssetsName + "/";//当前文件夹路径
        Debug.Log("生成路径:" + dirPath);//生成路径位置
        if (!Directory.Exists(dirPath))
        {
    
    
            Directory.CreateDirectory(dirPath);//没有路径则生成
        }
        for (int i = 0; i < 1000; i++)
        {
    
    
            if (!File.Exists(dirPath + "Image" + "(" + i + ")" + ".png"))
            {
    
    
                File.WriteAllBytes(dirPath + "Image" + "(" + i + ")" + ".png", bytes);//写入文件里面
                break;
            }
        }
    }


    Texture2D GenerateTexture()
    {
    
    
        Texture2D texture = new Texture2D(width, height);//新建贴图

        for (int x = 0; x < width; x++)
        {
    
    
            for (int y = 0; y < height; y++)
            {
    
    
                Color color = CalculateColor(x, y);//计算颜色,遍历像素
                texture.SetPixel(x, y, color);//设置像素颜色
            }
        }
        texture.Apply();//应用贴图修改

        return texture;
    }

Speichern von Bilddateien

einige Referenzmaterialien

Unity realisiert die Erstellung von Rauschkarten (Perlin Noise).
Verwenden Sie Unity, um verschiedene Arten von Rauschkarten zu generieren und die grundlegende Generierungsmethode der
fraktalen Brownschen Bewegungsrauschfunktion von FBM
zu teilen.
Ich werde die .cs-Datei später hochladen.
Klicken Sie auf diesen Download

Supongo que te gusta

Origin blog.csdn.net/qq_45498613/article/details/131905507
Recomendado
Clasificación