Lightmaps und globale Beleuchtung
Einführung
Hinweis: Ab Qt 6.4 befindet sich das Baking von Lightmaps in einem frühen Technologie-Preview-Stadium. In zukünftigen Versionen sind Änderungen an Funktionen, Qualität und API wahrscheinlich.
Mit gebackenen Lightmaps lässt sich die direkte Beleuchtung durch Lichtquellen wie „ DirectionalLight “, „ PointLight “ und „ SpotLight “ vorab generieren, einschließlich der von den Lichtquellen geworfenen Schatten. Zur Laufzeit wird anstelle der entsprechenden Berechnungen im Fragment-Shader und – im Falle von Schatten – der potenziell rechenintensiven Echtzeit-Generierung von Schattenkarten stattdessen die vorab generierte Bildkarte abgefragt.
Pro „ Model “ wird eine Lightmap generiert. Selbst wenn ein „ Model “ mehrere Submeshes aufweist und daher mehreren Materialien zugeordnet ist, wird für das gesamte Modell ein einziges Lightmap-Bild generiert.
Lightmaps werden mittels Raytracing erzeugt, das naturgemäß für korrekte Okklusion sorgt („Licht dringt nicht durch Wände“) und möglicherweise realistischere Schatten liefert als die Echtzeitverfahren für Beleuchtung und Schattenabbildung.
Noch wichtiger ist, dass Lightmaps auch das „Baking“ indirekter Beleuchtung ermöglichen und damit eine Lösung für die globale Beleuchtung bieten. Dabei werden Lichtstrahlen berücksichtigt, die von anderen Oberflächen in der Szene reflektiert werden.
Nachfolgend finden Sie ein einfaches Beispiel. Die Szene enthält vier „Rectangle“- und ein „Sphere“-Modell sowie eine nach unten gerichtete „ DirectionalLight “ und eine „ PointLight “. Die „Rectangle“-Modelle sind um 0 und 90 Grad gedreht, was die Einschränkungen der Echtzeit-Beleuchtungsberechnungen überdehnt, da sie alle entweder parallel oder senkrecht zur Richtung der „ DirectionalLight “ stehen.
Auf dem zweiten Bild wird die Szene mit aktiviertem Lightmapping gerendert, nachdem für alle fünf Modelle Lightmaps gebacken wurden. Beide Lichtquellen sind auf „vollständig gebacken“ eingestellt, was bedeutet, dass sowohl die direkte als auch die indirekte Beleuchtung gebacken wurde. Für die indirekte Beleuchtung werden 256 „ samples “ und maximal 3 „ bounces “ verwendet. Die resultierenden Lightmaps wurden anschließend entrauscht. Dies führt zu einem deutlich realistischeren Bild.
Echtzeitbeleuchtung

Vollständig gebackene Beleuchtung

Im folgenden Ausschnitt wird gezeigt, wie die Ergebnisse mit Lightmaps erzielt wurden. Der Unterschied liegt in den Eigenschaften „ usedInBakedLighting “, „ bakeMode “ und „ bakedLightmap “. In diesem Beispiel wurde die Lightmap-Größe mithilfe der Eigenschaft „ texelsPerUnit “ reduziert, um Speicherplatz zu sparen und die Ladezeiten der Anwendung zu verkürzen.
DirectionalLight {
bakeMode: Light.BakeModeAll
eulerRotation.x: -90
brightness: 0.5
castsShadow: true
shadowFactor: 75
}
PointLight {
bakeMode: Light.BakeModeAll
y: 200
z: 100
color: "#d9c62b"
castsShadow: true
shadowFactor: 75
}
Model {
usedInBakedLighting: true
bakedLightmap: BakedLightmap {
enabled: true
key: "sphere1"
}
source: "#Sphere"
materials: PrincipledMaterial { }
y: 100
}
Model {
usedInBakedLighting: true
bakedLightmap: BakedLightmap {
enabled: true
key: "rect1"
}
source: "#Rectangle"
materials: PrincipledMaterial { }
eulerRotation.x: -90
scale: Qt.vector3d(10, 10, 10)
}
// ... three additional Rectangle models, with rotations 0, 90, and -90Im obigen Beispiel wurden vollständig gebackene Lichter verwendet. Eine Lichtquelle kann auch so konfiguriert werden, dass sie vorgerenderte Beleuchtung nur für die indirekte Beleuchtung verwendet, während die direkte Beleuchtung und das Schatten-Mapping in Echtzeit erfolgen. In der folgenden Szene gibt es 5 Punktlichtquellen, die für den zweiten Screenshot alle auf „ BakeModeIndirect “ eingestellt sind. Während die direkte Beleuchtung und die Schatten identisch aussehen, wirkt das zweite Bild aufgrund einer zusätzlichen globalen Beleuchtung deutlich besser.
Echtzeitbeleuchtung

Mit hinzugefügter gebackener indirekter Beleuchtung

Wichtige Überlegungen bei der Arbeit mit Lichtkarten
Bei Lichtquellen, die zur „Baked Lighting“ beitragen, ist die Eigenschaft „ bakeMode “ entweder auf „ Light.BakeModeIndirect “ oder „ Light.BakeModeAll “ gesetzt. Letzteres bedeutet, dass sowohl der direkte als auch der indirekte Beitrag dieser bestimmten Lichtquelle aus der Lightmap stammt. Der direkte Beitrag umfasst immer auch Schatten. Soll die Lichtkarte hingegen lediglich dazu dienen, der Szene für eine bestimmte Lichtquelle indirekte Beleuchtung hinzuzufügen, während die direkte Beleuchtung weiterhin in Echtzeit berechnet wird (und Schatten-Mapping durchgeführt wird), sollte die Lichtquelle stattdessen „ Light.BakeModeIndirect “ verwenden.
Hinweis: Lightmaps eignen sich im Allgemeinen für Modelle, die hinsichtlich Transformation, Geometrie und Materialien statisch sind. Dasselbe gilt für die Lichter, die an der gebackenen Beleuchtung beteiligt sind.
Beispielsweise führt eine Szene, in der ein „ Model “ durch Animation der Eigenschaft „ eulerRotation “ gedreht wird, zu visuell fehlerhaften Ergebnissen, wenn eine Lichtkarte auf dieses „ Model “ angewendet wird. Die Renderergebnisse für dieses bestimmte „ Model “ sind fehlerhaft, da die vorab generierte Lichtkarte nur einen einzigen Rotationszustand des Objekts erfasst. Das Gleiche würde, um ein anderes Beispiel zu nennen, gelten, wenn das Material für eines der Submeshes des Modells seine Eigenschaft „ baseColor “ dynamisch in Abhängigkeit von der Zeit (Animation) oder einer Benutzerinteraktion ändert. Die Lightmap kann nur eine bestimmte Material baseColor erfassen. Das Gleiche gilt für Lichter. Beispielsweise ist ein „ DirectionalLight “, das sich dreht und im Laufe der Zeit seine Helligkeit, Farbe usw. ändert, nicht für gebackene Beleuchtung geeignet.
Hinweis: Andererseits liegt die Entscheidung, wann Lightmapping verwendet wird, stets beim Designer. Insbesondere bei „ BakeModeIndirect “-Lichtern ist es wahrscheinlich, dass es Szenen gibt, in denen die Ergebnisse visuell immer noch zufriedenstellend sind, auch wenn einige der Objekte in der Lightmapping-Szene dynamisches Verhalten aufweisen.
Lightmapping ist eine komplexe Engine- und Tooling-Funktion. Es ersetzt und implementiert mehrere Teile der Rendering-Pipeline der Engine neu. Beim Baking von Lightmaps arbeitet es mit einem grundlegend anderen Rendering-Modell, nutzt dabei jedoch weiterhin dieselbe Szenenstruktur, dieselben Asset-Daten und dieselben Engine-Datenstrukturen und interagiert mit diesen. Die auf Raytracing basierenden Ergebnisse übertreffen oft die Echtzeit-Alternativen, manchmal sogar deutlich, was jedoch mit Einschränkungen einhergeht, wie beispielsweise der zwingenden Statik der beteiligten Modelle und Lichter sowie gelegentlich mit Qualitätsproblemen und Rendering-Artefakten, die spezifisch für das Lightmapping sind.
In der Praxis ist es eine künstlerische Entscheidung der Designer, welche Art von Beleuchtung wann verwendet wird. Alle drei „ bakeMode “-Einstellungen haben ihre Berechtigung, und komplexe, größere Szenen können durchaus alle drei für unterschiedliche Lichtquellen nutzen, je nachdem, was für einen bestimmten Abschnitt der Szene als geeignet erachtet wird und welche Art von Modellen, Materialien und dynamischem Verhalten vorhanden ist. Lightmapping ist kein einfacher Ein-/Aus-Schalter, der für jede Szene und Anwendung aktiviert werden kann, sondern eine leistungsstarke Funktion, die eine sorgfältige Bewertung der Beleuchtungsanforderungen einer bestimmten Szene voraussetzt und oft erfordert, dass der Inhalt und das Verhalten der Szene entsprechend gestaltet werden, kombiniert mit einem Test- und Optimierungszyklus, in dem verschiedene Einstellungen für das Baking und die Qualität der Lightmaps untersucht und getestet werden, bevor man sich für den endgültigen Ansatz und die entsprechenden Einstellungen entscheidet.
Hinweis: Lightmaps unterstützen keine doppelseitigen Oberflächen. Bei der Echtzeitbeleuchtung kehrt ein Material mit der Einstellung „ cull mode “ ( Material.NoCulling ) die Normale automatisch entsprechend der Ausrichtung des Fragments um. Dies ist bei Lightmaps nicht möglich, da das Lightmap-Baking nicht im Ansichtsraum erfolgt. Vermeiden Sie daher gebackene Beleuchtung für Modelle, die darauf angewiesen wären.
Lightmaps backen
Eigenschaften und Typen, die für das Baking von Lightmaps relevant sind, d. h. den Offline-Prozess zur Erzeugung von Bildkarten, die direkte und indirekte Beleuchtung erfassen und vom Renderer bei nachfolgenden Ausführungen der Anwendung verwendet werden können:
- Model::usedInBakedLighting
- Model::lightmapBaseResolution,
- Light::bakeMode,
- Lightmapper und SceneEnvironment::lightmapper
- BakedLightmap und Model::bakedLightmap
Ab Qt 6.4 muss der Lightmap-Baking-Prozess manuell ausgelöst werden. Immer wenn das Befehlszeilenargument „ --bake-lightmaps “ vorhanden ist oder die Umgebungsvariable „ QT_QUICK3D_BAKE_LIGHTMAPS “ auf „ 1 “ (oder einen anderen Wert ungleich Null) gesetzt ist, arbeitet die Engine im Baking-Modus und beendet die Anwendung, sobald das Baking abgeschlossen ist. Die einzelnen Schritte des Baking-Prozesses lassen sich anhand der in der Debug-Ausgabe angezeigten Meldungen verfolgen. Das Ergebnis ist eine Binärdatei (standardmäßig „lightmaps.bin “), die in das aktuelle Arbeitsverzeichnis geschrieben wird und alle gebackenen Lightmaps der Szene enthält. Außerdem wird eine Datei „ .raw “ erstellt, die die gesamte Lightmap sowie einige zusätzliche Daten enthält, die für die Rauschunterdrückung benötigt werden. Jede Lightmap wird in der Datei durch den eindeutigen Schlüssel aus „ BakedLightmap::key “ identifiziert.
Die Vorbereitung einer Szene mit Lightmaps umfasst die folgenden Hauptschritte:
- Legen Sie fest, welche Modelle eine Lightmap verwenden sollen und welche Modelle zur Lightmap beitragen sollen. Modelle, die Teil der Lightmap-Szene sind, sollten „ Model::usedInBakedLighting “ auf „true“ setzen. Modelle, für die eine Lightmap erstellt wird (d. h., für die eine Lightmap gebacken werden soll), sollten zusätzlich ` Model::bakedLightmap ` auf ein aktiviertes ` BakedLightmap `-Objekt setzen, das einen eindeutigen Schlüssel bereitstellt, der die jeweilige Instanz des `Model`-Objekts dauerhaft identifiziert (dies liegt daran, dass Qt einen Schlüssel benötigt, um die Modelldaten im persistenten Festplattenspeicher zu identifizieren). Nur bei Modellen mit statischer Geometrie, Transformation und Materialien sind korrekte Ergebnisse garantiert, wenn sie zur Laufzeit mit einer Lightmap versehen werden. In der Regel führt alles, was im Laufe der Zeit zu einer nicht-statischen Welttransformation führt – wie beispielsweise eine dynamisch geänderte oder animierte Position, Rotation oder Skalierung –, dazu, dass das Modell von der Teilnahme ausgeschlossen wird. Künstlerische Anforderungen können dies jedoch außer Kraft setzen, insbesondere bei Modellen, die nur zur gebackenen indirekten Beleuchtung beitragen, selbst aber nicht mit einem Lightmap versehen werden. Bei diesen kann es oft visuell akzeptabel sein, dynamische Transformationen zu haben, was jedoch immer vom jeweiligen Modell und der jeweiligen Szene abhängt.
- Legen Sie fest, welche Lichter in welchem Umfang beitragen sollen. „ Light::bakeMode “ bietet drei Optionen:
- Light.BakeModeDisabled, die Standardeinstellung, bei der das Licht für alle Lightmapping-Zwecke effektiv ignoriert wird.
- Light.BakeModeIndirect ist oft die „sichere“ Wahl, wenn das einzige Ziel darin besteht, ein Maß an globaler Beleuchtung (indirekte Beleuchtung) in der Szene zu erzielen, ohne die Renderergebnisse für das Licht anderweitig zu beeinflussen. In diesem Modus führt der Renderer weiterhin die gesamte Beleuchtung durch, einschließlich diffuser, spiegelnder, Himmel-/Umgebungsbeiträge sowie des Schatten-Mappings für diese Lichtquelle unter Verwendung der üblichen Echtzeit-Techniken. Die Lichtquelle trägt jedoch mithilfe der vorab gebackenen Daten zur indirekten Beleuchtung bei, was möglicherweise dazu führt, dass Oberflächen beleuchtet werden, die von den standardmäßigen Echtzeit-Beleuchtungsberechnungen ansonsten unberührt bleiben.
- „Light.BakeModeAll“ ist eine Option, die wahrscheinlich nur für bestimmte Lichter verwendet wird, je nachdem, was die Designer für eine bestimmte Szene als angemessen erachten. In diesem Modus werden alle Beiträge des Lichts gebacken, einschließlich der Schatten. Stand Qt 6.4 wird spiegelnde Beleuchtung nicht als Teil der gebackenen Beleuchtung unterstützt, sodass solche Lichter keine spiegelnden Beiträge aufweisen. Andererseits erzeugen sie raygetrackte, gebackene Schatten und weisen eine korrekte Okklusion für das Licht auf (sie „dringen“ beispielsweise nicht „durch Wände“), da hier alle direkten Beleuchtungsbeiträge, die von dem Licht ausgehen, bereits beim Backen der Lightmap per Raytracing ermittelt werden, anstatt zur Laufzeit berechnet zu werden. Zudem wird die indirekte Beleuchtung gebacken, genau wie bei „BakeModeIndirect“.
- Führen Sie die Szene (Anwendung) im Baking-Modus aus, um sicherzustellen, dass die Lightmaps erfolgreich generiert werden. Ab Qt 6.4 wird erwartet, dass Anwendungen so strukturiert sind, dass die mit Lightmaps versehene Szene als erste Ansicht angezeigt wird oder dass die betreffende Szene mit einem Qt QML Viewer wie dem Tool „
qml“ geladen werden kann. Sobald das Baking abgeschlossen ist – dessen Fortschritt über die Konsolen-/Debug-Ausgabe verfolgt werden kann –, wird die Anwendung beendet. - Führen Sie die Szene (Anwendung) normal aus, um zu sehen, wie sie mit den geladenen Lightmaps aussieht. Anschließend kann die Feinabstimmung beginnen:
- Bei einigen Modellen ist es sinnvoll, den Wert für „ texelsPerUnit “ vom Standardwert auf einen kleineren Wert zu reduzieren. Dies gilt insbesondere für die integrierten Primitive und alle Objekte mit ausreichend einfacher Geometrie. Dies führt zu kleineren Lightmaps und schnelleren Baking-Zeiten. Beim ersten Baking sollte der Standardwert ausreichend sein; der Wert kann anschließend angepasst werden.
- Das Lightmapper-Objekt bietet zahlreiche Einstellungen mit sinnvollen Standardwerten, doch es ist nicht unwahrscheinlich, dass einige davon angepasst werden müssen, um den Erwartungen der Designer zu entsprechen. Beispielsweise lassen sich „ samples “ und „ bounces “ ändern, um die Qualität der indirekten Beleuchtung zu beeinflussen, während „ indirectLightFactor “ es ermöglicht, den Beitrag der indirekten Beleuchtung stärker hervorzuheben. Treten Artefakte auf, insbesondere im Bereich von Schatten, kann „ bias “ feinjustiert werden.
- Die Rauschunterdrückung der generierten Lightmaps ist unerlässlich. Die indirekte Beleuchtung wird mittels Path Tracing berechnet, was je nach Anzahl der verwendeten „ samples “ zu verrauschten Bildern führt. Eine Erhöhung der Sample-Anzahl reduziert das Rauschen, verlängert jedoch die für die Erzeugung der Lightmap benötigte Zeit. Unabhängig von der Sample-Anzahl ist es fast immer sinnvoll, einen Denoiser auf die generierten Lightmaps anzuwenden, bei denen es sich um 32-Bit-RGBA-Gleitkomma-Bilder handelt, die in einer Binärdatei gespeichert sind.
Ab Qt 6.5 wird über die „ DebugView “ eine interaktive Laufzeitlösung bereitgestellt. Unter „Tools“ befindet sich nun eine Schaltfläche, die beim Anklicken den Baking-Prozess auslöst. Es erscheint ein Fenster, das den aktuellen Fortschritt anzeigt. Zum Abbrechen können Sie entweder auf die Schaltfläche „Abbrechen“ klicken oder dieses Fenster schließen. Nach Abschluss des Vorgangs wird die Lightmap-Binärdatei im aktuellen Verzeichnis gespeichert.
Rauschunterdrückung
Nachfolgend finden Sie ein Beispiel einer Cornell-Box-Szene, die zunächst mit der Lightmap gerendert wurde, die mit 256 „ samples “ und maximal 3 „ bounces “ gebacken wurde. Im zweiten Beispiel wurde die erzeugte Bilddatei entrauscht, und die Ergebnisse sehen deutlich besser aus, da das Rauschen größtenteils beseitigt wurde.
Original

Rauschunterdrückung

Die Rauschunterdrückung erfolgt automatisch bei jeder gebackenen Lightmap. Wenn sich im Arbeitsverzeichnis eine bereits gebackene Lightmap-Datei mit dem Parameter „ .raw “ befindet, ist es möglich, nur die Rauschunterdrückung durchzuführen, indem man im Menü „ DebugView “ auf die Schaltfläche „ Denoise “ klickt. Die Rauschunterdrückung kann auch durch Aufruf der Anwendung mit dem Argument „ --denoise-lightmaps “ erfolgen. Um die Stärke der Rauschunterdrückung anzupassen, kann die Eigenschaft „ denoiseSigma “ verwendet werden.
Lightmap-UVs
Lightmap-UV-Koordinaten verwenden nicht dieselben UV-Daten wie bei der regulären Texturierung. Beim Rendern mit Lightmaps werden beim Abtasten der Lightmap weder die UV0- noch die UV1-Daten vom Renderer verwendet. Stattdessen gibt es im Mesh einen zusätzlichen, dedizierten UV-Kanal, der UV-Diagramme enthält, die in einer für die Zwecke des Lightmappings geeigneten Weise angeordnet sind. Dies beinhaltet das Vermeiden von Überlappungen und das Einfügen von Auffüllbereichen an geeigneten Stellen. Bei regulären UV-Daten gibt es keine derartigen Anforderungen, und man möchte möglicherweise durchaus dieselben U- und V-Koordinaten für mehr als einen Scheitelpunkt verwenden.
Der Vorgang der Erzeugung eines geeigneten UV-Satzes wird als „Lightmap-UV-Unwrapping“ bezeichnet. Qt führt diesen Vorgang beim Baking von Lightmaps durch und speichert das resultierende Mesh in der Lightmaps-Datei, sodass für die generierte Lightmap stets ein kompatibles Mesh geladen und verwendet wird. Das bedeutet: Wenn ein Modell stets gebackene Beleuchtung verwendet, muss die Quell-Mesh-Datei nicht zusammen mit der Anwendung ausgeliefert werden.
Größe der Lightmap-Textur
Für jedes Modell, einschließlich aller seiner Teilmeshes, ermittelt der Lightmap-Baking-Prozess während der Phase der Lightmap-UV-Generierung eine geeignete Lightmap-Texturgröße. Dies hat Auswirkungen auf Qualität, Leistung und Ressourcenverbrauch (sowohl auf der Festplatte als auch im Arbeitsspeicher).
Die Standardeinstellung ist oft geeignet und erfordert keine Anpassung, insbesondere bei Modellen mit mittlerer bis hoher Komplexität.
Bei sehr einfachen Modellen kann es jedoch sinnvoll sein, die Größe manuell zu reduzieren, da eine kleinere Lightmap-Größe immer noch visuell ansprechende Ergebnisse liefern kann, während die Verringerung der Asset-Größe (Lightmap-Bild) sowohl Festplattenspeicher als auch Arbeitsspeicher spart. Setzen Sie dazu den Wert „ texelsPerUnit “ auf eine entsprechend kleine Zahl. Die tatsächliche Breite und Höhe der Lightmap werden dann – abhängig von der Größe und der Geometrie des Modells – so angepasst, dass die Texel-Dichte möglichst nahe an den Wert „ texelsPerUnit “ herankommt.
Wenn Sie den Wert ändern, sollten Sie die Lightmaps immer neu berechnen und die Ergebnisse visuell überprüfen, um die Auswirkungen der geänderten Lightmap-Größe zu bewerten.
Verwendung von Lightmaps zur Laufzeit
Eigenschaften und Typen, die bei der Verwendung der vorab berechneten Lightmaps zur Laufzeit relevant sind:
Sobald das Baking erfolgreich abgeschlossen ist, greift die Anwendung bei normalem Start (ohne festgelegtes Befehlszeilenargument oder Umgebungsvariable) nun auf die generierten Lightmap-Bilder zurück und rendert sie korrekt – was erst nach dem ersten Baking der Lightmaps möglich ist. Falls gewünscht, kann die Anwendung diese an einem anderen Speicherort ablegen oder sie über das Qt-Ressourcensystem als Teil der ausführbaren Datei mitliefern. Dies wird durch die Eigenschaft ` source ` aktiviert.
Am Beispiel des oben genannten Beispielcodes mit der Kugel und den vier Rechtecken erzeugt der Baking-Vorgang eine Datei „ lightmaps.bin “, die alle gebackenen Meshes und Lightmaps enthält. Die Anwendung muss diese Datei an dem unter „ source “ angegebenen Speicherort bereitstellen, damit sie von der Engine gefunden werden kann.
Siehe auch „Qt Quick 3D – Beispiel für gebackene Lightmaps “ und „Qt Quick 3D – SSGI-Lightmap-Beispiel“.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.