Unity Shader-Varianten Tipps zur Optimierung und Fehlerbehebung

Beim Schreiben von Shadern in Unity haben wir die Möglichkeit, mehrere Funktionen, Durchläufe und Verzweigungslogik in einer einzigen Quelldatei zu integrieren. Zum Zeitpunkt der Erstellung werden die Shader-Quelldateien in Shader-Programme kompiliert, die eine oder mehrere Varianten enthalten. Eine Variante ist eine Version dieses Shaders, die einem einzigen Satz von Bedingungen folgt, was (in den meisten Fällen) zu einem linearen Ausführungspfad ohne statische Verzweigungsbedingungen führt.
Der Grund, warum wir Varianten verwenden, anstatt die Verzweigungspfade alle in einem Shader zu belassen, liegt darin, dass GPUs hervorragend in der Lage sind, Code zu parallelisieren, der vorhersehbar ist und immer demselben Pfad folgt, was zu einem höheren Durchsatz führt. Wenn das kompilierte Shader-Programm Bedingungen enthält, muss die GPU Ressourcen für prädiktive Aufgaben aufwenden, warten, bis die anderen Pfade abgeschlossen sind, und so weiter, was zu Ineffizienzen führt.
Dies führt zwar zu einer deutlich besseren GPU-Leistung im Vergleich zur dynamischen Verzweigung, hat aber auch einige Nachteile. Die Erstellungszeiten werden mit zunehmender Anzahl von Varianten länger, manchmal sogar um mehrere Stunden pro Erstellung. Das Spiel braucht auch länger zum Booten, da es mehr Zeit zum Laden und Aufwärmen der Shader benötigt. Schließlich können Sie einen erheblichen Laufzeitspeicherverbrauch durch Shader feststellen, wenn die Varianten nicht ordnungsgemäß verwaltet werden, manchmal über 1 GB.
Die Anzahl der erzeugten Varianten hängt von einer Vielzahl von Faktoren ab, u.a. von den definierten Schlüsselwörtern und Eigenschaften, den Qualitätseinstellungen, den Grafikstufen, den aktivierten Grafik-APIs, den Nachbearbeitungseffekten, der aktiven Rendering-Pipeline, den Beleuchtungs- und Nebelmodi und davon, ob XR aktiviert ist. Shader, die zu einer großen Anzahl von Varianten führen, werden oft als Uber-Shader bezeichnet. Zur Laufzeit lädt Unity die Variante, die den erforderlichen Einstellungen und Schlüsselwörtern entspricht, wie wir später noch erläutern werden.
Dies ist besonders wichtig, wenn man bedenkt, dass wir oft Shader mit über 100 Schlüsselwörtern sehen, was zu einer unüberschaubaren Anzahl von Varianten führt, die oft als Shader-Varianten-Explosion bezeichnet werden. Es ist nicht ungewöhnlich, Shader mit einem anfänglichen Variantenraum in Millionenhöhe zu sehen, bevor irgendeine Filterung angewendet wird.
Um dies zu vermeiden, versucht Unity, die Anzahl der generierten Varianten anhand einiger weniger Filterdurchläufe zu reduzieren. Wenn zum Beispiel XR nicht aktiviert ist, werden Varianten, die dafür benötigt werden, normalerweise entfernt. Unity berücksichtigt dann, welche Funktionen Sie in Ihren Szenen tatsächlich verwenden, z. B. Beleuchtungsmodi, Nebel usw. Diese sind besonders schwierig zu erkennen, da Entwickler und Künstler scheinbar sichere Änderungen einführen könnten, die in Wirklichkeit zu einer erheblichen Zunahme von Shader-Varianten führen, ohne dass es offensichtlich ist, wie Sie dies erkennen können, es sei denn, Sie haben einige Sicherheitsvorkehrungen als Teil Ihrer Bereitstellungspipeline getroffen.
Das ist zwar hilfreich, aber dieser Prozess ist nicht perfekt, und es gibt eine Menge, was wir tun können, um so viele Varianten wie möglich zu entfernen, ohne die visuelle Qualität Ihres Spiels zu beeinträchtigen.
Hier möchte ich Ihnen ein paar praktische Tipps geben, wie Sie mit Varianten umgehen können, wie Sie verstehen, woher sie kommen, und wie Sie sie effektiv reduzieren können. Ihre Projektentwicklungszeit und Ihr Speicherplatzbedarf werden dadurch erheblich verbessert.
Es werden Shader-Varianten generiert, die unter anderem auf allen möglichen Kombinationen der in Ihrem Shader verwendeten Schlüsselwörter shader_feature und multi_compile basieren. Schlüsselwörter, die als multi_compile markiert sind, sind immer in Ihrem Build enthalten, während diejenigen, die als shader_feature markiert sind, enthalten sind, wenn sie von einem Material in Ihrem Projekt referenziert werden. Aus diesem Grund sollten Sie, wann immer möglich, shader_feature verwenden.
Um zu sehen, welche Schlüsselwörter in einem Shader definiert sind, können Sie ihn auswählen und im Inspektor überprüfen.

