Grafik- und Rendering-Tipps von Survival Kids

STEVEN CANNAVAN AND DANIEL REIDLER / UNITYSurvival Kids
Aug 20, 2025|8 Min.
Gameplay in Survival Kids
Diese Website wurde aus praktischen Gründen für Sie maschinell übersetzt. Die Richtigkeit und Zuverlässigkeit des übersetzten Inhalts kann von uns nicht gewährleistet werden. Sollten Sie Zweifel an der Richtigkeit des übersetzten Inhalts haben, schauen Sie sich bitte die offizielle englische Version der Website an.

In diesem Sommer veröffentlichte Unity das erste Spiel, das vollständig intern entwickelt wurde, ein Update zum Koop-Familien-Spiel Survival Kids, in Partnerschaft mit KONAMI. Das Spiel wurde von einem kleinen internen Team von maximal etwa 20 Personen entwickelt, sodass das Team innovative Wege finden musste, um im Rahmen des Projekts und des Zeitplans mit begrenzten Ressourcen zu bleiben, genau wie jedes Indie-Studio. In diesem Beitrag gehen wir darauf ein, wie wir den visuellen Rahmen und das Rendering des Spiels erstellt haben.

Definition der visuellen Identität

Wir wollten etwas visuell Interessantes erreichen. Unsere Ziele waren sehr künstlerisch, aber wir wollten es auch in Bezug auf die Leistung sehr günstig gestalten, da wir anfangs nicht wussten, mit welchen Geräteeigenschaften wir arbeiten würden.

Der erste Teil des Projekts bestand nur darin, visuell zu erkunden – wir hatten ein Kunst-Diorama, das wir verwendeten, um zu zeigen, wie wir uns die Kunst vorstellten. Ein Teil davon ist eine sehr stilisierte Beleuchtungseinrichtung, einschließlich benutzerdefinierter Schatten.

Wir haben uns für die Universal Render Pipeline (URP) entschieden, da sie eine hervorragende Leistung auf einer Vielzahl von Geräten bietet und es relativ einfach ist, neue Funktionen zu erstellen, die wir benötigen, um die visuellen Ziele des Spiels zu erreichen. Der gerenderte Rahmen ist sehr nah an der Vanilla URP im Forward-Modus, da das Spiel hauptsächlich nur eine Lichtquelle hat, die Sonne. Wir haben hier und da ein paar Modifikationen, wie die benutzerdefinierten Schatten, die Umgebungsokklusion und ein paar andere benutzerdefinierte Renderfunktionen, aber insgesamt ist es Vanilla URP auf dem Bildschirm.

Gameplay in Survival Kids
Gameplay in Survival Kids

Die größte Ergänzung war die zu den Shadern, um den sehr spezifischen Look der künstlerischen Richtung zu unterstützen, da wir Modifikationen daran vornehmen mussten, wie das Licht berechnet wurde. Benutzerdefinierte Shader zu erstellen ist nicht besonders neu, jedoch haben wir unsere eigenen benutzerdefinierten Shader Graph-Ziele geschrieben, um sicherzustellen, dass jeder beitragen kann. Die Verwendung von AssemblyDefinitionReferences ermöglichte es uns, projektspezifische Shader Graph-Ziele hinzuzufügen, ohne eine vollständig benutzerdefinierte URP-Version zu benötigen. Das ließ uns an der Vanilla URP mit nur unseren lokalen Shader Graph-Zielen festhalten, was für unser Projekt sehr gut funktionierte.

Beleuchtung und globale Beleuchtung

Eines unserer Ziele war es, dynamische Beleuchtung zu haben – wir wollten die Möglichkeit haben, die Lichtfarbe, Intensität usw. zu ändern. Das bedeutete, dass wir Beleuchtungsinformationen nicht einfach mit Lichtkarten backen konnten, sodass uns einige der Beleuchtungsdetails fehlen würden, die man durch das Backen von Streu- und globaler Beleuchtung erhalten würde. Wir mussten über verschiedene Möglichkeiten nachdenken, um hohe visuelle Qualität und gute Leistung mit einem dynamischen Beleuchtungsansatz in Einklang zu bringen, da dies normalerweise teurer ist. Das führte uns dazu, zunächst LightProbes zu verwenden und auch stärker auf Ambient Occlusion (AO) zu setzen, um Objekte zu verankern.

Beleuchtung und globale Beleuchtungsinformationen in einer Survival Kids-Umgebung
Beleuchtung und globale Beleuchtungsinformationen

Da wir wussten, dass globale Beleuchtung für dieses Projekt sehr wichtig sein würde, haben wir zunächst eine benutzerdefinierte Lösung implementiert, die LightProbes zur Laufzeit aktualisiert. Als wir dann zu Unity 6 wechselten, wollte das Team wirklich auf Adaptive Probe Volumes (APVs) umsteigen, da die visuelle Qualität erheblich besser war als das System, das wir zusammengeschustert hatten, während die Leistung vergleichbar war. Wenn Sie die Möglichkeit haben, von etwas Gutem auf etwas wirklich Gutem umzusteigen, das von hoher Qualität und leistungsfähig ist, wechseln Sie einfach.

Ozean

Der Ozean basierte stark auf einem Unity URP-Demo-Projekt Boot Angriff, hatte aber einen stilisierteren Look. Eine der Dinge, die wir wirklich tun wollten, war, dass Wellen von der Insel und anderen Elementen im Wasser kommen. Dies wird normalerweise implementiert, indem der Tiefenpuffer verwendet wird, um die Küstenlinie nach Entfernung zu ermitteln – aber wir haben eigentlich keine Küstenlinie, wir haben eine Whurtle-Insel.

Wellen treten im Ozeanwasser in einem festgelegten Abstand von der Küstenlinie einer kleinen Inselumgebung auf.
Das Signed Distance Field (SDF) erzeugt Wellen in einem festgelegten Abstand von der Küstenlinie.

Mit der Whurtle-Insel haben Sie einen plötzlichen Abfall, und es gibt nicht genug Tiefenabfall für den Effekt, insbesondere unter Berücksichtigung des Geländes, das unter Wasser liegt. Die beste Idee, die wir hatten, war die Verwendung eines Signed Distance Field oder SDF – es ist im Grunde eine Textur, die den signierten Abstand eines Objekts kodiert oder, in unserem Fall, die Küstenlinie. Auf diese Weise können wir die Welle in einem bestimmten Abstand von der Küstenlinie starten und dann Sinuswellen und einige Verzerrungstexturen verwenden, um ihr ein interessantes Aussehen zu verleihen.

Am Ende hatten wir ein Editor-Tool, das den signierten Abstand für die Küstenlinie basierend auf vier festgelegten Wasserhöhen backt. Dann haben wir einige Mischungen und Lerp zwischen ihnen gemacht, um eine grobe Annäherung daran zu erhalten, wo die Küstenlinie tatsächlich war, da der Wasserspiegel in den meisten Levels je nach Fortschritt des Spielers variiert. Wir haben uns auf diese vorgebackenen SDF-Informationen für mehrere verschiedene Effekte verlassen, von der Anpassung der Ozeanwellenhöhe bis hin zum Hinzufügen von Schaum, Wellen und Kaustiken.


Aufschlüsselung eines Frames
Hochrangige Aufschlüsselung eines gerenderten Frames
Hochrangige Aufschlüsselung eines gerenderten Frames, wobei die in Rot markierten Pässe angepasst sind
Visuelle Interaktion

Für visuelle Interaktionen wird eine Kapsel aus einer Draufsicht um alles gerendert, dessen Position wir verfolgen mussten, wie Spieler, tragbare Objekte, Werkzeuge usw., in ein RenderTexture. Die Textur basiert im Weltmaßstab mit einem gleitenden Fenster, während sich die Kamera des Spielers bewegt.

Wir erzeugen einen Offset (rot, blau) vom Zentrum der Kapsel sowie Informationen zur Weltmaßstabhöhe (grün). Im Alphakanal speichern wir einen Abfallwert für die Stärke. Das wird dann von verschiedenen Shadern verwendet, um Effekte wie das Biegen von Vegetation, animierte Wellen auf Wasseroberflächen oder das Abdunkeln des Geländes zu erzeugen, um einen sehr sanften Schatteneffekt zu erzeugen.


Shader werden auf eine RenderTexture "Kapsel" um Spieler und Objekte angewendet, um Effekte zu erzeugen, die sie im Raum verankert erscheinen lassen, wie Schatten oder Wellen im Wasser.
Shader werden auf eine RenderTexture "Kapsel" um jeden Spieler und tragbares Objekt angewendet, um Effekte zu erzeugen, die sie im Raum verankert erscheinen lassen, wie Schatten oder Wellen im Wasser.
Tiefe und Dither-Vorpass

Für eine Leistungsoptimierung haben wir einen Tiefenvorpass verwendet, der den Tiefenpuffer füllt, bevor wir Objekte normal rendern, wodurch die Kosten für das Rendern dieser Objekte durch frühe Tiefentestablehnung gesenkt werden.

Ein Stencil, das für das Weichzeichnen im SMAA-Pass verwendet wird und den Tiefenpuffer mit einem Dither-Muster vorfüllt, um hinter der Geometrie zu sehen.
Ein Stencil, das für das Weichzeichnen im SMAA-Pass verwendet wird und den Tiefenpuffer mit einem Dither-Muster vorfüllt, um hinter der Geometrie zu sehen.

Wir haben mit ditherten Objekten in einem benutzerdefinierten Pass separat gearbeitet, da wir sie je nach Zustand und dem Spieler, der sie betrachtet, unterschiedlich rendern müssen. Sie befinden sich in einer anderen GameObject-Schicht, die vom Opaque Layer Mask im Renderer ausgeschlossen ist, sodass sie nicht automatisch gerendert werden, und das bedeutet, dass wir sie in einem benutzerdefinierten Pass rendern müssen. Wir haben MaterialPropertyBlocks verwendet, um individuelle Werte für Objekte festzulegen, und Stencils angewendet, um die Objekte zu kennzeichnen, die gedithert sind, damit wir diese Abschnitte später weichzeichnen können. Da dies jedoch das SRP-Batching unterbricht, mussten wir die Verwendung einschränken. Wir haben beschlossen, MaterialPropertyBlocks nur nach Bedarf anzuwenden und sie zu entfernen, wenn wir fertig sind, um die Objekte in einen batchbaren Zustand zurückzuversetzen.

Am Ende haben wir einen gesamten Pass, der sich nur damit beschäftigt, wie wir diese bestimmte Schicht in den Tiefenpuffer rendern. Als nächstes wenden wir ein Stencil auf den Tiefenpuffer an, um zu markieren, welche Pixel Teil der Objekte sind, die wir ausblenden, und das wird später verwendet, wenn wir Antialiasing durchführen.

Gradientenschatten

Ein Teil unseres Kunststils bestand darin, farbige Schatten mit einem Farbverlauf in Richtung des Schattens zu haben. Um dies zu erreichen, hatten wir eine benutzerdefinierte Bildschirmtextur erstellt, die von einem RenderFeature generiert wurde, das die Schattenkarte im Weltmaßstab abtastete, aber auch im XZ-Plane vorausschaut, um einen Schattenmischwert zu bestimmen. Dies ähnelt einem PCF-Filter, der in weichen Schatten verwendet wird, jedoch in eine Richtung. Dies wurde in eine verkleinerte Textur gerendert, die etwa ein Viertel der Bildschirmgröße hatte, und wir haben dann die Schattenfarbe zwischen drei Farben gemischt.

Ein Bildschirmraum-Pass mit niedriger Auflösung auf den Schatten erzeugt die Randverlauf-Farben und erstellt einen Verlauf in Lichtrichtung. Es verlässt sich später auf bilineares Sampling.
Ein Bildschirmraum-Pass mit niedriger Auflösung auf den Schatten erzeugt die Randverlauf-Farben und erstellt einen Verlauf in Lichtrichtung. Es verlässt sich später auf bilineares Sampling.
MSVAO (multi-scale volumetrische Umgebungsokklusion)

Leider war das SSAO, das mit URP bereitgestellt wurde, nicht ganz auf unsere Bedürfnisse zugeschnitten. Obwohl es eine mobile-freundliche Implementierung ist, mussten wir für den Look, den wir anstreben, den Radiuswert ziemlich hoch einstellen, was einen erheblichen Teil unseres Frame-Budgets (~4ms) in Anspruch nahm. Stattdessen haben wir die MSVAO-Implementierung aus dem alten PostProcessing Stack v2-Paket wiederverwendet, mit einigen geringfügigen Änderungen, um sie effizienter zu machen und unsere Schattenfarbe zu integrieren.

