Inzwischen streamt deine Welt, hat Foliage und blendet ins Terrain. Und du hast vermutlich ein paar hundert Felsen platziert, indem du dasselbe Mesh immer wieder reingezogen hast.

Mach stat RHI auf und schau auf DrawPrimitive calls. Diese Zahl ist dein Problem.

Warum 800 Felsen 800 Draw Calls kosten

Jeder Static Mesh Actor ist ein Actor: ein Transform, eine Component, ein Scene Proxy, und eine eigene Reise durch die Render-Pipeline. Das Mesh ist identisch, das Material ist identisch, und die GPU erfährt 800 mal separat davon.

Instancing faltet das zusammen. Eine Component hält ein Mesh und N Transforms. Die GPU erfährt es einmal: zeichne das, hier sind die 800 Stellen. Gleiche Pixel, ein Bruchteil der CPU-Kosten.

Die drei Wege, die du schon hast

Foliage Mode — schon instanziert. Alles was du malst sind Instanzen. Deshalb funktionieren gemalte Wälder und reingezogene nicht.

ISM (InstancedStaticMeshComponent) — du packst sie in ein Blueprint und rufst Add Instance mit einem Transform. Das ist die manuelle Variante, und die wirst du nutzen.

HISM (HierarchicalInstancedStaticMeshComponent) — ISM mit einer Hierarchie für Culling und LOD.

ISM oder HISM? Eine Frage

Die alte Faustregel war "HISM macht Per-Instance-LOD, ISM nicht, nimm HISM". Das ist veraltet. ISM unterstützt inzwischen Per-Instance-LOD, und die aktuelle Leitlinie ist ungefähr:

  • HISM — besser bei tausenden Instanzen, die sich nicht bewegen. Die statische Hierarchie macht Culling billig.
  • ISM — keine statische Hierarchie, cullt und LODt also jede Instanz auf der GPU. Flexibler für bewegte Instanzen, aber teurer auf schwachen Plattformen.
  • HISMs LOD arbeitet pro Gruppe, nicht pro Instanz, weil es in Clustern denkt. Wenn du LOD-Verhalten wie bei einem normalen Static Mesh brauchst, gibt HISM dir das nicht. HISM ist da am besten, wo Per-Instance-LOD egal ist — Meshes mit wenig Dreiecken.

Und die moderne Abkürzung: wenn dein Projekt nur Nanite nutzt, ist ISM immer die Wahl — Nanite macht sein eigenes Culling und LOD, die HISM-Hierarchie hat nichts beizutragen. HISM da, wo du Nanite plus Fallback-Meshes hast.

Ehrlich? Beides probieren und profilen. Doku und Foren sind sich einig, dass die Antwort vom Projekt abhängt.

Wann Instancing das falsche Werkzeug ist

Instanzen sind keine Actors. Das ist der ganze Tausch:

  • Keine Per-Instance-Blueprint-Logik. Eine Instanz kann kein Script, keine Component, kein Overlap-Event haben.
  • Keine Per-Instance-Material-Parameter. Immer dasselbe Material. Per-Instance Custom Data gibt es und hilft, aber das ist ein Float-Array im Vertex Shader, keine Material-Instance.
  • Interaktion heißt Buchhaltung. Add Instance gibt einen Index zurück. Remove Instance verschiebt jeden Index darüber. Speicher Instanz-Indices in einer Variable und du hast stille, undebugbare Korruption, sobald einer entfernt wird.

Also: Zaunpfähle, Felsen, Gras, Schutt, Kisten die nur Deko sind — instanzieren. Alles womit der Spieler einzeln interagiert bleibt Actor, sonst verbringst du eine Woche damit, Actor-Semantik auf einem Index-Array nachzubauen.

Damit es wirklich hilft

Instancing gewinnt bei Draw Calls. Es gewinnt nicht automatisch überall:

  • Culling läuft pro Component. 5000 Instanzen in einem ISM über deine ganze Map heißt: alles oder nichts cullen. Räumlich aufteilen — eine Component pro Region.
  • Distance Culling auf ISM/HISM hat eine lange Geschichte von Überraschungen. Testen, nicht annehmen dass die Einstellung tut was ihr Name sagt.
  • Überlappende Instanzen tun weh, wenn du Hardware-Ray-Tracing-Lumen fährst. Viele sich schneidende Instanzen verschlechtern die Acceleration Structure.
  • stat RHI vorher und nachher. Wenn die DrawPrimitive calls nicht gefallen sind, hast du nichts repariert und solltest jetzt rausfinden warum.

Häufige Fehler

  • Einen Instanz-Index über ein Remove Instance hinweg speichern. Indices verschieben sich. Nimm eine stabile ID, gemappt auf einen Index, und bau die Map beim Entfernen neu.
  • Ein riesiges ISM fürs ganze Level. Culling wird alles-oder-nichts. Räumlich gruppieren.
  • Dinge instanzieren, mit denen der Spieler interagiert. Du baust Actors nach, nur schlechter.
  • Per-Instance-Materialien erwarten. Schau dir stattdessen Per-Instance Custom Data an — und kenn die Grenzen.
  • HISM nehmen weil ein 2020er-Tutorial das sagte. Gegen die aktuelle Doku prüfen — ISM hat jetzt Per-Instance-LOD, und Nanite ändert die Antwort komplett.
  • Nicht profilen. "Instancing ist schneller" ist eine Aussage über Draw Calls, nicht über deine Szene.

30-Sekunden-Recap

  • Jeder Static Mesh Actor ist ein eigener Draw Call. Instanzen teilen sich einen.
  • Foliage Mode instanziert schon. ISM ist die manuelle Version.
  • HISM: tausende unbewegte Instanzen mit wenig Dreiecken. ISM: alles andere — und immer, wenn du nur Nanite nutzt.
  • Instanzen haben keine Blueprint-Logik, keine Per-Instance-Materialien, und instabile Indices nach dem Entfernen.
  • Instanzen in räumliche Components aufteilen, sonst ist Culling alles-oder-nichts.
  • stat RHI sagt dir, ob es geklappt hat.

Nächsten Sonntag: Garbage Collection — warum dein Spiel im 60-Sekunden-Takt stockt, und die Einstellung, die das auf mehrere Frames verteilt.

— Marco