Interne Rendering-Architektur
Diese Seite gibt einen Überblick über das interne Renderer-Design von Godot 4. Sie gilt nicht für frühere Godot-Versionen.
Das Ziel dieser Seite ist es, Design-Entscheidungen zu dokumentieren, die getroffen wurden, um der Godot Design-Philosophie am besten zu entsprechen, und gleichzeitig einen Ausgangspunkt für neue Rendering-Mitwirkende zu bieten.
Wenn Sie Fragen zu Rendering-Interna haben, die hier nicht beantwortet werden, können Sie diese im #rendering-Kanal des Godot Mitwirkenden-Chat stellen.
Bemerkung
Wenn Sie Schwierigkeiten haben, die Konzepte auf dieser Seite zu verstehen, ist es empfehlenswert, ein OpenGL-Tutorial wie LearnOpenGL durchzuarbeiten.
Modern low-level APIs (Vulkan/Direct3D 12/Metal) require intermediate knowledge of higher-level APIs (OpenGL/Direct3D 11) to be used effectively. Thankfully, contributors rarely need to work directly with low-level APIs. Godot's renderers are built entirely on OpenGL and RenderingDevice, which is our abstraction over Vulkan/Direct3D 12/Metal.
Rendering-Methoden
Forward+
Dies ist ein Vorwärts-Renderer, der einen Cluster-Ansatz für die Beleuchtung verwendet.
Bei der Cluster-Beleuchtung wird ein Compute-Shader verwendet, um die Lichter in einem an 3D-Frustum-ausgerichteten Raster zu gruppieren. Zur Renderzeit können die Pixel dann nachsehen, welche Lichter die Rasterzelle, in der sie sich befinden, beeinflussen, und nur Lichtberechnungen für Lichter durchführen, die dieses Pixel beeinflussen könnten.
Dieser Ansatz kann die Rendering-Performance auf Desktop-Hardware erheblich beschleunigen, ist aber auf mobilen Geräten wesentlich weniger effizient.
Mobile
This is a forward renderer that uses a traditional single-pass approach to lighting. Internally, it is called Forward Mobile.
Gedacht für mobile Plattformen, kann aber auch auf Desktop-Plattformen ausgeführt werden. Diese Rendering-Methode ist für eine gute Performance auf mobilen GPUs optimiert. Mobile GPUs haben eine ganz andere Architektur als Desktop-GPUs, da sie besondere Einschränkungen in Bezug auf den Batterieverbrauch, die Wärmeentwicklung und die allgemeine Bandbreitenbeschränkung beim Lesen und Schreiben von Daten haben. Auch Compute-Shader werden nur sehr eingeschränkt oder gar nicht unterstützt. Infolgedessen verwendet der Mobile-Renderer ausschließlich rasterbasierte Shader (Fragment/Vertex).
Im Gegensatz zu Desktop-GPUs führen mobile GPUs Tile-Based-Rendering durch. Anstatt das gesamte Bild als eine Einheit zu rendern, wird das Bild in kleinere Kacheln unterteilt, die in den schnelleren internen Speicher der mobilen GPU passen. Jede Kachel wird gerendert und dann in die Zieltextur geschrieben. Dies geschieht alles automatisch durch den Grafiktreiber.
Das Problem ist, dass dies zu Engpässen in unserem traditionellen Ansatz führt. Beim Desktop-Rendering werden zunächst alle undurchsichtigen Geometrien gerendert, dann der Hintergrund bearbeitet, dann die transparenten Geometrien und schließlich die Nachbearbeitung. Jeder Durchlauf muss das aktuelle Ergebnis in den Kachel-Speicher einlesen, seine Operationen durchführen und es dann wieder herausschreiben. Anschließend warten wir, bis alle Kacheln fertiggestellt sind, bevor wir zum nächsten Durchgang übergehen.
Die erste wichtige Änderung im mobilen Renderer ist, dass der mobile Renderer nicht die RGBA16F-Texturformate verwendet, die der Desktop-Renderer verwendet. Stattdessen wird ein R10G10B10A2 UNORM-Texturformat verwendet. Dadurch halbiert sich die erforderliche Bandbreite und es ergeben sich weitere Verbesserungen, da die mobile Hardware häufig für 32-Bit-Formate optimiert ist. Der Nachteil ist, dass der mobile Renderer aufgrund der reduzierten Präzision und der Maximalwerte in den Farbdaten nur begrenzte HDR-Fähigkeiten hat.
Die zweite wichtige Änderung ist die Verwendung von Sub-Passes, wann immer dies möglich ist. Mit Sub-Passes können wir die Rendering-Schritte Ende-zu-Ende pro Kachel durchführen und so den Overhead einsparen, der durch das Lesen von und Schreiben in die Kacheln zwischen den einzelnen Rendering-Durchgängen entsteht. Die Möglichkeit, Sub-Passes zu verwenden, wird durch die Unmöglichkeit eingeschränkt, benachbarte Pixel zu lesen, da wir auf die Arbeit innerhalb einer einzelnen Kachel beschränkt sind.
Diese Einschränkung von Subpasses führt dazu, dass Features wie Glow und Schärfentiefe nicht effizient implementiert werden können. Ähnlich verhält es sich, wenn aus der Bildschirmtextur oder der Tiefentextur gelesen werden muss, so dass das Rendering-Ergebnis vollständig ausgeschrieben werden muss, was die Möglichkeit der Verwendung von Subpasses einschränkt. Wenn solche Features aktiviert sind, wird eine Mischung aus Sub-Passes und normalen Passes verwendet, und diese Features führen zu einem erheblichen Performanceverlust.
On desktop platforms, the use of sub-passes won't have any impact on performance. However, this rendering method can still perform better than Forward+ in simple scenes thanks to its lower complexity and lower bandwidth usage. This is especially noticeable on low-end GPUs, integrated graphics or in VR applications.
Da diese Rendering-Methode auf das einfache Rendering ausgerichtet ist, bietet sie keine High-End-Rendering-Features wie SDFGI und Volumetrischer Nebel und Nebelvolumen. Verschieden Nachbearbeitungseffekte sind ebenfalls nicht verfügbar.
Kompatibilität
Bemerkung
This is the only rendering method available when using the OpenGL driver. This rendering method is not available when using Vulkan, Direct3D 12, or Metal.
This is a traditional (non-clustered) forward renderer. Internally, it is called GL Compatibility. It's intended for old GPUs that don't have Vulkan support, but still works very efficiently on newer hardware. Specifically, it is optimized for older and lower-end mobile devices. However, many optimizations carry over making it a good choice for older and lower-end desktop as well.
Wie der mobile Renderer verwendet auch der Kompatibilitäts-Renderer eine R10G10B10A2 UNORM-Textur für das 3D-Rendering. Im Gegensatz zum mobilen Renderer werden die Farben im sRGB-Format gespeichert, sodass keine HDR-Unterstützung vorhanden ist. Dadurch wird ein Tonemapping-Durchgang überflüssig und wir können die Textur mit niedrigeren Bits ohne erhebliches Banding verwenden.
Der Kompatibilitäts-Renderer verwendet einen traditionellen Forward-Single-Pass-Ansatz zum Zeichnen von Objekten mit Lichtern, aber er verwendet einen Multi-Pass-Ansatz, um Lichter mit Schatten zu zeichnen. Insbesondere kann er im ersten Durchgang mehrere Lichter ohne Schatten und bis zu einem DirectionalLight3D mit Schatten zeichnen. In jedem weiteren Durchgang kann er bis zu einem OmniLight3D, einem SpotLight3D und einem DirectionalLight3D mit Schatten zeichnen. Lichter mit Schatten wirken sich anders auf die Szene aus als Lichter ohne Schatten, da die Beleuchtung im sRGB-Raum und nicht im linearen Raum gemischt wird. Dieser Unterschied in der Beleuchtung wirkt sich auf das Aussehen der Szene aus und muss bei der Gestaltung von Szenen für den Kompatibilitätsrenderer berücksichtigt werden.
Given its low-end focus, this rendering method does not provide high-end rendering features (even less so compared to Mobile). Most post-processing effects are not available.
Warum kein verzögertes Rendering?
Forward Rendering bietet im Allgemeinen einen besseren Kompromiss zwischen Performance und Flexibilität, insbesondere wenn ein Cluster-Ansatz für die Beleuchtung verwendet wird. Verzögertes Rendering kann zwar in einigen Fällen schneller sein, ist aber auch weniger flexibel und erfordert die Verwendung von Hacks, um MSAA nutzen zu können. Da Spiele mit einem weniger realistischen Grafikstil sehr von MSAA profitieren können, haben wir uns bei Godot 4 (wie bei Godot 3) für Forward Rendering entschieden.
Allerdings werden Teile des Vorwärtsrenderers mit einem verzögerten Ansatz ausgeführt, um einige Optimierungen zu erreichen, wenn dies möglich ist. Dies gilt insbesondere für VoxelGI und SDFGI.
Für die Zukunft ist die Entwicklung eines "geclusterten verzögerten Renderers" geplant. Dieser Renderer könnte in Situationen verwendet werden, in denen die Performance gegenüber der Flexibilität im Vordergrund steht.
Rendering-Treiber
Godot 4 unterstützt die folgenden Grafik-APIs:
Vulkan
Dies ist der Haupttreiber in Godot 4, auf den der größte Teil der Entwicklung ausgerichtet ist.
Vulkan 1.0 ist als Basis erforderlich, wobei optionale Vulkan 1.1- und 1.2-Features verwendet werden, wenn sie verfügbar sind. volk wird als Vulkan-Loader verwendet, und Vulkan Memory Allocator wird für die Speicherverwaltung verwendet.
Sowohl Forward+ als auch Mobile Rendering-Methoden werden bei Verwendung des Vulkan-Treibers unterstützt.
Vulkan Kontexterstellung:
Direct3D 12-Kontexterstellung:
Direct3D 12
Wie Vulkan zielt auch der Direct3D 12-Treiber nur auf moderne Plattformen ab. Er ist sowohl für Windows als auch für die Xbox konzipiert (während Vulkan nicht direkt auf der Xbox verwendet werden kann).
Sowohl die Forward+ als auch die Mobile-Rendering-Methoden können mit Direct3D 12 verwendet werden.
Core-Shader werden gemeinsam mit dem Vulkan-Renderer genutzt. Shader werden von SPIR-V nach DXIL unter Verwendung von Mesa NIR (mehr Informationen) transpiliert.
Dieser Treiber ist noch experimentell und nur in Godot 4.3 und höher verfügbar. Während Direct3D 12 die Unterstützung von Direct3D-exklusiven Funktionen unter Windows 11 wie Fensteroptimierungen und Auto-HDR ermöglicht, wird Vulkan für die meisten Projekte weiterhin empfohlen. Weitere Informationen finden Sie im Pull Request, mit dem die Direct3D 12-Unterstützung eingeführt wurde.
Metal
Godot provides a native Metal driver that works on all Apple Silicon hardware (macOS ARM). Compared to using the MoltenVK translation layer, this is significantly faster, particularly in CPU-bound scenarios.
Both the Forward+ and Mobile Rendering-Methoden can be used with Metal.
Core-Shader are shared with the Vulkan renderer. Shaders are transpiled from GLSL to MSL using SPIRV-Cross.
Godot also supports Metal rendering via MoltenVK, which is used as a fallback when native Metal support is not available (e.g. on x86 macOS).
This driver is still experimental and only available in Godot 4.4 and later. See the pull request that introduced Metal support for more information.
OpenGL
Dieser Treiber verwendet OpenGL ES 3.0 und zielt auf ältere und Low-End-Geräte ab, die Vulkan nicht unterstützen. OpenGL 3.3 Core Profile wird auf Desktop-Plattformen verwendet, um diesen Treiber auszuführen, da die meisten Grafiktreiber auf dem Desktop OpenGL ES nicht unterstützen. WebGL 2.0 wird für Web-Exporte verwendet.
It is possible to use OpenGL ES 3.0 directly on desktop platforms
by passing the --rendering-driver opengl3_es command line argument, although this
will only work on graphics drivers that feature native OpenGL ES support (such
as Mesa).
Nur die Rendering-Methode Kompatibilität kann mit dem OpenGL-Treiber verwendet werden.
Core-Shader sind völlig anders als der Vulkan-Renderer.
Viele fortgeschrittene Funktionen werden von diesem Treiber nicht unterstützt, da er in erster Linie auf Low-End-Geräte ausgerichtet ist.
Zusammenfassung der Rendering-Treiber/Methoden
Die folgenden Kombinationen aus Rendering-API und Rendering-Methode sind derzeit möglich:
Vulkan + Forward+ (optionally through MoltenVK on macOS and iOS)
Vulkan + Mobile (optionally through MoltenVK on macOS and iOS)
Direct3D 12 + Forward+
Direct3D 12 + Mobile
Metal + Forward+
Metal + Mobile
OpenGL + Compatibility (optionally through ANGLE on Windows and macOS)
Jede Kombination hat ihre eigenen Einschränkungen und Performancemerkmale. Stellen Sie sicher, dass Sie Ihre Änderungen nach Möglichkeit mit allen Rendering-Methoden testen, bevor Sie einen Pull Request erstellen.
RenderingDevice-Abstraktion
Bemerkung
Der OpenGL-Treiber verwendet nicht die RenderingDevice-Abstraktion.
Um die Komplexität moderner Low-Level-Grafik-APIs besser handhabbar zu machen, verwendet Godot eine eigene Abstraktion namens RenderingDevice.
This means that when writing code for modern rendering methods, you don't actually use the Vulkan, Direct3D 12, or Metal APIs directly. While this is still lower-level than an API like OpenGL, this makes working on the renderer easier, as RenderingDevice will abstract many API-specific quirks for you. The RenderingDevice presents a similar level of abstraction as WebGPU.
Vulkan RenderingDevice-Implementierung:
Direct3D 12 RenderingDevice-Implementierung:
Metal RenderingDevice implementation:
Architektur der wichtigsten Rendering-Klassen
Dieses Diagramm zeigt die Struktur der Rendering-Klassen in Godot, einschließlich der RenderingDevice-Abstraktion:
Core-Shader
Während Shader in Godot-Projekten mit einer eigenen, von GLSL inspirierten Sprache geschrieben werden, werden Core-Shader direkt in GLSL geschrieben.
Diese Core-Shader werden zur Kompilierungszeit in die Editor- und Exportvorlagen-Binärdateien eingebettet. Um Änderungen an diesen GLSL-Shadern zu sehen, müssen Sie den Editor oder die Exportvorlagen-Binärdatei neu kompilieren.
Einige Material-Eigenschaften wie Height Mapping, Refraction und Proximity Fade sind nicht Teil der Core-Shader und werden im Standard-BaseMaterial3D stattdessen mit der Godot-Shader-Sprache (nicht GLSL) ausgeführt. Dies geschieht durch prozedurale Generierung des erforderlichen Shader-Codes in Abhängigkeit von den im Material aktivierten Features.
Konventionell werden Shader-Dateien mit _inc in ihrem Namen in andere GLSL-Dateien eingebunden, um die Wiederverwendung von Code zu verbessern. Um dies zu erreichen, wird die standardmäßige GLSL-Vorverarbeitung verwendet.
Warnung
Core-Material-Shader werden von jedem Material in der Szene verwendet - sowohl mit dem standardmäßigen BaseMaterial3D als auch mit benutzerdefinierten Shadern. Daher müssen diese Shader so einfach wie möglich gehalten werden, um Performanceprobleme zu vermeiden und sicherzustellen, dass die Shader-Kompilierung nicht zu langsam wird.
Wenn Sie if-Verzweigungen in einem Shader verwenden, kann die Performance sinken, da die VGPR-Nutzung im Shader steigt. Dies geschieht selbst dann, wenn alle Pixel in einem bestimmten Frame als true oder false ausgewertet werden.
Wenn Sie die #if-Präprozessorverzweigung verwenden, wird die Anzahl der benötigten Shader-Versionen in der Szene steigen. Im schlimmsten Fall kann das Hinzufügen eines einzigen booleschen #define die Anzahl der Shader-Versionen, die in einer bestimmten Szene kompiliert werden müssen, verdoppeln. In einigen Fällen können Vulkan-Spezialisierungskonstanten als schnellere (aber begrenztere) Alternative verwendet werden.
Das bedeutet, dass es eine hohe Hürde für das Hinzufügen neuer Built-in-Material-Eigenschaften in Godot gibt, sowohl in den Core-Shadern als auch in BaseMaterial3D. BaseMaterial3D kann zwar die dynamische Codegenerierung nutzen, um den Shader-Code nur dann einzubeziehen, wenn das Feature aktiviert ist, aber es müssen immer noch mehr Shader-Versionen generiert werden, wenn diese Features in einem Projekt verwendet werden. Dies kann dazu führen, dass die Shader-Kompilierung in komplexen 3D-Szenen stärker stottert.
Weitere Informationen finden Sie in den Blogbeiträgen The Shader Permutation Problem und Branching on a GPU.
Core-GLSL-Material-Shader:
Forward+: servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
Mobile: servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
Kompatibilität: drivers/gles3/shaders/scene.glsl
Material-Shader-Generierung:
Other GLSL shaders for Forward+ and Mobile rendering methods:
Andere GLSL-Shader für die Kompatibilitäts-Renderingmethode:
Trennung von 2D- und 3D-Rendering
Bemerkung
The following is only applicable in the Forward+ and Mobile rendering methods, not in Compatibility. Multiple Viewports can be used to emulate this when using the Compatibility renderer, or to perform 2D resolution scaling.
2D und 3D werden in getrennten Puffern gerendert, da das 2D-Rendering in Godot im LDR sRGB-Raum durchgeführt wird, während das 3D-Rendering den HDR linearen Raum verwendet.
Das für das 2D-Rendering verwendete Farbformat ist RGB8 (RGBA8, wenn die Property Transparent im Viewport aktiviert ist). Das 3D-Rendering verwendet einen 24-Bit-Tiefenpuffer mit normalisierten unsigned Integer oder 32-Bit-signed Float, wenn ein 24-Bit-Tiefenpuffer von der Hardware nicht unterstützt wird. Beim 2D-Rendering wird kein Tiefenpuffer verwendet.
Die Skalierung der 3D-Auflösung wird unterschiedlich durchgeführt, je nachdem, ob eine bilineare oder eine FSR 1.0-Skalierung verwendet wird. Bei bilinearer Skalierung wird kein spezieller Upscaling-Shader ausgeführt. Stattdessen wird die Textur des Viewports gestreckt und mit einem linearen Sampler angezeigt (wodurch die Filterung direkt in der Hardware erfolgt). Dies ermöglicht die Maximierung der Performance der bilinearen 3D-Skalierung.
Die Funktion configure() in RenderSceneBuffersRD ordnet die 2D/3D-Puffer neu zu, wenn sich die Auflösung oder Skalierung ändert.
Die dynamische Auflösungsskalierung wird noch nicht unterstützt, ist aber für ein künftiges Godot-Release geplant.
C++-Code für 2D- und 3D-Rendering-Bufferkonfiguration:
FSR 1.0:
2D-Rendering-Techniken
Das 2D-Lichtrendering wird in einem einzigen Durchgang durchgeführt, um eine bessere Performance bei großen Mengen von Lichtern zu ermöglichen.
All rendering methods feature 2D batching to improve performance, which is especially noticeable with lots of text on screen.
MSAA kann in 2D aktiviert werden, um ein "automatisches" Antialiasing für Linien und Polygone zu ermöglichen, aber FXAA hat keinen Einfluss auf das 2D-Rendering, da es berechnet wird, bevor das 2D-Rendering beginnt. Godots 2D-Zeichenmethoden wie der Line2D-Node oder einige CanvasItem draw_*()-Methoden bieten ihre eigene Art des Antialiasing basierend auf Triangle Strips und Vertex-Farben, die kein MSAA benötigen, um zu funktionieren.
Ein 2D-Signed Distance Field, das LightOccluder2D-Nodes im Viewport repräsentiert, wird automatisch erzeugt, wenn ein Benutzer-Shader es anfordert. Dies kann für verschiedene Effekte in benutzerdefinierten Shadern verwendet werden, z.B. für die 2D Global Illumination. Es wird auch zur Berechnung von Partikelkollisionen in 2D verwendet.
2D-SDF-GLSL-Shader:
3D-Rendering-Techniken
Batching und Instanziierung
In the Forward+ renderer, Vulkan instancing is used to group rendering of identical opaque or alpha-tested objects for performance. (Alpha-blended objects are never instanced.) This is not as fast as static mesh merging, but it still allows instances to be culled individually.
Licht-, Decal- und Reflexionsprobe-Rendering
Bemerkung
Decal rendering is currently not available in the Compatibility renderer.
The Forward+ renderer uses clustered lighting. This allows using as many lights as you want; performance largely depends on screen coverage. Shadow-less lights can be almost free if they don't occupy much space on screen.
Alle Rendering-Methoden unterstützen auch das gleichzeitige Rendering von bis zu 8 gerichteten Lichtern (wenn auch mit geringerer Schattenqualität, wenn mehr als ein Licht Schatten aktiviert hat).
The Mobile renderer uses a single-pass lighting approach, with a limitation of 8 OmniLights + 8 SpotLights affecting each Mesh resource (plus a limitation of 256 OmniLights + 256 SpotLights in the camera view). These limits are hardcoded and can't be adjusted in the project settings.
The Compatibility renderer uses a hybrid single-pass + multi-pass lighting approach. Lights without shadows are rendered in a single pass. Lights with shadows are rendered in multiple passes. This is required for performance reasons on mobile devices. As a result, performance does not scale well with many shadow-casting lights. It is recommended to only have a handful of lights with shadows in the camera frustum at a time and for those lights to be spread apart so that each object is only touched by 1 or 2 shadowed lights at a time. The maximum number of lights visible at once can be adjusted in the project settings.
Bei allen 3 Methoden sind Lichter ohne Schatten viel billiger als Lichter mit Schatten. Um die Performance zu verbessern, werden Lichter nur aktualisiert, wenn das Licht geändert wird oder wenn Objekte in seinem Radius geändert werden. Godot trennt derzeit nicht zwischen statischem und dynamischem Schattenrendering, aber dies ist für ein zukünftiges Release geplant.
Clustering is also used for reflection probes and decal rendering in the Forward+ renderer.
Shadow-Mapping
Both Forward+ and Mobile methods use PCF to filter shadow maps and create a soft penumbra. Instead of using a fixed PCF pattern, these methods use a vogel disk pattern which allows for changing the number of samples and smoothly changing the quality.
Godot also supports percentage-closer soft shadows (PCSS) for more realistic shadow penumbra rendering. PCSS shadows are limited to the Forward+ renderer as they're too demanding to be usable in the Mobile renderer. PCSS also uses a vogel-disk shaped kernel.
Darüber hinaus rotieren beide Shadow-Mapping-Techniken den Kernel auf einer pro-Pixel-Basis, um Unterabtastungsartefakte zu mildern.
The Compatibility renderer supports shadow mapping for DirectionalLight3D, OmniLight3D, and SpotLight3D lights.
Temporales Antialiasing
Bemerkung
Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
Godot verwendet eine benutzerdefinierte TAA-Implementierung, die auf der alten TAA-Implementierung der Spartan Engine basiert.
Temporales Antialiasing erfordert Bewegungsvektoren, um zu funktionieren. Wenn die Bewegungsvektoren nicht korrekt erzeugt werden, kommt es zu Geisterbildern, wenn sich die Kamera oder Objekte bewegen.
Die Bewegungsvektoren werden auf der GPU im Hauptmaterial-Shader erzeugt. Dazu wird der Vertex-Shader des vorherigen gerenderten Frames (mit der vorherigen Kameratransformation) zusätzlich zum Vertex-Shader des aktuellen gerenderten Frames ausgeführt und die Differenz zwischen beiden in einem Farbpuffer gespeichert.
Alternativ kann FSR 2.2 als Upscaling-Lösung verwendet werden, die auch einen eigenen Algorithmus für temporales Antialiasing bietet. FSR 2.2 ist auf der RenderingDevice-Abstraktion implementiert und verwendet nicht direkt den Referenzcode von AMD.
TAA-Resolve:
FSR 2.2:
Global Illumination
Bemerkung
VoxelGI and SDFGI are only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
LightmapGI baking is only available in the Forward+ and Mobile renderers, and can only be performed within the editor (not in an exported project). LightmapGI rendering is supported by the Compatibility renderer.
Godot unterstützt voxelbasiertes GI (VoxelGI), Signed Distance Field-GI (SDFGI), sowie Lightmap-Backen und -Rendering (LightmapGI). Diese Techniken können bei Bedarf gleichzeitig verwendet werden.
Lightmap baking happens on the GPU using Vulkan compute shaders. The GPU-based lightmapper is implemented in the LightmapperRD class, which inherits from the Lightmapper class. This allows for implementing additional lightmappers, paving the way for a future port of the CPU-based lightmapper present in Godot 3.x. This would allow baking lightmaps while using the Compatibility renderer.
C++-Code für Core GI:
scene/3d/voxel_gi.cpp - VoxelGI-Node
editor/plugins/voxel_gi_editor_plugin.cpp - Editor-UI für den VoxelGI-Node
Core GI GLSL Shader:
servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl
servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl - VoxelGI Debug-Draw-Modus
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl - SDFGI Kaskaden-Debug-Draw-Modus
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl - SDFGI Probes Debug-Draw-Modus
servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
C++-Code für Lightmapper:
scene/3d/lightmap_gi.cpp - LightmapGI-Node
editor/plugins/lightmap_gi_editor_plugin.cpp - Editor-UI für den LightmapGI-Node
scene/3d/lightmapper.cpp - abstrakte Klasse
modules/lightmapper_rd/lightmapper_rd.cpp - GPU-basierte Lightmapper-Implementierung
Lightmapper GLSL Shader:
Schärfentiefe
Bemerkung
Only available in the Forward+ and Mobile renderers, not the Compatibility renderer.
The Forward+ and Mobile renderers use different approaches to DOF rendering, with different visual results. This is done to best match the performance characteristics of the target hardware. In Forward+, DOF is performed using a compute shader. In Mobile, DOF is performed using a fragment shader (raster).
Es stehen Box-, Hexagon und Kreis-Bokeh-Formen zur Verfügung (vom schnellsten zum langsamsten). Die Schärfentiefe kann optional bei jedem Bild gejittert werden, um das Erscheinungsbild zu verbessern, wenn das temporale Antialiasing aktiviert ist.
C++-Code zu Schärfentiefe:
GLSL-Shader mit Schärfentiefe (Compute - verwendet für Forward+):
Depth of field GLSL shader (raster - used for Mobile):
Screen Space-Effekte (SSAO, SSIL, SSR, SSS)
Bemerkung
Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
The Forward+ renderer supports screen-space ambient occlusion, screen-space indirect lighting, screen-space reflections and subsurface scattering.
SSAO verwendet eine Implementierung, die von Intels ASSAO (konvertiert zu Vulkan) abgeleitet ist. SSIL ist von SSAO abgeleitet, um eine leistungsstarke indirekte Beleuchtung zu ermöglichen.
Wenn sowohl SSAO als auch SSIL aktiviert sind, werden Teile von SSAO und SSIL gemeinsam genutzt, um die Auswirkungen auf die Performance zu verringern.
SSAO und SSIL werden standardmäßig mit halber Auflösung ausgeführt, um die Performance zu verbessern. SSR wird immer mit halber Auflösung ausgeführt, um die Performance zu verbessern.
C++-Code für Screen Space-Effekte:
GSL-Shader für Screen Space Ambient Occlusion:
servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
GSL-Shader für Screen Space Indirect Lighting:
servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
GLSL-Shader für Screen Space Reflections:
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl
GLSL mit Subsurface Scattering:
Himmelsrendering
Siehe auch
Godot unterstützt die Verwendung von Shadern zum Rendern des Himmelshintergrunds. Die Radiance Map (die verwendet wird, um Umgebungslicht und Reflexionen für PBR-Materialien bereitzustellen) wird automatisch auf der Grundlage des Himmelsshaders aktualisiert.
Die SkyMaterial-Ressourcen wie ProceduralSkyMaterial, PhysicalSkyMaterial und PanoramaSkyMaterial erzeugen einen Built-in-Shader für das Himmelsrendering. Dies ist vergleichbar mit dem, was BaseMaterial3D für 3D-Szenenmaterialien bietet.
Eine detaillierte technische Implementierung findet sich im Artikel Custom sky shaders in Godot 4.0.
C++-Code für Himmelsrendering:
servers/rendering/renderer_rd/environment/sky.cpp - Himmelsrendering
scene/resources/sky.cpp - Himmelsressource (nicht zu verwechseln mit Himmelsrendering)
scene/resources/sky_material.cpp SkyMaterial-Ressourcen (verwendet in der Himmelsressource)
GLSL-Shader für Himmelsrendering:
Volumetrischer Nebel
Bemerkung
Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
Siehe auch
Godot unterstützt einen Frustum-aligned Voxel (Froxel)-Ansatz für das Rendern von volumetrischem Nebel. Im Gegensatz zu einem Post-Processing-Filter ist dieser Ansatz vielseitiger, da er mit jedem Lichttyp arbeiten kann. Nebel kann auch Shader für benutzerdefiniertes Verhalten verwenden, was die Animation des Nebels oder die Verwendung einer 3D-Textur zur Darstellung von Dichte ermöglicht.
Die FogMaterial-Ressource erzeugt einen Built-in-Shader für FogVolume-Nodes. Dies ist vergleichbar mit dem, was BaseMaterial3D für 3D-Szenenmaterialien bietet.
Eine ausführliche technische Erklärung finden Sie im Artikel Fog Volumes arrive in Godot 4.0.
C++-Code für volumetrischen Nebel:
servers/rendering/renderer_rd/environment/fog.cpp - Allgemeiner volumetrischer Nebel
scene/3d/fog_volume.cpp - FogVolume-Node
scene/resources/fog_material.cpp - FogMaterial-Ressource (verwendet von FogVolume)
GLSL Shader mit volumetrischem Nebel:
Occlusion Culling
While modern GPUs can handle drawing a lot of triangles, the number of draw calls in complex scenes can still be a bottleneck (even with Vulkan, Direct3D 12, and Metal).
Godot 4 supports occlusion culling to reduce overdraw (when the depth prepass is disabled) and reduce vertex throughput. This is done by rasterizing a low-resolution buffer on the CPU using Embree. The buffer's resolution depends on the number of CPU threads on the system, as this is done in parallel. This buffer includes occluder shapes that were baked in the editor or created at runtime.
Da komplexe Occluder die CPU stark belasten können, können gebackene Occluder bei der Erstellung im Editor automatisch vereinfacht werden.
Godot's occlusion culling doesn't support dynamic occluders yet, but OccluderInstance3D nodes can still have their visibility toggled or be moved. However, this will be slow when updating complex occluders this way. Therefore, updating occluders at runtime is best done only on simple occluder shapes such as quads or cuboids.
Dieser CPU-basierte Ansatz hat einige Vorteile gegenüber anderen Lösungen, wie z.B. Portalen und Räumen oder einer GPU-basierten Culling-Lösung:
Keine manuelle Einrichtung erforderlich (kann aber für optimale Performance manuell angepasst werden).
Keine Bildverzögerung, die in Zwischensequenzen bei Kameraschwenks problematisch ist, oder wenn sich die Kamera schnell hinter einer Wand bewegt.
Funktioniert bei allen Rendering-Treibern und -Methoden gleich, ohne unvorhersehbares Verhalten je nach Treiber oder GPU-Hardware.
Occlusion Culling wird durch die Registrierung von Occluder Meshes durchgeführt, was mit OccluderInstance3D-Nodes geschieht (die ihrerseits Occluder3D-Ressourcen verwenden). RenderingServer führt dann Occlusion Culling durch den Aufruf von Embree in RendererSceneOcclusionCull durch.
C++-Code für Occlusion-Culling:
Sichtbarkeits-Reichweite (LOD)
Godot unterstützt manuell erstellte hierarchisches Level of Detail (HLOD), wobei die Abstände vom Benutzer im Inspektor festgelegt werden.
In RenderingSceneCull sind es die Funktionen _scene_cull() und _render_scene(), in denen der Großteil der LOD-Bestimmung stattfindet. Jeder Viewport kann das gleiche Mesh mit unterschiedlichen LODs rendern (um ein korrektes Split-Screen-Rendering zu ermöglichen).
C++-Code zu Sichtbarkeits-Reichweite
Automatisches Mesh-LOD
Die ImporterMesh-Klasse wird für den 3D-Mesh-Import-Workflow im Editor verwendet. Ihre Funktion generate_lods() behandelt die Generierung mit der Bibliothek meshoptimizer.
Bei der LOD-Mesh-Generierung werden gleichzeitig auch Schatten-Meshes erzeugt. Dabei handelt es sich um Meshes, deren Vertices unabhängig von Glättung und Materialien verschweißt sind. Dies wird verwendet, um die Performance beim Rendern von Schatten zu verbessern, indem der für das Rendern von Schatten erforderliche Vertex-Durchsatz verringert wird.
Die Funktion _render_scene() der Klasse RenderingSceneCull bestimmt, welches Mesh-LOD beim Rendern verwendet werden soll. Jeder Viewport kann das gleiche Mesh mit unterschiedlichen LODs rendern (um ein korrektes Split-Screen-Rendering zu ermöglichen).
Das LOD des Meshes wird automatisch auf der Grundlage einer Bildschirmabdeckungsmetrik ausgewählt. Dabei werden Änderungen der Auflösung und des Kamerabildes berücksichtigt, ohne dass der Benutzer eingreifen muss. Der Schwellenwertmultiplikator kann in den Projekteinstellungen angepasst werden.
Um die Performance zu verbessern, wählen das Schatten-Rendering und das Reflection-Probe-Rendering auch ihre eigenen Mesh-LOD-Schwellenwerte (die sich vom Rendering der Hauptszene unterscheiden können).
C++-Code zu Mesh LOD-Erzeugung bei Import:
C++-Code zur Bestimmung von Mesh LOD: