Titelbild: eine lange, von der Sonne beleuchtete Kolonnade mit scharfen, stabilen Schatten auf dem Gehweg

Schatten gehören zu den Details, die einer 3D-Szene Bodenhaftung und Glaubwürdigkeit verleihen – und zugleich zu denen, bei denen Fehler am leichtesten ins Auge fallen. Dieses Update macht die Schatten der Sonne stabiler, sauberer und deutlich leichter einstellbar und bringt dieselben Verbesserungen auch für Spot-, Punkt- und Flächenlichter.

Kurz zusammengefasst:

In diesem Artikel

Warum Schatten wichtig sind

Entfernen Sie die Schatten aus einer Szene, und alles scheint zu schweben. Objekte verlieren ihre Verbindung zum Boden, Tiefe ist schwerer zu erfassen, und die Beleuchtung wirkt flach. Ein guter Schatten zeigt Ihnen, wo sich Dinge befinden, wie groß sie sind und woher das Licht kommt.

Ein schlechter Schatten fällt ebenso auf. Kanten, die bei Kamerabewegungen wandern, Streifen auf einer Oberfläche oder ein Schatten, der sich vom werfenden Objekt löst – all das zerstört die Illusion sofort. Genau das nimmt dieses Release ins Visier.

Wie funktioniert ein Echtzeitschatten?

Echte Schatten entstehen, weil Licht blockiert wird, doch ein Echtzeit-Renderer verfolgt kein Licht. Er nutzt einen günstigeren und sehr wirkungsvollen Trick, die sogenannte Shadow Map:

  1. Aus Sicht des Lichts. Wir rendern die Szene aus dem Blickwinkel des Lichts, speichern aber für jedes Pixel nur die Entfernung zur nächstgelegenen Oberfläche. Das Ergebnis ist die Shadow Map.
  2. Aus Sicht der Kamera. Für jedes Pixel auf dem Bildschirm ermitteln wir, wo es aus Sicht des Lichts liegt, und vergleichen seine Entfernung mit dem Wert, den die Shadow Map aufgezeichnet hat.
  3. Entscheiden. Wurde etwas näher am Licht aufgezeichnet, liegt das Pixel im Schatten. Andernfalls ist es beleuchtet.

Diagramm: eine Shadow Map in drei Schritten

Der Haken: Eine Shadow Map ist eine Textur mit fester Auflösung. Stellen Sie sie sich als niedrig aufgelöstes Foto der Szene vor, aufgenommen aus Sicht des Lichts. Fast jede Schattentechnik ist ein Weg, das Beste aus dieser begrenzten Auflösung herauszuholen.

Und was ist mit Raytracing- und Pathtracing-Schatten?

Shadow Maps sind eine Näherung, daher ist die Frage berechtigt, warum wir das Licht nicht einfach verfolgen. Auf GPUs mit Hardware-Raytracing ist das möglich: Man schickt von jedem sichtbaren Punkt einen Strahl in Richtung Licht, und wenn etwas im Weg ist, liegt der Punkt im Schatten. Es gibt keine Texturauflösung, die ausgehen könnte, also keine Blockartefakte, keine Acne und kein Peter-Panning, und weiche Schatten werden präzise berechnet. Pathtracing geht noch weiter und verfolgt viele zufällige Lichtpfade, während sie durch die Szene reflektiert werden, sodass Schatten, Reflexionen und indirekte Beleuchtung aus demselben Prozess hervorgehen. Das Pathtracer-Beispiel von Evergine zeigt, wie das aussieht.

Diagramm: Shadow Maps im Vergleich zu Raytracing-Schatten

Der Preis ist die Performance. Ein sauberes Bild erfordert in jedem Frame mehrere Strahlen pro Pixel, meist gefolgt von einem Denoiser. Die Szene benötigt eine Beschleunigungsstruktur, die neu aufgebaut werden muss, wenn sich Objekte bewegen. Und Strahlen streuen in alle Richtungen, was den GPU-Speicher weit stärker belastet als das Rasterisieren von Dreiecken in eine Textur. Selbst High-End-Desktop-GPUs gehen sparsam mit ihren Strahlen um, und die meisten Smartphones, Tablets und Einsteigergeräte haben überhaupt kein Hardware-Raytracing.

