Work in progress

The content of this page was not yet updated for Godot 4.2 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

Steuern von Tausenden von Fischen mittels Partikeln

Das Problem mit MeshInstance3D ist, dass es teuer ist, ihr Transform-Array zu aktualisieren. Es ist großartig, um viele statische Objekte in der Szene zu platzieren. Aber es ist immer noch schwierig, die Objekte in der Szene zu bewegen.

Um jede Instanz auf interessante Weise zu bewegen, werden wir einen GPUParticles3D-Node verwenden. Partikel nutzen die Vorteile der GPU-Beschleunigung, indem sie die Informationen pro Instanz in einem Shader berechnen und einstellen.

Erstellen Sie zunächst einen Particles-Node. Dann setzen Sie unter "Draw Passes" den "Draw Pass 1" des Partikels auf Ihr Mesh. Dann erstellen Sie unter "Process Material" ein neues ShaderMaterial.

Setzen Sie den shader_type auf particles.

shader_type particles

Anschließend fügen Sie die folgenden beiden Funktionen hinzu:

float rand_from_seed(in uint seed) {
  int k;
  int s = int(seed);
  if (s == 0)
    s = 305420679;
  k = s / 127773;
  s = 16807 * (s - k * 127773) - 2836 * k;
  if (s < 0)
    s += 2147483647;
  seed = uint(s);
  return float(seed % uint(65536)) / 65535.0;
}

uint hash(uint x) {
  x = ((x >> uint(16)) ^ x) * uint(73244475);
  x = ((x >> uint(16)) ^ x) * uint(73244475);
  x = (x >> uint(16)) ^ x;
  return x;
}

Diese Funktionen kommen von dem Default-ParticleProcessMaterial. Sie werden verwendet, um eine Zufallszahl aus dem RANDOM_SEED jedes Partikels zu erzeugen.

Einzigartig an Partikel-Shadern ist, dass einige Built-in-Variablen über Frames hinweg gespeichert werden. Auf TRANSFORM, COLOR und CUSTOM kann im Shader des Meshes zugegriffen werden und auch im Partikel-Shader, wenn er das nächste Mal ausgeführt wird.

Als nächstes richten Sie Ihre start() Funktion ein. Partikel-Shader enthalten eine start() Funktion und eine process() Funktion.

Der Code in der start()-Funktion läuft nur, wenn das Partikelsystem startet. Der Code in der process()-Funktion wird immer ausgeführt.

Wir müssen 4 Zufallszahlen erzeugen: 3, um eine zufällige Position zu erzeugen, und eine für den zufälligen Offset des Schwimmzyklus.

Erzeugen Sie zunächst 4 Seeds innerhalb der start()-Funktion unter Verwendung der oben angegebenen hash()-Funktion:

uint alt_seed1 = hash(NUMBER + uint(1) + RANDOM_SEED);
uint alt_seed2 = hash(NUMBER + uint(27) + RANDOM_SEED);
uint alt_seed3 = hash(NUMBER + uint(43) + RANDOM_SEED);
uint alt_seed4 = hash(NUMBER + uint(111) + RANDOM_SEED);

Dann verwenden Sie diese Seeds, um Zufallszahlen unter Verwendung von rand_from_seed zu erzeugen:

CUSTOM.x = rand_from_seed(alt_seed1);
vec3 position = vec3(rand_from_seed(alt_seed2) * 2.0 - 1.0,
                     rand_from_seed(alt_seed3) * 2.0 - 1.0,
                     rand_from_seed(alt_seed4) * 2.0 - 1.0);

Abschließend weisen Sie Position dem Wert TRANSFORM[3].xyz zu, die den Teil der Transformation darstellt, der die Positionsinformationen enthält.

TRANSFORM[3].xyz = position * 20.0;

Denken Sie daran, dass der gesamte bisherige Code innerhalb der Funktion start() steht.

Der Vertex-Shader für Ihr Mesh kann genau so bleiben, wie er im vorherigen Tutorial war.

Jetzt können Sie jeden Fisch einzeln in jedem Frame bewegen, entweder indem Sie die TRANSFORM direkt hinzufügen oder indem Sie in die VELOCITY schreiben.

Lassen Sie uns die Fische transformieren, indem wir ihre VELOCITY in der start() Funktion setzen.

VELOCITY.z = 10.0;

Dies ist der einfachste Weg, um die VELOCITY einzustellen, da jeder Partikel (oder Fisch) die gleiche Geschwindigkeit hat.

Indem Sie einfach VELOCITY einstellen, können Sie den Fisch schwimmen lassen, wie Sie wollen. Probieren Sie zum Beispiel den folgenden Code aus.

VELOCITY.z = cos(TIME + CUSTOM.x * 6.28) * 4.0 + 6.0;

Dadurch erhält jeder Fisch eine einzigartige Geschwindigkeit zwischen 2 und 10.

Sie können auch jeden Fisch seine Geschwindigkeit über die Zeit ändern lassen, wenn Sie die Geschwindigkeit in der Funktion process() festlegen.

Wenn Sie CUSTOM.y im letzten Tutorial benutzt haben, können Sie auch die Geschwindigkeit der Schwimmanimation basierend auf der VELOCITY einstellen. Verwenden Sie einfach CUSTOM.y.

CUSTOM.y = VELOCITY.z * 0.1;

Dieser Code führt zu folgendem Ergebnis:

../../../_images/scene.gif

Mit einem ParticleProcessMaterial kann man das Verhalten der Fische so einfach oder komplex gestalten, wie man möchte. In diesem Tutorial stellen wir nur die Geschwindigkeit ein, aber in Ihren eigenen Shadern können Sie auch COLOR, Rotation, Skalierung (durch TRANSFORM) einstellen. Bitte lesen Sie die Partikel-Shader-Referenz für weitere Informationen über Partikel Shader.