Wie Sie sehen können, sind die Schlüsselwörter in überschreibbar und nicht überschreibbar unterteilt. Lokale Schlüsselwörter (die in der eigentlichen Shader-Datei definiert sind) mit einem globalen Geltungsbereich können durch ein globales Shader-Schlüsselwort mit einem passenden Namen überschrieben werden. Wenn sie stattdessen auf lokaler Ebene definiert werden (mit multi_compile_local oder shader_feature_local), können sie nicht überschrieben werden und werden im Abschnitt Nicht überschreibbar darunter angezeigt. Globale Shader-Schlüsselwörter werden von der Unity-Engine bereitgestellt und sind überschreibbar. Da sie an jedem beliebigen Punkt des Erstellungsprozesses hinzugefügt werden können, tauchen möglicherweise nicht alle globalen Schlüsselwörter in dieser Liste auf.
Schlüsselwörter können in sich gegenseitig ausschließenden Gruppen, so genannten Sets, definiert werden, indem Sie sie in der gleichen Direktive definieren. Auf diese Weise vermeiden Sie die Erstellung von Varianten für Kombinationen von Schlüsselwörtern, die niemals gleichzeitig aktiviert werden (z. B. zwei verschiedene Arten von Beleuchtung oder Nebel).
#pragma shader_feature LIGHT_LOW_Q LIGHT_HIGH_Q
Um die Anzahl der Schlüsselwörter pro Plattform zu reduzieren, können Sie z.B. Präprozessormakros verwenden, um sie nur für die jeweilige Plattform zu definieren:
#ifdef SHADER_API_METAL
#pragma shader_feature IOS_FOG_FEATURE
#else
#pragma shader_feature BASE_FOG_FEATURE
#endif
Beachten Sie, dass diese Ausdrücke mit Makros nicht von anderen Schlüsselwörtern oder Funktionen abhängen dürfen, die sich nicht nur auf das Build-Ziel beziehen.
Schlüsselwörter können auch auf einen bestimmten Durchgang beschränkt werden, was die Anzahl der möglichen Kombinationen reduziert. Dazu können Sie eines der folgenden Suffixe an die Direktive anhängen:
- _vertex
- _fragment
- _hull
- _domain
- _geometry
- _raytracing
Zum Beispiel:
#pragma shader_feature_fragment FRAG_FEATURE_1 FRAG_FEATURE_2
Dies kann sich je nach dem von Ihnen verwendeten Renderer unterschiedlich verhalten. Bei OpenGL zum Beispiel werden die Suffixe OpenGL ES und Vulkan ignoriert.
Sie können die Direktive #pragma skip_variants verwenden, um Schlüsselwörter zu definieren, die bei der Erstellung von Varianten für diesen speziellen Shader ausgeschlossen werden sollen. Wenn Sie Ihr Player-Build erstellen, werden alle Shader-Varianten für diesen Shader, die eines dieser Schlüsselwörter enthalten, übersprungen.
Sie können auch optional Schlüsselwörter mit der Direktive #pragma dynamic_branch definieren, die Unity dazu zwingt, sich auf dynamische Verzweigungen zu verlassen und keine Varianten für diese Schlüsselwörter zu erzeugen. Dies reduziert zwar die Anzahl der resultierenden Varianten, kann aber je nach Shader und Spielinhalt zu einer schwächeren GPU-Leistung führen. Es wird daher empfohlen, ein entsprechendes Profil zu erstellen, wenn Sie es verwenden.
Normalerweise werden Shader-Varianten erst kompiliert, wenn Sie das Spiel tatsächlich bauen. Mit dieser Option können Sie die resultierenden Shader-Varianten für eine bestimmte Build-Plattform oder Grafik-API untersuchen. Auf diese Weise können Sie bereits im Vorfeld auf Fehler prüfen. Außerdem können Sie den generierten Code in GPU-Shader-Leistungsanalysetools wie PVRShaderEditor einfügen, um weitere Optimierungen vorzunehmen.