Deshalb sind Shadow Maps nach wie vor das Arbeitspferd für Echtzeitschatten: Sie sind günstig, vorhersehbar und laufen auf praktisch jedem Gerät. Raytracing ist eine hervorragende Option, wo die Hardware es zulässt, doch Shadow Maps sorgen dafür, dass eine Szene überall sonst läuft – und deshalb investieren wir weiter in sie.

Das Sonnenproblem und Kaskaden

Ein gerichtetes Licht steht für die Sonne, und die Sonne beleuchtet alles. Eine einzelne Shadow Map müsste die gesamte sichtbare Welt abdecken. Eine über Hunderte Meter gestreckte Textur ergäbe also blockige Schatten direkt vor dem Spieler, wo Details am wichtigsten sind.

Die klassische Lösung sind Cascaded Shadow Maps. Wir teilen die Ansicht nach Entfernung von der Kamera in Abschnitte auf: einen kleinen Abschnitt nahe bei Ihnen, einen größeren dahinter und so weiter. Jeder Abschnitt erhält eine eigene Shadow Map, sodass nahe Schatten scharf und ferne gröber sind. Weit entfernte Dinge sind auf dem Bildschirm klein, daher fällt das kaum auf.

Diagramm: das Kamera-Frustum, aufgeteilt in vier Kaskaden, die jeweils in eine Shadow Map gleicher Auflösung gerendert werden

Evergine verwendete bereits Kaskaden. Im neuen Release geht es darum, dass sie sich besser verhalten.

Wo der bisherige Ansatz an seine Grenzen stieß

Drei Probleme traten immer wieder auf:

Neuerungen

Kaskaden, die nicht mehr flimmern

Der Schattenraum hängt jetzt nur noch von der Ausrichtung des Lichts ab, nicht davon, wohin die Kamera blickt. Jede Kaskade wird zudem am Texelraster der Shadow Map ausgerichtet, und ihre Größe ändert sich nur in kleinen Schritten von etwa 2 %. Dadurch ändert eine Bewegung oder Drehung der Kamera nicht mehr, welcher Texel welchen Teil der Welt abdeckt, und das Flimmern ist verschwunden.

Diagramm: die Schattenkante über drei Frames, vor und nach dem Ausrichten der Kaskaden am Texelraster

Ein Bias, der Ihre Szene versteht

Der Bias wird jetzt im World Space angewendet und in Shadow-Map-Texeln gemessen. Zwei neue Eigenschaften, ShadowDepthBias und ShadowNormalBias, skalieren automatisch mit der Texelgröße jeder Kaskade und mit der Weichheit des Schattenfilters. Eine einzige Einstellung verhält sich jetzt von der nächsten bis zur fernsten Kaskade sinnvoll, wodurch die Acne-Streifen bei flachen Winkeln und die schwebenden Schatten in der Ferne verschwinden.

Diagramm: zu wenig Bias, ausgewogener Bias und zu viel Bias

Spot-, Punkt- und Flächenlichter

Das texelbasierte Bias-Modell ist nicht auf die Sonne beschränkt. Auch Spot-, Punkt- und Flächenlichter verwenden es jetzt, sodass ShadowDepthBias und ShadowNormalBias bei jedem Lichttyp dasselbe bedeuten. Dabei haben wir zwei Probleme behoben:

Diagramm: das Guard Band, durch das sich die Würfelflächen um ein Punktlicht überlappen

Einstellbare Kaskaden

Gerichtete Lichter legen jetzt die Kompromisse zwischen Qualität und Performance offen:

Diagramm: die Kaskaden-Fit-Modi Stable und Tight

Hinweis: Das Aktualisierungsintervall hat keine Wirkung, wenn ein Licht von mehreren Kameras gerendert wird.

Besseres Debugging

