Einer der beliebtesten Artikel auf meiner Website befasst sich mit der
Erstellung polygonaler Karten (
Übersetzung in Habré). Das Erstellen solcher Karten erfordert viel Aufwand. Aber ich habe nicht damit begonnen, sondern mit einer
viel einfacheren Aufgabe, die ich hier beschreiben werde. Mit dieser einfachen Technik können Sie solche Karten in weniger als 50 Codezeilen erstellen:
Ich werde nicht erklären, wie man solche Karten zeichnet: Es hängt von der Sprache, der Grafikbibliothek, der Plattform usw. ab. Ich werde nur erklären, wie
das Array mit Kartendaten gefüllt wird.
Der Lärm
Eine Standardmethode zum Generieren von 2D-Karten besteht darin, Rauschen mit einem begrenzten Frequenzband als Baustein zu verwenden, z. B. Perlin-Rauschen oder Simplex-Rauschen. So sieht die Rauschfunktion aus:
Wir weisen jedem Punkt auf der Karte eine Zahl von 0,0 bis 1,0 zu. In diesem Bild ist 0.0 schwarz und 1.0 weiß.
So legen Sie die Farbe jedes Rasterpunkts in der Syntax einer C-ähnlichen Sprache fest:
for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double nx = x/width - 0.5, ny = y/height - 0.5; value[y][x] = noise(nx, ny); } }
Die Schleife funktioniert genauso in Javascript, Python, Haxe, C ++, C #, Java und den meisten anderen gängigen Sprachen. Daher werde ich sie in einer C-ähnlichen Syntax anzeigen, damit Sie sie in die gewünschte Sprache konvertieren können. Im Rest des Tutorials werde ich zeigen, wie sich der Zykluskörper ändert (
value[y][x]=…
), wenn neue Funktionen hinzugefügt werden. Die Demo zeigt ein vollständiges Beispiel.
In einigen Bibliotheken müssen die resultierenden Werte verschoben oder multipliziert werden, um sie im Bereich von 0,0 bis 1,0 zurückzugeben.
Höhe
Lärm an sich ist nur eine Sammlung von Zahlen. Wir müssen ihm einen
Sinn geben . Das erste, woran Sie denken können, ist, den Rauschwert an die Höhe zu binden (dies wird als „Höhenkarte“ bezeichnet). Nehmen wir das oben gezeigte Geräusch und zeichnen es als Höhen:
Der Code blieb mit Ausnahme der inneren Schleife fast gleich. Jetzt sieht es so aus:
elevation[y][x] = noise(nx, ny);
Ja, und das war's. Die Kartendaten blieben gleich, aber jetzt werde ich sie
elevation
(Höhe) nennen, nicht
value
.
Wir haben viele Hügel, aber nichts weiter. Was ist los?
Frequenz
Rauschen kann mit jeder
Frequenz erzeugt werden. Bisher habe ich nur eine Frequenz gewählt. Mal sehen, wie es sich auswirkt.
Versuchen Sie, den Wert mit dem Schieberegler (im Originalartikel) zu
ändern, und sehen Sie, was bei verschiedenen Frequenzen passiert:
Es ändert nur die Skala. Dies scheint zunächst nicht sehr nützlich zu sein, ist es aber nicht. Ich habe noch ein
Tutorial (
Übersetzung in Habré), das die
Theorie erklärt: Konzepte wie Frequenz, Amplitude, Oktaven, rosa und blaues Rauschen und so weiter.
elevation[y][x] = noise(freq * nx, freq * ny);
Manchmal ist es auch nützlich, sich an die
Wellenlänge zu erinnern, die der Kehrwert der Größe ist. Wenn die Frequenz verdoppelt wird, wird die Größe nur halbiert. Verdoppelung der Wellenlänge verdoppelt sich. Die Wellenlänge ist die Entfernung, die in Pixel / Kacheln / Metern oder anderen Einheiten gemessen wird, die Sie für Karten ausgewählt haben. Es hängt mit der Frequenz zusammen:
wavelength = map_size / frequency
.
Oktaven
Um die Höhenkarte interessanter zu gestalten,
fügen wir
Rauschen mit unterschiedlichen Frequenzen hinzu :
elevation[y][x] = 1 * noise(1 * nx, 1 * ny); + 0.5 * noise(2 * nx, 2 * ny); + 0.25 * noise(4 * nx, 2 * ny);
Mischen wir große Niederfrequenzhügel mit kleinen Hochfrequenzhügeln in einer Karte.
Bewegen Sie den Schieberegler (im Originalartikel), um der Mischung kleine Hügel hinzuzufügen:
Jetzt ist es viel mehr wie das fraktale Relief, das wir brauchen! Wir können Hügel und raue Berge bekommen, aber wir haben immer noch keine flachen Ebenen. Dazu benötigen Sie etwas anderes.
Umverteilung
Die Rauschfunktion gibt Werte zwischen 0 und 1 an (oder von -1 bis +1, abhängig von der Bibliothek). Um flache Ebenen zu schaffen, können wir
die Höhe auf eine Kraft erhöhen .
Bewegen Sie den Schieberegler (im Originalartikel), um unterschiedliche Grade zu erhalten.
e = 1 * noise(1 * nx, 1 * ny); + 0.5 * noise(2 * nx, 2 * ny); + 0.25 * noise(4 * nx, 4 * ny); elevation[y][x] = Math.pow(e, exponent);
Hohe Werte
senken die durchschnittliche Höhe in die Ebene , und niedrige Werte erhöhen die durchschnittliche Höhe in Richtung Berggipfel. Wir müssen sie weglassen. Ich benutze Potenzfunktionen, weil sie einfacher sind, aber Sie können jede Kurve verwenden. Ich habe eine kompliziertere
Demo .
Nachdem wir nun eine realistische Höhenkarte haben, fügen wir Biomes hinzu!
Biomes
Lärm gibt Zahlen, aber wir brauchen eine Karte mit Wäldern, Wüsten und Ozeanen. Das erste, was Sie tun können, ist, kleine Höhen in Wasser zu verwandeln:
function biome(e) { if (e < waterlevel) return WATER; else return LAND; }
Wow, das wird schon wie eine prozedural erzeugte Welt! Wir haben Wasser, Gras und Schnee. Aber was ist, wenn wir mehr brauchen? Machen wir eine Sequenz aus Wasser, Sand, Gras, Wald, Savanne, Wüste und Schnee:
Erleichterung aufgrund der Höhe function biome(e) { if (e < 0.1) return WATER; else if (e < 0.2) return BEACH; else if (e < 0.3) return FOREST; else if (e < 0.5) return JUNGLE; else if (e < 0.7) return SAVANNAH; else if (e < 0.9) return DESERT; else return SNOW; }
Wow, das sieht toll aus! Für Ihr Spiel können Sie die Werte und Biomes ändern. Crysis wird viel mehr Dschungel haben; Skyrim hat viel mehr Eis und Schnee. Unabhängig davon, wie Sie die Zahlen ändern, ist dieser Ansatz recht begrenzt. Reliefarten entsprechen Höhen, bilden also Streifen. Um sie interessanter zu machen, müssen wir Biome basierend auf etwas anderem auswählen. Lassen Sie uns eine
zweite Geräuschkarte für die Luftfeuchtigkeit erstellen.
Oben ist das Höhengeräusch; Boden - FeuchtigkeitsgeräuschVerwenden wir nun Höhe und Luftfeuchtigkeit
zusammen . Im ersten Bild unten ist die y-Achse die Höhe (aus dem obigen Bild) und die x-Achse die Luftfeuchtigkeit (das zweite Bild ist höher). Dies gibt uns eine überzeugende Karte:
Entlastung basierend auf zwei GeräuschwertenKleine Höhen sind Ozeane und Küsten. Große Höhen sind felsig und schneebedeckt. Dazwischen erhalten wir eine breite Palette von Biomen. Der Code sieht folgendermaßen aus:
function biome(e, m) { if (e < 0.1) return OCEAN; if (e < 0.12) return BEACH; if (e > 0.8) { if (m < 0.1) return SCORCHED; if (m < 0.2) return BARE; if (m < 0.5) return TUNDRA; return SNOW; } if (e > 0.6) { if (m < 0.33) return TEMPERATE_DESERT; if (m < 0.66) return SHRUBLAND; return TAIGA; } if (e > 0.3) { if (m < 0.16) return TEMPERATE_DESERT; if (m < 0.50) return GRASSLAND; if (m < 0.83) return TEMPERATE_DECIDUOUS_FOREST; return TEMPERATE_RAIN_FOREST; } if (m < 0.16) return SUBTROPICAL_DESERT; if (m < 0.33) return GRASSLAND; if (m < 0.66) return TROPICAL_SEASONAL_FOREST; return TROPICAL_RAIN_FOREST; }
Bei Bedarf können Sie alle diese Werte entsprechend den Anforderungen Ihres Spiels ändern.
Wenn wir keine Biome benötigen, können glatte Farbverläufe (siehe
diesen Artikel ) Farben erzeugen:
Sowohl für Biome als auch für Gradienten bietet ein einzelner Rauschwert keine ausreichende Variabilität, aber zwei sind ausreichend.
Klima
Im vorherigen Abschnitt habe ich die
Höhe als
Temperaturersatz verwendet . Je höher die Höhe, desto niedriger die Temperatur. Der geografische Breitengrad beeinflusst jedoch auch die Temperaturen. Verwenden wir sowohl Höhe als auch Breite, um die Temperatur zu steuern:
In der Nähe der Pole (große Breiten) ist das Klima kälter, und auf den Gipfeln der Berge (große Höhen) ist das Klima auch kälter. Bisher habe ich es nicht sehr schwer herausgearbeitet: Für die richtige Herangehensweise an diese Parameter benötigen Sie viele subtile Einstellungen.
Es gibt auch
saisonalen Klimawandel. Im Sommer und Winter werden die nördlichen und südlichen Hemisphären wärmer und kälter, aber am Äquator ändert sich nicht viel. Hier kann auch viel getan werden, zum Beispiel ist es möglich, die vorherrschenden Winde und Meeresströmungen, die Auswirkung von Biomes auf das Klima und die durchschnittliche Auswirkung von Ozeanen auf die Temperatur zu simulieren.
Die Inseln
In einigen Projekten brauchte ich die Ränder der Karte als Wasser. Dies macht die Welt zu einer oder mehreren Inseln. Es gibt viele Möglichkeiten, dies zu tun, aber ich habe in meinem Polygonkartengenerator eine ziemlich einfache Lösung verwendet: Ich habe die Höhe als
e = e + a - b*d^c
geändert, wobei
d
der Abstand vom Zentrum ist (auf einer Skala von 0-1). Eine andere Möglichkeit besteht darin,
e = (e + a) * (1 - b*d^c)
zu ändern. Die Konstante
a
erhöht alles nach oben,
b
senkt die Kanten nach unten und
c
steuert die Abnahmerate.
Ich bin damit nicht ganz zufrieden und es bleibt noch viel zu erforschen. Sollte es Manhattan oder euklidische Entfernung sein? Sollte es vom Abstand zum Zentrum oder vom Abstand zum Rand abhängen? Sollte der Abstand quadratisch oder linear sein oder einen anderen Grad haben? Sollte es Addition / Subtraktion oder Multiplikation / Division oder etwas anderes sein?
Versuchen Sie im Originalartikel Hinzufügen, a = 0,1, b = 0,3, c = 2,0 oder Multiplizieren, a = 0,05, b = 1,00, c = 1,5. Welche Optionen zu Ihnen passen, hängt von Ihrem Projekt ab.
Warum überhaupt an Standard-Mathematikfunktionen festhalten? Wie ich in meinem
Artikel über Schäden in RPG (
Übersetzung auf Habré) sagte, verwendet jeder (einschließlich ich) mathematische Funktionen wie Polynome, Exponentialverteilungen usw., aber auf dem Computer können wir nicht auf sie beschränkt sein. Wir können
jede Formationsfunktion verwenden und sie hier verwenden, indem wir die Nachschlagetabelle
e = e + height_adjust[d]
. Bisher habe ich dieses Thema nicht untersucht.
Stacheliges Geräusch
Anstatt die Höhe auf eine Potenz zu erhöhen, können wir den absoluten Wert verwenden, um scharfe Spitzen zu erzeugen:
function ridgenoise(nx, ny) { return 2 * (0.5 - abs(0.5 - noise(nx, ny))); }
Um Oktaven hinzuzufügen, können wir die Amplituden hoher Frequenzen so variieren, dass nur Berge das zusätzliche Rauschen empfangen:
e0 = 1 * ridgenoise(1 * nx, 1 * ny); e1 = 0.5 * ridgenoise(2 * nx, 2 * ny) * e0; e2 = 0.25 * ridgenoise(4 * nx, 4 * ny) * (e0+e1); e = e0 + e1 + e2; elevation[y][x] = Math.pow(e, exponent);
Ich habe nicht viel Erfahrung mit dieser Technik, daher muss ich experimentieren, um zu lernen, wie man sie gut benutzt. Es kann auch interessant sein, stacheliges Niederfrequenzrauschen mit nicht stacheligem Hochfrequenzrauschen zu mischen.
Terrassen
Wenn wir die Höhe auf die nächsten n Ebenen runden, erhalten wir Terrassen:
Dies ist das Ergebnis der Anwendung der Höhenumverteilungsfunktion in der Form
e = f(e)
. Oben haben wir
e = Math.pow(e, exponent)
, um die Berggipfel zu schärfen. hier verwenden wir
e = Math.round(e * n) / n
, um Terrassen zu erstellen. Wenn Sie eine Nicht-Stufen-Funktion verwenden, können die Terrassen abgerundet sein oder nur in bestimmten Höhen auftreten.
Baumplatzierung
Normalerweise haben wir fraktales Rauschen für Höhe und Luftfeuchtigkeit verwendet, aber es kann auch verwendet werden, um ungleichmäßig verteilte Objekte wie Bäume und Steine zu platzieren. Für die Höhe verwenden wir hohe Amplituden mit niedrigen Frequenzen („rotes Rauschen“). Um Objekte zu platzieren, müssen Sie hohe Amplituden mit hohen Frequenzen verwenden ("blaues Rauschen"). Links ist ein blaues Rauschmuster; Auf der rechten Seite befinden sich Stellen, an denen das Rauschen größer ist als benachbarte Werte:
for (int yc = 0; yc < height; yc++) { for (int xc = 0; xc < width; xc++) { double max = 0;
Wenn wir für jedes Biom ein anderes R wählen, können wir eine variable Baumdichte erhalten:
Es ist großartig, dass solches Rauschen zum Platzieren von Bäumen verwendet werden kann, aber andere Algorithmen sind oft effektiver und sorgen für eine gleichmäßigere Verteilung: Poisson-Spots, Van-Kacheln oder grafisches Dithering.
Bis ins Unendliche und darüber hinaus
Die Berechnungen des Bioms an der Position (x, y) sind unabhängig von den Berechnungen aller anderen Positionen. Diese
lokale Berechnung hat zwei praktische Eigenschaften: Sie kann parallel berechnet und für endloses Gelände verwendet werden.
Platzieren Sie den Mauszeiger auf der Minikarte (im Originalartikel) links, um die Karte rechts zu
erstellen . Sie können einen beliebigen Teil der Karte generieren, ohne die gesamte Karte zu generieren (und sogar ohne sie zu speichern).


Implementierung
Die Verwendung von Lärm zur Erzeugung von Gelände ist eine beliebte Lösung. Im Internet finden Sie Tutorials für viele verschiedene Sprachen und Plattformen. Der Code zum Generieren von Karten in verschiedenen Sprachen ist ungefähr gleich. Hier ist die einfachste Schleife in drei verschiedenen Sprachen:
- Javascript:
let gen = new SimplexNoise(); function noise(nx, ny) {
- C ++:
module::Perlin gen; double noise(double nx, double ny) {
- Python:
from opensimplex import OpenSimplex gen = OpenSimplex() def noise(nx, ny):
Alle Rauschbibliotheken sind ziemlich ähnlich. Versuchen Sie
OpenSimplex für Python oder
Libnoise für C ++ oder
Simplex-Noise für Javascript. Für die meisten gängigen Sprachen gibt es viele Rauschbibliotheken. Oder Sie können lernen, wie Perlin-Rauschen funktioniert, oder das Rauschen selbst realisieren.
Ich habe es nicht getan.In verschiedenen Rauschbibliotheken für Ihre Sprache können die Anwendungsdetails geringfügig variieren (einige Rückgabewerte liegen im Bereich von 0,0 bis 1,0, andere im Bereich von -1,0 bis +1,0), aber die Grundidee ist dieselbe. Für ein reales Projekt müssen Sie möglicherweise die
noise
und das
gen
Objekt in eine Klasse
gen
, aber diese Details sind irrelevant, daher habe ich sie global gemacht.
Für ein so einfaches Projekt spielt es keine Rolle, welches Rauschen Sie verwenden: Perlin-Rauschen, Simplex-Rauschen, OpenSimplex-Rauschen, Wertrauschen, Mittelpunktversatz, Diamantalgorithmus oder die inverse Fourier-Transformation. Jeder von ihnen hat seine Vor- und Nachteile, aber für einen ähnlichen Kartengenerator erzeugen alle mehr oder weniger die gleichen Ausgabewerte.
Das Rendern der Karte hängt von der Plattform und dem Spiel ab, daher habe ich sie nicht implementiert. Dieser Code wird nur benötigt, um Höhen und Biomes zu generieren, deren Darstellung vom im Spiel verwendeten Stil abhängt. Sie können es kopieren, portieren und in Ihren Projekten verwenden.
Die Experimente
Ich habe mir überlegt, wie man Oktaven mischt, Grad zu einer Potenz erhöht und Höhen mit Feuchtigkeit kombiniert, um ein Biom zu erzeugen.
Hier können Sie ein interaktives Diagramm studieren, mit dem Sie mit all diesen Parametern experimentieren können. Es zeigt, woraus der Code besteht:
Hier ist ein Beispielcode:
var rng1 = PM_PRNG.create(seed1); var rng2 = PM_PRNG.create(seed2); var gen1 = new SimplexNoise(rng1.nextDouble.bind(rng1)); var gen2 = new SimplexNoise(rng2.nextDouble.bind(rng2)); function noise1(nx, ny) { return gen1.noise2D(nx, ny)/2 + 0.5; } function noise2(nx, ny) { return gen2.noise2D(nx, ny)/2 + 0.5; } for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var nx = x/width - 0.5, ny = y/height - 0.5; var e = (1.00 * noise1( 1 * nx, 1 * ny) + 0.50 * noise1( 2 * nx, 2 * ny) + 0.25 * noise1( 4 * nx, 4 * ny) + 0.13 * noise1( 8 * nx, 8 * ny) + 0.06 * noise1(16 * nx, 16 * ny) + 0.03 * noise1(32 * nx, 32 * ny)); e /= (1.00+0.50+0.25+0.13+0.06+0.03); e = Math.pow(e, 5.00); var m = (1.00 * noise2( 1 * nx, 1 * ny) + 0.75 * noise2( 2 * nx, 2 * ny) + 0.33 * noise2( 4 * nx, 4 * ny) + 0.33 * noise2( 8 * nx, 8 * ny) + 0.33 * noise2(16 * nx, 16 * ny) + 0.50 * noise2(32 * nx, 32 * ny)); m /= (1.00+0.75+0.33+0.33+0.33+0.50); } }
Es gibt eine Schwierigkeit: Für Höhen- und Feuchtigkeitsgeräusche muss ein anderes Saatgut verwendet werden, da es sich sonst als gleich herausstellt und die Karten nicht so interessant aussehen. In Javascript verwende ich
die Prng-Parkmiller-Bibliothek . In C ++ können Sie zwei separate
Objekte linear_congruential_engine verwenden . In Python können Sie zwei separate Instanzen einer
random.Random-Klasse erstellen .
Gedanken
Ich mag diesen Ansatz zur Kartengenerierung wegen seiner
Einfachheit . Es ist schnell und erfordert sehr wenig Code, um anständige Ergebnisse zu erzielen.
Ich mag seine Grenzen in diesem Ansatz nicht. Lokale Berechnungen bedeuten, dass jeder Punkt unabhängig von allen anderen ist. Verschiedene Bereiche der Karte sind
nicht miteinander verbunden . Jeder Ort auf der Karte „scheint“ gleich zu sein. Es gibt keine globalen Einschränkungen, z. B. "Es sollten 3 bis 5 Seen auf der Karte sein" oder globale Merkmale wie einen Fluss, der von der Spitze des höchsten Gipfels in den Ozean fließt. Ich mag auch nicht die Tatsache, dass Sie die Parameter für eine lange Zeit konfigurieren müssen, um ein gutes Bild zu erhalten.
Warum empfehle ich es? Ich denke, dies ist ein guter Ausgangspunkt, insbesondere für Indie-Spiele und Game-Jams. Zwei meiner Freunde haben
in nur 30 Tagen die erste Version von
Realm of the Mad God für einen
Spielewettbewerb geschrieben . Sie baten mich, beim Erstellen von Karten zu helfen. Ich habe diese Technik verwendet (plus ein paar weitere Funktionen, die sich als nicht sehr nützlich erwiesen haben) und eine Karte für sie erstellt. Einige Monate später, nachdem wir Feedback von den Spielern erhalten und das Design des Spiels sorgfältig studiert hatten, erstellten wir einen fortschrittlicheren Kartengenerator auf der Basis der
hier beschriebenen Voronoi-Polygone (
Übersetzung in Habré). Dieser Kartengenerator verwendet nicht die in diesem Artikel beschriebenen Techniken. Es verwendet Rauschen, um Karten auf ganz andere Weise zu erstellen.
Weitere Informationen
Es gibt
viele coole Dinge, die Sie mit Rauschfunktionen tun können. Wenn Sie im Internet suchen, finden Sie Optionen wie Turbulenzen, Wogen, geriffelte Multifraktale, Amplitudendämpfung, Terrassen-, Voronoi-Rauschen, analytische Derivate, Domain Warping und andere. Sie können
diese Seite als Inspirationsquelle verwenden. Ich betrachte sie hier nicht, mein Artikel konzentriert sich auf Einfachheit.
Dieses Projekt wurde von meinen vorherigen Kartengenerierungsprojekten beeinflusst:
- Ich habe Perlins Gesamtrauschen für meinen ersten Realm of the Mad God-Kartengenerator verwendet . Wir haben es in den ersten sechs Monaten des Alpha-Tests verwendet und es dann durch einen Kartengenerator für Voronoi-Polygone ersetzt , der speziell für die Gameplay-Anforderungen entwickelt wurde, die wir während des Alpha-Tests ermittelt haben. Biomes und ihre Farben für den Artikel stammen aus diesen Projekten.
- Beim Studium der Verarbeitung von Audiosignalen habe ich ein Rausch-Tutorial geschrieben , in dem Konzepte wie Frequenz, Amplitude, Oktaven und die „Farbe“ des Rauschens erläutert werden. Die gleichen Konzepte, die für Sound gelten, gelten auch für die rauschbasierte Kartenerzeugung. Zu dieser Zeit habe ich eine rohe Demo-Relief-Generation erstellt , aber ich habe sie nicht fertiggestellt.
- Manchmal experimentiere ich, um Grenzen zu finden. Ich wollte wissen, wie viel Code minimal benötigt wird, um überzeugende Karten zu erstellen. In diesem Miniprojekt habe ich null Codezeilen erreicht - alles wird mit Bildfiltern (Turbulenzen, Schwellenwerte, Farbverläufe) gemacht. Das hat mich glücklich und traurig gemacht. Inwieweit kann die Kartenerzeugung durch Bildfilter durchgeführt werden? In groß genug. Alles, was oben über das "Schema glatter Farbverläufe" beschrieben wurde, stammt aus diesem Experiment. Die Rauschschicht ist ein Turbulenzbildfilter; Oktaven sind einander überlagerte Bilder; Das Grad-Werkzeug wird in Photoshop als „Kurvenkorrektur“ bezeichnet.
Was mich ein bisschen stört, ist, dass der größte Teil des Codes, den Spieleentwickler für die rauschbasierte Geländegenerierung (einschließlich der Verschiebung des Mittelpunkts) schreiben, der gleiche ist wie bei Ton- und Bildfiltern. Auf der anderen Seite werden in nur wenigen Codezeilen recht anständige Ergebnisse erzielt, weshalb ich diesen Artikel geschrieben habe. Dies ist ein
schneller und einfacher Bezugspunkt . Normalerweise benutze ich solche Karten nicht lange, sondern ersetze sie durch einen komplexeren Kartengenerator, sobald ich herausfinde, welche Kartentypen besser für das Design des Spiels geeignet sind. Für mich ist dies ein Standardmuster: Beginnen Sie mit etwas extrem Einfachem und ersetzen Sie es erst, nachdem ich das System, mit dem ich arbeite, besser verstanden habe.
Es gibt noch
viel mehr Dinge, die mit Lärm gemacht werden können, in dem Artikel habe ich nur einige erwähnt. Probieren Sie
Noise Studio aus , um verschiedene Funktionen interaktiv zu testen.