This page provides an architectural overview of Godot's rendering system: the RenderingServer public API, the RenderingDevice GPU abstraction, scene culling, viewport management, and the available rendering pipelines. It covers how these layers connect from scene node updates down to GPU command submission.
For details on how the RenderingServer API is organized and what it manages (cameras, instances, environments, etc.), see RenderingServer (7.1). For the low-level GPU command abstraction and driver implementations, see RenderingDevice & Drivers (7.2). For the specific forward rendering pipelines, see Scene Rendering Pipelines (7.3). For shader compilation, see Shader Language & Compiler (7.4). For the OpenGL compatibility backend, see GLES3 Backend (7.5). For display and window management, see Display Server (7.6).
Godot's rendering system is organized into four tiers:
| Tier | Role | Key Classes |
|---|---|---|
| Public API | Scene-facing interface | RenderingServer, RenderingServerDefault |
| Scene Backend | Culling, viewport management | RendererSceneCull, RendererViewport, RendererCanvasCull |
| Pipeline | 3D scene rendering algorithms | RenderForwardClustered, RenderForwardMobile |
| GPU Abstraction | Cross-API GPU commands | RenderingDevice, RenderingDeviceDriver, RenderingDeviceGraph |
Architecture Diagram: Rendering System Layers
Sources: servers/rendering/rendering_server_default.h47-95 servers/rendering/renderer_viewport.h servers/rendering/renderer_scene_cull.h servers/rendering/renderer_rd/renderer_scene_render_rd.h57-60 servers/rendering/rendering_device.h61-70 servers/rendering/rendering_device_graph.h servers/rendering/rendering_device_driver.h
RenderingServer (defined in servers/rendering/rendering_server.h) is the abstract singleton API for all rendering operations. The concrete implementation is RenderingServerDefault in servers/rendering/rendering_server_default.h
RenderingServerDefault can run on a dedicated render thread. It uses a CommandQueueMT to marshal calls from the main thread to the render thread. The macros ASYNC_COND_PUSH, ASYNC_COND_PUSH_AND_RET, and ASYNC_COND_PUSH_AND_SYNC control whether a call is pushed asynchronously, synchronously with return, or with synchronization:
Thread::get_caller_id() == server_thread, the call is executed inline.command_queue and dispatched on the render thread.The call_on_render_thread(Callable) method (exposed to scripting) allows user code to safely access RenderingDevice internals from the render thread.
Thread dispatch flow:
Sources: servers/rendering/rendering_server_default.h80-120 servers/rendering/rendering_device.cpp53-55
All rendering objects (meshes, textures, lights, materials, cameras, viewports, etc.) are identified by RID handles. Resources are created with *_create() methods that return an RID and freed with free_rid(). The RID is an opaque pointer; there is no reference counting. The scene system (e.g., MeshInstance3D) holds RIDs and calls the appropriate RenderingServer functions with them.
RendererViewport (in servers/rendering/renderer_viewport.h) manages all active viewports. Each frame, RenderingServerDefault::_draw() calls into RendererViewport, which iterates viewports in topological order (children before parents) via _sort_active_viewports().
For each active viewport, RendererViewport dispatches:
RendererCanvasCull for canvas itemsRendererSceneCull::render_scene() for 3D worldsXRServer interface when in XR mode3D render buffers (RenderSceneBuffersRD) are configured per-viewport including resolution, MSAA settings, and 3D scaling mode. The method _configure_3d_render_buffers() in servers/rendering/renderer_viewport.cpp132-200 handles scaling mode selection and fallback logic (e.g., MetalFX → FSR2 → bilinear if a mode is unavailable).
Per-frame viewport dispatch:
Sources: servers/rendering/renderer_viewport.cpp94-200 servers/rendering/renderer_viewport.h
RendererSceneCull (in servers/rendering/renderer_scene_cull.h) is responsible for:
DynamicBVH) of all scene instances per scenarioA scenario is a container for all 3D visual objects. Each 3D instance (INSTANCE_MESH, INSTANCE_LIGHT, INSTANCE_REFLECTION_PROBE, etc.) must be placed in a scenario to be rendered. When two instances overlap spatially, _instance_pair() in servers/rendering/renderer_scene_cull.cpp174-297 is called to establish the relationship (e.g., a light paired with a mesh marks the mesh's lighting dirty flag).
During render_scene(), the BVH is queried against the camera frustum. Visible instances are sorted and passed to RendererSceneRender::render_scene() as PagedArray<RenderGeometryInstance*>.
Occlusion culling is supported via RendererSceneOcclusionCull (pluggable). Physics interpolation is handled via update_interpolation_tick() and update_interpolation_frame().
Sources: servers/rendering/renderer_scene_cull.cpp67-296 servers/rendering/renderer_scene_cull.h
RenderingDevice (alias RD) in servers/rendering/rendering_device.h is the cross-platform GPU API. It is a RenderingDeviceCommons subclass exposed to GDScript for advanced use.
| Area | Description |
|---|---|
| Buffer management | uniform_buffer_create, storage_buffer_create, buffer_update, buffer_copy |
| Texture management | texture_create, texture_update, texture_copy |
| Shader management | shader_compile_spirv_from_source, shader_create_from_bytecode |
| Framebuffer management | framebuffer_create, framebuffer_get_format |
| Pipeline management | render_pipeline_create, compute_pipeline_create |
| Draw lists | draw_list_begin, draw_list_bind_render_pipeline, draw_list_draw, draw_list_end |
| Compute lists | compute_list_begin, compute_list_dispatch, compute_list_end |
| Staging buffers | Internal upload/download CPU↔GPU staging with triple-buffered blocks |
| Raytracing | blas_create, tlas_create, acceleration_structure_build (optional feature) |
RenderingDeviceGraph (in servers/rendering/rendering_device_graph.h) is an internal command recorder that:
RENDER_GRAPH_REORDER)SECONDARY_COMMAND_BUFFERS_PER_FRAME)Each GPU resource has a ResourceTracker that tracks current usage (RESOURCE_USAGE_* flags). When a resource transitions between uses (e.g., render target → shader input), the graph inserts the necessary barrier automatically.
RenderingDevice class relationships:
Sources: servers/rendering/rendering_device.h61-210 servers/rendering/rendering_device_graph.h servers/rendering/rendering_device_driver.h
The RenderingDeviceDriver abstract class (in servers/rendering/rendering_device_driver.h) is implemented for each supported graphics API.
| Driver Class | File | API | Platforms |
|---|---|---|---|
RenderingDeviceDriverVulkan | drivers/vulkan/rendering_device_driver_vulkan.cpp | Vulkan | Linux, Android, Windows |
RenderingDeviceDriverD3D12 | drivers/d3d12/rendering_device_driver_d3d12.cpp | Direct3D 12 | Windows |
RenderingDeviceDriverMetal | drivers/metal/rendering_device_driver_metal.cpp | Metal | macOS, iOS |
Each driver maps RenderingDevice's API-agnostic types to the native API. For example, RD::DataFormat values are mapped to VkFormat in drivers/vulkan/rendering_device_driver_vulkan.cpp92-130 and to DXGI_FORMAT in drivers/d3d12/rendering_device_driver_d3d12.cpp118-300
Shader compilation produces SPIR-V, which is then:
A RenderingContextDriver (abstract) handles surface creation and swapchain management per platform, sitting above the OS windowing layer provided by DisplayServer.
Sources: drivers/vulkan/rendering_device_driver_vulkan.cpp1-130 drivers/d3d12/rendering_device_driver_d3d12.cpp60-120 drivers/metal/rendering_device_driver_metal.h
Two pipelines are available for the RenderingDevice-based backend (referred to as the "RD backend"). Both inherit from RendererSceneRenderRD in servers/rendering/renderer_rd/renderer_scene_render_rd.h
Class: RenderForwardClustered in servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
Designed for desktop targets. Features:
Framebuffer configurations are assembled on-demand via RenderBufferDataForwardClustered in servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp50-260 with textures for specular, normal/roughness, VoxelGI, velocity (motion vectors), and VRS.
Class: RenderForwardMobile in servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
Designed for mobile/tile-based GPUs. Key differences from clustered:
fill_push_constant_instance_indices() in servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp82-154).DATA_FORMAT_A2B10G10R10_UNORM_PACK32 color format to enable AFBC compression on Mali GPUs._render_buffers_can_be_storage() returns false).Pipeline selection and pass modes:
Sources: servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp301-680 servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp746-900 servers/rendering/renderer_rd/renderer_scene_render_rd.h
Shaders in the RD backend go through the following stages:
#include support via ShaderIncludeDBglslang (module glslang) via shader_compile_spirv_from_source() in servers/rendering/rendering_device.cpp200-212shader_compile_binary_from_spirv() → shader_create_from_bytecode()draw_list_bind_render_pipeline()Pipelines for scene shaders (SceneShaderForwardClustered, SceneShaderForwardMobile) are keyed by a PipelineKey struct containing framebuffer format, vertex format, specialization constants, and pass version. An ubershader fallback path is used when a specialized pipeline is not yet compiled, allowing background pipeline compilation without hitching.
Sources: servers/rendering/rendering_device.cpp200-218 servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp495-537
A separate RendererCompositorGLES3 path exists for the gl_compatibility rendering method. This backend uses OpenGL ES 3 and does not use RenderingDevice. It is selected when the project setting rendering/renderer/rendering_method is "gl_compatibility". Scaling modes that require RenderingDevice (FSR2, MetalFX) fall back to bilinear in this mode, as enforced in servers/rendering/renderer_viewport.cpp152-155
See GLES3 Backend (7.5) for details.
The RenderingServer API groups methods by object type. All methods use RID handles.
| Prefix | Object Type | Examples |
|---|---|---|
texture_* | GPU textures | texture_2d_create, texture_update |
shader_* | Shaders | shader_create, shader_set_default_texture_parameter |
material_* | Materials | material_create, material_set_shader, material_set_param |
mesh_* | Mesh geometry | mesh_create, mesh_add_surface |
instance_* | Scene instances | instance_create, instance_set_base, instance_set_scenario |
camera_* | Cameras | camera_create, camera_set_perspective, camera_set_transform |
canvas_* / canvas_item_* | 2D canvas | canvas_create, canvas_item_add_rect, canvas_item_add_texture_rect |
viewport_* | Viewports | viewport_create, viewport_set_size, viewport_set_scenario |
environment_* | Environments | environment_create, environment_set_sky, environment_set_ssao |
light_* | Lights | directional_light_create, omni_light_create, light_set_color |
reflection_probe_* | Reflection probes | reflection_probe_create, reflection_probe_set_resolution |
scenario_* | Scenarios | scenario_create, scenario_set_environment |
Sources: doc/classes/RenderingServer.xml1-30 servers/rendering/rendering_server_default.h131-200
The RSG (RenderingServerGlobals) namespace provides typed accessors to the active sub-systems:
| Symbol | Type | Role |
|---|---|---|
RSG::texture_storage | RendererTextureStorage* | Texture and render target management |
RSG::mesh_storage | RendererMeshStorage* | Mesh and surface data |
RSG::light_storage | RendererLightStorage* | Lights, shadows, lightmaps |
RSG::material_storage | RendererMaterialStorage* | Materials and shaders |
RSG::particles_storage | RendererParticlesStorage* | CPU/GPU particle systems |
RSG::camera_attributes | RendererCameraAttributes* | DOF, exposure |
RSG::scene | RendererSceneCull* | 3D scene culling |
RSG::canvas | RendererCanvasCull* | 2D canvas culling |
RSG::rasterizer | RendererCompositor* | Active compositor/backend |
RD::get_singleton() | RenderingDevice* | Global GPU device |
Sources: servers/rendering/rendering_server_default.h132-145 servers/rendering/renderer_scene_cull.cpp35-40
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.