Der Debug Mode für Lichter zeigt jetzt die Farbe jeder Kaskade (und bei Punktlichtern jeder Würfelfläche) sowie ein Schachbrettmuster aus 8x8 Shadow-Map-Texeln, sodass Sie genau sehen, wie dicht Ihre Schatten auf dem Bildschirm sind. Auch Spotlichter erhalten einen eigenen DebugMode.

Außerdem haben wir verwandte Probleme behoben: Die Distanzen der Kaskadenaufteilung verwenden jetzt die korrekte Formel, orthografische Kameras mit einer Near Plane von null erzeugen keine ungültigen Aufteilungen mehr, und beim Rendern mehrerer Kameras mit mehreren schattenwerfenden gerichteten Lichtern überschreiben sich die Lichter nicht mehr gegenseitig ihre Shadow Maps. Die Backends behandeln Depth Clamping einheitlich, sodass Objekte vor einer Kaskade nicht mehr abgeschnitten werden.

Sehen Sie den Unterschied

Ziehen Sie den Schieberegler, um das bisherige Schattensystem mit dem neuen in derselben Szene und Kameraposition zu vergleichen.

Vorher: Kolonnade vom Gehweg aus gesehen, mit dem bisherigen Schattensystem Nachher: Kolonnade vom Gehweg aus gesehen, mit dem neuen Schattensystem
Vergleich 1
Vorher: Testszene, Ansicht 2, mit dem bisherigen Schattensystem Nachher: Testszene, Ansicht 2, mit dem neuen Schattensystem
Vergleich 2
Vorher: Zaun und Säulenbasis, mit dem bisherigen Schattensystem Nachher: Zaun und Säulenbasis, mit dem neuen Schattensystem
Vergleich 3
Vorher: Testszene, Ansicht 4, mit dem bisherigen Schattensystem Nachher: Testszene, Ansicht 4, mit dem neuen Schattensystem
Vergleich 4
Vorher: Testszene, Ansicht 5, mit dem bisherigen Schattensystem Nachher: Testszene, Ansicht 5, mit dem neuen Schattensystem
Vergleich 5
Vorher: Kolonnade und Obelisken in der Ferne, mit dem bisherigen Schattensystem Nachher: Kolonnade und Obelisken in der Ferne, mit dem neuen Schattensystem
Vergleich 6

Erste Schritte

Sie können alles im Editor oder im Code anpassen. Die folgenden Werte sind beispielhafte Ausgangspunkte – stimmen Sie sie auf Ihre Szene ab:

// Get the directional light of your sun entity
var sun = sunEntity.FindComponent<DirectionalLight>();

sun.IsShadowEnabled = true;
sun.ShadowDistance = 100;                   // How far from the camera shadows are rendered
sun.ShadowCascadeCount = 3;                 // Between 1 and 4

// Keep cascades stable, and fade shadows out smoothly
sun.CascadeFitMode = DirectionalLight.CascadeFitModes.Stable;
sun.ShadowFadeFraction = 0.1f;
sun.CascadeBlendFraction = 0.1f;

// Bias is measured in shadow map texels
sun.ShadowDepthBias = 1;
sun.ShadowNormalBias = 1;

Damit wird eine schattenwerfende Sonne mit drei stabilen Kaskaden, weicher Überblendung zwischen ihnen und einem sanften Ausblenden an der Schattendistanz aktiviert. Wenn Sie Acne sehen, erhöhen Sie die Bias-Werte leicht. Wirken Schatten von ihren Werfern losgelöst, verringern Sie sie.

Upgrade von der vorherigen Version

Einige Änderungen betreffen bestehende Projekte:

Probieren Sie es aus und sagen Sie uns Ihre Meinung

Bereit für stabilere, sauberere Schatten in Ihren Szenen? Aktualisieren Sie Evergine, öffnen Sie eine Szene mit einem gerichteten Licht und probieren Sie die neuen Optionen aus.

Wir freuen uns auf Ihre Meinung.

José Antonio Collado Araque
Autor
José Antonio Collado Araque
Graphics Engineer – Researcher