Perspektive einer Insellandschaft, die eine angepasste Version der MSVAO aus dem PostProcessing Stack v2-Paket zeigt, mit geringfügigen Anpassungen, um sie auf einer Zielplattform leistungsfähiger zu machen.
Eine angepasste Version der MSVAO aus dem PostProcessing Stack v2-Paket, mit geringfügigen Anpassungen, um sie auf einer Zielplattform leistungsfähiger zu machen.
Die Szene zeichnen

Survival Kids hat die standardmäßigen Rendering-Pässe, die man in URP erwartet (Opaque, Skybox, Transparenz), aber wir haben auch einen zusätzlichen Pass, um unsere ditherten Objekte zu behandeln, direkt nach dem undurchsichtigen Pass. Hier werden wir tatsächlich unsere ditherten Geometrien rendern, da Geometrie in dieser Schicht im undurchsichtigen Pass nicht gerendert wird. Wir führen auch einen Tiefenvergleichstest in diesem Pass durch, um sicherzustellen, dass wir nur dort rendern, wo wir den Tiefenpuffer vorgefüllt haben.

Zeichnen der Geometrie (Tiefenvergleichstest) für unsere ditherten Objekte. Umgebungsokklusion ist in diesem Zustand deaktiviert.
Zeichnen der Geometrie (Tiefenvergleichstest) für unsere ditherten Objekte. Umgebungsokklusion ist in diesem Zustand deaktiviert.

Für Objekte, die gedithert sind, müssen wir die Umgebungsokklusion deaktivieren, da Artefakte auftreten, weil MSVAO die "Löcher" im Tiefenpuffer als Okklusion behandelt.

Spielbild, das die visuellen Effekte der Verwendung von SMAA + Unschärfe auf Dithern zeigt.
SMAA + Unschärfe auf Dithering

Nachdem die Szene gerendert wurde, wenden wir unser Anti-Aliasing an. Leider werden die Bereiche, die gedithert sind, den Algorithmus (SMAA) durcheinanderbringen, was visuelle Artefakte verursacht. Um dies zu vermeiden, müssen wir diese Bereiche separat behandeln. Bereiche, die gedithert sind (bestimmt durch die Stencil), werden unscharf gemacht, was einen Alpha-Misch-Effekt in diesen Bereichen erzeugt, und dann wird SMAA in den Bereichen verarbeitet, die nicht gedithert sind. Dies wird unter bestimmten Umständen übersprungen, aber wir erhalten ein bereinigtes Endbild, das bereit für die Nachbearbeitung ist.

Nachbearbeitung und UI

Wir haben unsere Nachbearbeitungseffekte so günstig wie möglich gehalten, indem wir nur ein wenig Tonemapping, Bloom und Farbkorrektur verwendet haben.

An einem Punkt haben wir URP’s Unschärfe in der Nachbearbeitung verwendet, um das Spiel hinter der UI zu glätten, aber wir haben das später durch einen günstigeren Kawase-Unschärfe-RenderFeature ersetzt. Unser UI-System basiert auf UGUI mit ein wenig benutzerdefiniertem Rendering für das Ausblenden.

UI in Survival Kids
UI in Survival Kids

Als wir unser UI ursprünglich einrichteten, haben wir Menüs ein- und ausgeblendet, aber dieser Ansatz verursachte einige Probleme aufgrund der Art und Weise, wie der Alpha für die UI gemacht wird. Zuerst haben wir die UI über eine Kamera in eine separate Textur gerendert und dann korrekt geblitzt, damit wir die UI in das Hauptbild einblenden können. Wir haben dies geändert, damit es mit einem RenderFeature erreicht werden kann, anstatt eine ganze zusätzliche Kamera zu verwenden.

Dieser Beitrag bietet nur einen Einblick, wie wir stilisierte, leistungsfähige Grafiken und Rendering eingerichtet haben, um unsere Zielrate für Survival Kids zu erreichen. Bleiben Sie dran für den Unity-Blog für weitere Einblicke hinter die Kulissen über das Spiel, einschließlich eines zweiteiligen tiefen Einblicks in Multiplayer-Netzwerke und einen Blick auf das Terrain und die Arbeitsabläufe des Teams, oder schauen Sie sich weitere technische Entwicklergeschichten auf unserer Ressourcenseite an.