Unten sehen Sie einen Eintrag, der angibt, wie viele Varianten enthalten sind, basierend auf den Materialien, die in der aktuell geöffneten Szene vorhanden sind, ohne dass ein skriptfähiges Stripping angewendet wird. Wenn Sie auf die Schaltfläche Anzeigen klicken, wird eine temporäre Datei mit einigen zusätzlichen Debug-Informationen darüber angezeigt, welche Schlüsselwörter auf den verschiedenen Plattformen verwendet oder entfernt wurden, einschließlich der Anzahl der Vertex-Stufenvarianten.
Mit dem obigen Kontrollkästchen Nur vorverarbeiten können Sie zwischen kompiliertem Shader-Code und vorverarbeitetem Shader-Quellcode hin- und herschalten, um die Fehlersuche zu erleichtern und zu beschleunigen.
Wenn Sie die integrierte Render-Pipeline verwenden und mit einem Oberflächenshader arbeiten, haben Sie die Möglichkeit, den generierten Code zu überprüfen, den Unity verwendet, um Ihren vereinfachten Shader-Quellcode beim Erstellen zu ersetzen. Sie können dann optional Ihren Shader-Quelltext durch den generierten Code ersetzen, wenn Sie die Ausgabe verändern möchten.

Bei der Erstellung des Spiels bestimmt Unity den Variantenraum für jeden Shader auf der Grundlage aller möglichen Permutationen seiner Funktionen, der Engine-Einstellungen und anderer Faktoren. Diese Kombinationen werden dann an die Präprozessoren für mehrere Stripping-Durchgänge weitergegeben. Dies kann mit IPreprocessShaders Callbacks erweitert werden, um eine benutzerdefinierte Logik zu erstellen, mit der weitere Varianten aus dem Build entfernt werden können (siehe unten).
Bei Shadern, die in der Liste Immer enthaltene Shader (unter Projekteinstellungen > Grafik) enthalten sind, werden alle ihre Varianten in den Build aufgenommen. Verwenden Sie diese Funktion daher nur, wenn es unbedingt notwendig ist, da sie leicht dazu führen kann, dass eine große Anzahl von Varianten erzeugt wird.
Schließlich durchläuft die Build-Pipeline einen Prozess namens Deduplizierung, der identische Varianten innerhalb desselben Passes identifiziert und sicherstellt, dass sie auf denselben Bytecode verweisen. Dies führt zwar zu einer geringeren Größe auf der Festplatte, aber identische Varianten wirken sich immer noch negativ auf die Erstellungszeit, die Ladezeit und den Speicherverbrauch zur Laufzeit aus, so dass dies kein Ersatz für das richtige Strippen von Varianten ist.
Nach einem erfolgreichen Build können wir einen Blick in die Datei Editor.log werfen, um einige nützliche Informationen darüber zu sammeln, welche Shader-Varianten im Build enthalten waren. Suchen Sie dazu in der Protokolldatei nach "Shader kompilieren" und dem Namen Ihres Shaders. Hier sehen Sie zum Beispiel, wie es aussieht:
Compiling shader "GameShaders/MyShader" pass "Pass 1" (vp)
Full variant space: 608
After settings filtering: 608
After built-in stripping: 528
After scriptable stripping: 528
Processed in 0.00 seconds
starting compilation...
finished in 0.02 seconds. Local cache hits 528 (0.16s CPU time), remote cache hits 0 (0.00s CPU time), compiled 0 variants (0.00s CPU time), skipped 0 variants
In bestimmten Fällen kann es vorkommen, dass sich die Anzahl der Varianten nach dem Schritt des Filterns der Einstellungen erhöht, z.B. wenn Ihr Projekt XR aktiviert hat.
Wenn Ihr Spiel mehrere Grafik-APIs unterstützt, finden Sie auch Informationen für jeden unterstützten Renderer:
Serialized binary data for shader GameShaders/MyShader in 0.00s
gles3 (total internal programs: 290, unique: 193)
vulkan (total internal programs: 290, unique: 193)
Schließlich sehen Sie diese Komprimierungsprotokolle, die Ihnen einen Hinweis auf die endgültige Größe des Shaders auf der Festplatte für eine bestimmte Grafik-API geben:
Compressed shader 'GameShaders/MyShader' on vulkan from 1.35MB to 0.19MB
Wenn Sie die Universal Render Pipeline (URP) verwenden, können Sie wählen, ob die Protokolle nur von SRP-Shadern oder von allen Shadern erstellt werden sollen oder ob Sie die Protokolle deaktivieren möchten. Wählen Sie dazu die Protokollstufe unter Projekteinstellungen > Grafiken > Globale URP-Einstellungen.

