Inselgelände mit Simplex Noise (C # / XNA) erzeugen

7

Ich habe eine kleine Frage: Gibt es einen Code oder ein Beispiel, das zeigt, wie das Simplex-Rauschen funktioniert? Ich kann nichts darüber finden ... Wie soll ich es implementieren, ohne zu wissen, wie der Algorithmus funktioniert? ...

Die andere Frage ist: Ist das Simplex-Rauschen ein guter Algorithmus für die Inselgenerierung? Ich brauche riesige Inseln (wirklich riesig) mit verschiedenen Schichten (Sand, Gras, Stein) und deutlich sichtbaren Höhenunterschieden, die weiche Kanten haben, damit Sie ins Wasser gehen können, ohne über unebene Oberflächen zu springen.

SharpShade
quelle
Schauen Sie sich gamedev.stackexchange.com/questions/4628/ an. Suchen Sie auch nach speziellem Simplex-Rauschen? Ich habe ein Geräuschbeispiel, das ich selbst geschrieben habe, aber es ist nicht simplex (oder wirklich perlin ... es ist das sogenannte "Wert" -Geräusch, das genau genug aussieht)
The Communist Duck
hmm, es gibt keine Informationen mehr über Simplex-Rauschen ... oder trotzdem? Das Beispiel wäre hilfreich :) Vielleicht kannst du es mir geben? danke :)
SharpShade
Ich möchte nicht, dass dies eine Antwort ist, da es nicht meine Arbeit ist, aber Sie können den Forschungsartikel über Simplex Noise erhalten, den Ken geschrieben hat unter: cs.umbc.edu/~olano/s2002c36/ch02.pdf (Dieser Link war von der unten im Wikipedia-Artikel, der mit dem Artikel verlinkt ist, den Sie unten gepostet haben.) PS: Er enthält Code für C und Java am Ende des Artikels.
James

Antworten:

1

Mein Geräuschgenerator in C # basiert darauf :

static class NoiseGenerator
{
    public static int Seed { get; private set; }

    public static int Octaves { get; set; }

    public static double Amplitude { get; set; }

    public static double Persistence { get; set; }

    public static double Frequency { get; set; }

    static NoiseGenerator()
    {
        Random r = new Random();
        //LOOOL
        NoiseGenerator.Seed = r.Next(Int32.MaxValue);
        NoiseGenerator.Octaves = 8;
        NoiseGenerator.Amplitude = 1;
        NoiseGenerator.Frequency = 0.015;
        NoiseGenerator.Persistence = 0.65;
    }

    public static double Noise(int x, int y)
    {
        //returns -1 to 1
        double total = 0.0;
        double freq = NoiseGenerator.Frequency, amp = NoiseGenerator.Amplitude;
        for (int i = 0; i < NoiseGenerator.Octaves; ++i)
        {
            total = total + NoiseGenerator.Smooth(x * freq, y * freq) * amp;
            freq *= 2;
            amp *= NoiseGenerator.Persistence;
        }
        if (total < -2.4) total = -2.4;
        else if (total > 2.4) total = 2.4;

        return (total/ 2.4);
    }

    public static double NoiseGeneration(int x, int y)
    {
        int n = x + y * 57;
        n = (n << 13) ^ n;

        return (1.0 - ((n * (n * n * 15731 + 789221) + NoiseGenerator.Seed) & 0x7fffffff) / 1073741824.0);
    }

    private static double Interpolate(double x, double y, double a)
    {
        double value = (1 - Math.Cos(a * Math.PI)) * 0.5;
        return x * (1 - value) + y * value;
    }

    private static double Smooth(double x, double y)
    {
        double n1 = NoiseGeneration((int)x, (int)y);
        double n2 = NoiseGeneration((int)x + 1, (int)y);
        double n3 = NoiseGeneration((int)x, (int)y + 1);
        double n4 = NoiseGeneration((int)x + 1, (int)y + 1);

        double i1 = Interpolate(n1, n2, x - (int)x);
        double i2 = Interpolate(n3, n4, x - (int)x);

        return Interpolate(i1, i2, y - (int)y);
    }
}

Es wird nicht kommentiert, aber die Hauptteile:

Seed ist ein Wert, der verwendet wird, um ihn zufällig zu machen. Sie generieren also nicht jedes Mal dasselbe. Hier habe ich es in den NoiseGenerator gestellt.

Amplitude, Frequenz, Persistenz und Oktaven werden im Artikel erläutert - sie beeinflussen im Wesentlichen, wie das resultierende Rauschen aussieht.

NoiseGenerator Funktion ist buchstäblich ein PRNG - geben Sie ihm eine Eingabe, und es generiert eine Zufallszahl mit dieser als Startwert.

Noiseist das, was Sie nennen, um einen Rauschwert zu erhalten. Ich fand die Werte zwischen -2,4 und 2,4 (tatsächlich ungefähr 2.40032483 oder so, damit sie geklemmt werden) und fixierte sie auf Doppel zwischen ihnen -1 and 1.

Ich hatte damit keine Geschwindigkeitsprobleme. Ich habe ein 400x400-Raster mit 1x1-Sprites mit den hier festgelegten Werten gerendert und nur eine geringe Verzögerung erhalten (und das hat das Rauschen in jedem Frame neu berechnet).

Schauen Sie sich diese Frage für die Inselgeneration an - insbesondere ist dieser Link fast genau das, was Sie wollen, wenn auch in AS3.

Die kommunistische Ente
quelle
Tut mir leid, ich habe vergessen zu sagen, dass ich einen Generator brauche, der eine Höhenkarte generiert. Oder wie kann ich damit Terrain erzeugen? Im Moment generiere ich eine Höhenkarte (ich habe verschiedene Algorithmen ausprobiert ...) und berechne dann die Eckpunkte. Die große Sache ist, ich brauche einen Generierungsalgorithmus, der gut aussehende Inseln generiert: - / Ich weiß, ich bin schwierig, aber ich weiß nicht, wie ich das machen soll ...
SharpShade
@Razer Verwenden Sie die Koordinaten Ihrer Höhenkarte - z. B. x, y - als Eingabe für die Rauschfunktion. Es wird jedem Punkt einen Wert zwischen -1 und 1 zugewiesen, daher müssen Sie möglicherweise einige Normalisierungen vornehmen ((Wert + 1) * 127.5f funktioniert, um ihn zwischen 0 und 255 zu erhalten)
The Communist Duck
Es funktioniert, aber nicht sehr schön ... Was ich will, ist so etwas: hazelmckendrick.com/demos/terrain-generation-tropical-island
SharpShade
1
@Razer Warum nicht diese Quelle verwenden?
Die kommunistische Ente
Weil es keine Beschreibung der verwendeten Algorithmen gibt, keinen Code und nichts. Ja ich weiß, Quelle ist enthalten, aber es ist c ++. Ich verstehe C ++ nicht: - /
SharpShade
1

Ok danke an alle für die Hilfe :)

Vor 2 Tagen habe ich "Libnoise" und einen guten C # -Port gefunden. Ich werde dieses nehmen, weil es einen Renderer gibt, der glattere Höhenkarten rendert :)

SharpShade
quelle