Wenn Sie außerdem die Option Shader-Varianten exportieren wählen, wird nach dem Build eine JSON-Datei erstellt, die einen Bericht über die Kompilierung der Shader-Varianten enthält. Diese Funktion ist für Unity 2022.2 oder neuer verfügbar.
Um zu verstehen, welche Shader zur Laufzeit tatsächlich für die GPU kompiliert werden, können Sie unter Projekteinstellungen > Grafik die Option Shader-Kompilierung protokollieren aktivieren.

Dies bewirkt, dass Ihr Spiel in den Spielerprotokollen ausgibt, wenn ein Shader kompiliert wird, während Sie spielen. Sie funktioniert nur bei Entwicklungs-Builds und im Debug-Modus, wie im Tooltip beschrieben.
Das Format sieht wie folgt aus:
Compiled Shader: Folder/ShaderName, pass: PASS_NAME, stage: STAGE_NAME, keywords ACTIVE_KEYWORD_1 ACTIVE_KEYWORD_2
Beachten Sie, dass einige Plattformen, wie z.B. Android, kompilierte Shader zwischenspeichern. Aus diesem Grund müssen Sie das Spiel möglicherweise deinstallieren und neu installieren, bevor Sie einen Testdurchlauf durchführen, um alle kompilierten Shader zu erfassen.
Schließlich können Sie das Paket Memory Profiler verwenden, um einen Schnappschuss Ihres Spiels zu machen, während es läuft, und haben dann einen Überblick darüber, welche Shader derzeit im Speicher geladen sind und wie groß sie sind. Die Sortierung nach Größe gibt normalerweise einen guten Hinweis darauf, welche Shader die meisten Varianten einbringen und optimiert werden sollten.

Im Rahmen der Stripping-Passagen entfernt Unity Shader-Varianten, die mit Grafikfunktionen zusammenhängen, die Ihr Spiel nicht verwendet. Der Prozess ändert sich leicht, wenn Sie die integrierte Render-Pipeline oder URP verwenden.
Um diese zu definieren, gehen Sie zu Projekteinstellungen > Grafiken. Von hier aus können Sie bei Verwendung der integrierten Render-Pipeline auswählen, welche Lightmap- und Nebelmodi Ihr Spiel unterstützt.

Wenn Sie sie auf Automatisch setzen, kann Unity anhand der in Ihrem Build enthaltenen Szenen bestimmen, welche Varianten entfernt werden sollen.
Wenn Sie sich nicht sicher sind, welche Funktionen Sie benötigen, können Sie auch die Schaltfläche Aus aktueller Szene importieren verwenden, um Unity herausfinden zu lassen, welche Funktionen Sie benötigen. Dies ist natürlich nur hilfreich, wenn alle Ihre Szenen die gleichen Einstellungen verwenden. Stellen Sie also sicher, dass Sie eine repräsentative Szene auswählen, wenn Sie diese Option verwenden.
Wenn Sie URP verwenden, werden einige dieser Optionen ausgeblendet. Stattdessen können Sie die Funktionen, die Ihr Spiel benötigt, direkt im Asset Pipeline-Einstellungen festlegen.
Wenn Sie z.B. Terrain Holes deaktivieren, werden alle Terrain Holes Shader-Varianten entfernt, was die Bauzeit ebenfalls verkürzt.
URP bietet eine genauere Kontrolle darüber, welche Funktionen Sie in Ihr Spiel aufnehmen möchten, was möglicherweise zu optimierten Builds mit weniger ungenutzten Varianten führt.
Hinweis: Dies ist nur relevant, wenn Sie die integrierte Render-Pipeline verwenden. Diese Einstellungen werden ignoriert, wenn Sie eine skriptfähige Rendering-Pipeline wie URP verwenden.
Grafikstufen werden verwendet, um je nach der Hardware, auf der Ihr Spiel läuft, unterschiedliche Grafikeinstellungen anzuwenden (nicht zu verwechseln mit den Qualitätseinstellungen). Wenn das Spiel startet, bestimmt Unity die Grafikstufe Ihres Geräts auf der Grundlage der Hardware-Fähigkeiten, der Grafik-API und anderer Faktoren.
Sie können sie unter Projekteinstellungen > Grafiken > Tiereinstellungen einstellen.

Auf dieser Grundlage fügt Unity diese drei Schlüsselwörter zu allen Shadern hinzu:
UNITY_HARDWARE_TIER1
UNITY_HARDWARE_TIER2
UNITY_HARDWARE_TIER3
Es erzeugt dann Shader-Varianten für jede der definierten Grafikebenen. Wenn Sie keine Grafikebenen verwenden und die zugehörigen Varianten dafür vermeiden möchten, müssen Sie sicherstellen, dass alle Grafikebenen auf genau dieselben Einstellungen gesetzt sind, damit Unity diese Varianten überspringt.
Wie bereits erwähnt, versucht Unity, Varianten, die identisch sind, zu deduplizieren. Wenn also beispielsweise zwei der drei Ebenen die gleichen Einstellungen haben, führt dies zu einer Verringerung der Größe auf der Festplatte, auch wenn weiterhin alle Varianten erzeugt werden. Sie können Unity optional dazu zwingen, Tier-Varianten für eine bestimmte Shader- und Grafik-Renderer-API zu generieren, indem Sie die hardware_tier_variants wie unten gezeigt verwenden:
// Direct3D 11/12
#pragma hardware_tier_variants d3d11
Unity kompiliert einen Satz Shader-Varianten für jede in Ihrem Build enthaltene Grafik-API. In einigen Fällen ist es daher von Vorteil, die APIs manuell auszuwählen und die nicht benötigten auszuschließen.
Gehen Sie dazu zu Projekteinstellungen > Player. Standardmäßig ist die Option Auto Graphics API ausgewählt. Unity enthält eine Reihe von integrierten Grafik-APIs und wählt zur Laufzeit je nach den Fähigkeiten des Geräts eine aus. Unter Android versucht Unity zum Beispiel zuerst, Vulkan zu verwenden. Wenn das Gerät dies nicht unterstützt, greift die Engine auf GLES3.2, GLES3.1 oder GLES3.0 zurück (die Varianten sind bei diesen GLES-Versionen jedoch identisch).
Deaktivieren Sie stattdessen die automatische Grafik-API für die jeweilige Plattform und wählen Sie die APIs, die Sie einbeziehen möchten, manuell aus. Unity wird dann dem ersten in der Liste den Vorrang geben.

Der Nachteil ist, dass Sie möglicherweise die Anzahl der Geräte einschränken, die Ihr Spiel unterstützen. Stellen Sie also sicher, dass Sie wissen, was Sie tun, wenn Sie dies ändern, und testen Sie es auf einer Vielzahl von Geräten.
Normalerweise versucht Unity zur Laufzeit die Variante zu laden, die den angeforderten Schlüsselwörtern am nächsten kommt, wenn eine exakte Übereinstimmung nicht verfügbar ist oder aus dem Player-Build entfernt wurde. Das ist zwar praktisch, verbirgt aber auch mögliche Probleme bei der Einrichtung Ihrer Shader-Schlüsselwörter.
Ab Unity 2022.3 können Sie unter Projekteinstellungen > Player die Option Strikte Shader-Variantenanpassung auswählen, um sicherzustellen, dass Unity nur versucht, die exakte Übereinstimmung für die von Ihnen benötigte Kombination aus lokalen und globalen Schlüsselwörtern zu laden.

Wenn er nicht gefunden wird, verwendet er den Fehler-Shader und gibt in der Konsole eine Fehlermeldung aus, die den Shader, den Subshader-Index, den aktuellen Durchlauf und die angeforderten Schlüsselwörter enthält. Das ist ziemlich praktisch, wenn Sie fehlende Varianten aufspüren müssen, die Sie tatsächlich benötigen. Wie beim Strippen üblich, funktioniert dies nur im Player und hat keine Auswirkungen auf den Editor.
Während Sie das Spiel im Editor spielen, merkt sich Unity, welche Shader und Varianten gerade in Ihrer Szene verwendet werden und ermöglicht Ihnen, diese in eine Collection zu exportieren. Navigieren Sie dazu zu Projekteinstellungen > Grafiken. Unten sehen Sie den Abschnitt Shader-Ladung, der anzeigt, wie viele Shader derzeit als aktiv verfolgt werden.
Stellen Sie sicher, dass Sie vorher auf Löschen drücken, um eine genauere Probe zu erhalten. Gehen Sie dann in den Spielmodus und beschäftigen Sie sich mit Ihrer Szene, um sicherzustellen, dass Sie auf alle Spielelemente treffen, die bestimmte Shader erfordern. Dadurch werden die verfolgten Zähler erhöht. Klicken Sie dann auf die Schaltfläche "In Asset speichern...", um alle diese Assets in einer Sammlung zu speichern.

Shader-Varianten Collections sind Assets, die eine Liste von Shadern und zugehörigen Varianten enthalten. Sie werden in der Regel verwendet, um im Voraus festzulegen, welche Varianten Sie in Ihr Build aufnehmen möchten und um Shader vorzuwärmen.

Ein in einigen Projekten verwendeter Ansatz besteht darin, dies für jeden Level des Spiels auszuführen, für jeden Level eine Collection zu speichern und dann alle Varianten, die in keiner dieser Listen vorhanden sind, mit Hilfe eines IPreprocessShaders-Skripts (das im nächsten Abschnitt behandelt wird) zu entfernen. Das ist zwar praktisch, aber meiner Erfahrung nach auch ziemlich fehleranfällig. Es ist schwer sicherzustellen, dass Sie in einem einzigen Durchgang auf alle erforderlichen Varianten stoßen, und einige der Funktionen können nur auf dem Gerät und in bestimmten Fällen geladen werden, was zu einer Liste führt, die nicht unbedingt korrekt ist. Wenn sich Ihr Spiel verändert und neue Elemente zu den Levels hinzugefügt werden oder sich die Materialien ändern, müssen die Collections aktualisiert werden. Aus diesem Grund würde ich dies hauptsächlich für Debugging- und Untersuchungszwecke verwenden, anstatt es direkt in Ihre Build-Pipeline zu integrieren.
Immer wenn ein Shader in Ihrem Spiel-Build kompiliert werden soll, sendet Unity einen Callback. Dies geschieht sowohl bei der Erstellung von Playern als auch von Asset-Bündeln. Wir können diese bequem mit IPreprocessShaders.OnProcessShader und IPreprocessComputeShaders.OnProcessComputeShader (für Compute-Shader) abhören und eine eigene Logik hinzufügen, um unnötige Varianten zu entfernen. Auf diese Weise können wir die Build-Zeit, die Build-Größe und die Gesamtzahl der Varianten, die in Ihren Build gelangen, erheblich reduzieren.
Erstellen Sie dazu ein Skript, das die Schnittstelle IPreprocessShaders implementiert, und schreiben Sie dann Ihre Stripping-Logik in OnProcessShader. Hier ist zum Beispiel ein Skript, das alle Varianten, die das Shader-Schlüsselwort DEBUG enthalten, bei Release-Builds entfernt:
public class StripDebugVariantsPreprocessor : IPreprocessShaders
{
public int callbackOrder => 0;
ShaderKeyword keywordToStrip;
public StripDebugVariantsPreprocessor()
{
keywordToStrip = new ShaderKeyword("DEBUG");
}
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data)
{
if (EditorUserBuildSettings.development)
{
return;
}
for (int i = data.Count - 1; i >= 0; i--)
{
if (data[i].shaderKeywordSet.IsEnabled(keywordToStrip))
{
data.RemoveAt(i);
}
}
}
}
Mit der Callback-Reihenfolge können Sie festlegen, welches Vorverarbeitungsskript zuerst ausgeführt werden soll, so dass Sie mehrstufige Stripping-Durchgänge erstellen können. Skripte mit einer niedrigeren Priorität werden zuerst ausgeführt.
Besuchen Sie die Diskussion im Graphics-Shaders Forum, um mehr zu erfahren.