godotengine/godot
Rendering server
Purpose
The rendering server is the engine's largest subsystem — by file count, by lines of code, and by the breadth of its public API. It owns visual state (textures, meshes, materials, lights, environments, instances), schedules culling/visibility, and translates high-level scene draw requests into GPU commands. It supports two architectures in the same source tree: a "RenderingDevice" path that runs on Vulkan, Direct3D 12, and Metal, and a "Compatibility" path that talks directly to OpenGL ES 3.
Directory layout
servers/rendering/
├── rendering_server.{cpp,h} Public API (~197 KB cpp + ~73 KB h)
├── rendering_server_default.{cpp,h} Default implementation that owns global storage
├── rendering_server_globals.h Pointers to the active RasterizerCanvas/Scene/Storage
├── rendering_method.h Abstract interface every "renderer" implements
├── rendering_device.{cpp,h} Vendor-neutral GPU device (~452 KB cpp)
├── rendering_device_driver.{cpp,h} C++ interface drivers implement (Vulkan/D3D12/Metal)
├── rendering_device_graph.{cpp,h} DAG-based command scheduler with auto-barriers (~160 KB)
├── rendering_device_commons.{cpp,h} Shared enums, descriptor structs
├── rendering_device_binds.{cpp,h} Script-binding-friendly wrappers around RenderingDevice
├── rendering_context_driver.{cpp,h} Surface/context creation per platform/driver
├── rendering_shader_container.cpp Shader binary cache + reflection
├── shader_compiler.cpp Godot Shader Language → SPIR-V/Metal/HLSL
├── shader_language.cpp Godot Shader Language parser/AST/types (~406 KB cpp)
├── shader_preprocessor.cpp #include / #define handling
├── shader_types.cpp Built-in shader uniforms per pass type
├── renderer_canvas_cull.{cpp,h} 2D culling and dispatch (~101 KB cpp)
├── renderer_canvas_render.{cpp,h} Abstract 2D draw surface implemented per backend
├── renderer_compositor.{cpp,h} Owns the active rasterizer trio
├── renderer_geometry_instance.{cpp,h} Per-instance render data
├── renderer_scene_cull.{cpp,h} 3D scene culling (~183 KB cpp)
├── renderer_scene_occlusion_cull.{cpp,h} Occlusion culling
├── renderer_scene_render.{cpp,h} Abstract 3D scene render path
├── renderer_viewport.{cpp,h} Per-viewport state (camera, env, post-process, MSAA, FSR/TAA)
├── rendering_light_culler.{cpp,h} Light volume culling
├── instance_uniforms.{cpp,h} Per-instance shader uniforms
├── renderer_rd/ Renderer running on RenderingDevice
│ ├── forward_clustered/ Forward+ clustered renderer (desktop)
│ ├── forward_mobile/ Mobile forward renderer (tile-friendly)
│ ├── effects/ SSAO, SSIL, SSR, bloom, tonemap, FSR, copy, blur, taa, vrs
│ ├── environment/ Sky, GI (SDFGI/VoxelGI/LightmapGI dispatch), fog, GI probes
│ ├── shaders/ Cluster builder, depth reduce, GI passes, post-process
│ └── storage_rd/ RD-backed mesh/material/texture/light storage
├── storage/ Backend-agnostic helpers (utility code shared by storages)
├── dummy/ Headless / `--display-driver headless` no-op renderer
└── environment/ Default ambient/sky resourcesThe gles3 "Compatibility" renderer lives in drivers/gles3/ (it predates the RD architecture) and implements the same RendererCompositor / RendererCanvasRender / RendererSceneRender interface set as renderer_rd. See Drivers — Graphics.
Renderer methods
Three rendering methods ship; one is selected per project (rendering/renderer/rendering_method for desktop, rendering/renderer/rendering_method.mobile for mobile, .web for web):
| Method | Where | Backend | Use case |
|---|---|---|---|
| Forward+ | renderer_rd/forward_clustered/ |
Vulkan/D3D12/Metal | Desktop high-end; clustered forward shading, SDFGI, VoxelGI, SSAO/SSIL/SSR, TAA |
| Mobile | renderer_rd/forward_mobile/ |
Vulkan/D3D12/Metal | Tiled GPUs (mobile, integrated); fewer features for performance |
| Compatibility | drivers/gles3/ |
OpenGL ES 3 | Older hardware, web (WebGL2), low-power mobile |
The RD backends share most code (clustered builder, light culler, storage, effects), differing mainly in the lighting/shading pipeline. The Compatibility backend is a separate implementation, but it implements the same interfaces so the high-level RenderingServer API is identical to the consumer.
Public API surface
RenderingServer (rendering_server.h, ~73 KB header) is one of the largest public APIs in Godot. It groups methods into:
- Texture:
texture_2d_create,texture_2d_layered_create,texture_3d_create,texture_proxy_create,texture_replace, plus format/size queries. - Mesh / MultiMesh:
mesh_create,mesh_add_surface,mesh_set_blend_shape_count,multimesh_create,multimesh_set_buffer. - Shader / Material:
shader_create,shader_set_code,material_create,material_set_param,material_set_shader. - Skeleton:
skeleton_create,skeleton_allocate_data,skeleton_bone_set_transform. - Light / Reflection / Decal / Lightmap / VoxelGI: factory + setter methods for each.
- Instance:
instance_create,instance_set_base,instance_set_transform,instance_geometry_*(per-instance overrides). - Scenario:
scenario_create,scenario_set_environment,scenario_set_camera_attributes(a "scenario" is the 3D world a viewport renders). - Canvas / CanvasItem / CanvasLayer: 2D draw command lists.
- Viewport:
viewport_create,viewport_set_size,viewport_set_msaa_3d,viewport_set_use_taa,viewport_set_use_hdr_2d,viewport_attach_to_screen. - Environment / Sky / Compositor:
environment_create,environment_set_sky,environment_set_ssao,compositor_create,compositor_effect_create. - Particles: GPU particles infrastructure (
particles_create,particles_set_emission_transform,particles_set_amount). - GI:
voxel_gi_*,lightmap_*,sdfgi_*API. - Global shader uniforms:
global_shader_parameter_*for cross-shader values. - Render frame info / debug:
get_rendering_info,get_video_adapter_*,request_frame_drawn_callback.
How a frame flows
sequenceDiagram
participant Tree as SceneTree
participant Viewport as Viewport
participant RS as RenderingServer (WrapMT)
participant RSD as RenderingServerDefault
participant Cull as renderer_scene_cull
participant Method as Forward+ / Mobile / Compat
participant RD as RenderingDevice / GLES3
participant GPU
Tree->>Viewport: draw()
Viewport->>RS: viewport_draw / canvas_draw
RS->>RSD: enqueue
Note over RS,RSD: queued via WrapMT in MT mode
RSD->>Cull: cull scene + lights + decals + reflection probes
Cull->>Method: render_scene(...)
Method->>RD: build framebuffers, bind pipelines, draw
RD->>GPU: vkCmd* / D3D12 / Metal / GL calls
GPU-->>RD: frame complete
RD-->>Method: signal
Method-->>RSD: frame done
RSD-->>Viewport: notify draw callbacksThe split is intentional: renderer_scene_cull.cpp is renderer-agnostic and decides what is visible (frustum + occlusion + LOD + lightmap relevance + cluster classification). renderer_rd/forward_clustered/ (or forward_mobile/, or drivers/gles3/) takes that visibility set and turns it into draw calls.
RenderingDevice and the command graph
RenderingDevice is Vulkan-shaped: textures are RD::TextureFormat + RD::TextureView; pipelines are explicit (RD::PipelineRasterizationState, depth/stencil, multisample); barriers are derived automatically by RenderingDeviceGraph.
RenderingDeviceGraph (rendering_device_graph.cpp, ~160 KB) builds a per-frame command DAG so the engine can:
- Re-order non-dependent commands.
- Insert pipeline/image-memory barriers only where needed.
- Schedule async compute on graphics queues that support it.
Both renderer_rd/forward_* and the engine's compute effects (FSR, SSAO, bloom, GI passes) submit through this graph.
Shaders
Godot has its own shader language (an opinionated GLSL dialect with shader_type, render_mode, semantic uniform hints, and shader includes). The pipeline:
- Preprocess (
shader_preprocessor.cpp) — handles#includedirectives,#defines, conditional compilation. - Parse (
shader_language.cpp, ~406 KB) — produces an AST + symbol table; reportsshader_warningspershader_warnings.cpp. - Compile (
shader_compiler.cpp, ~60 KB) — emits SPIR-V (RD path) or GLSL/ESSL (Compatibility path); the SPIR-V is then cross-compiled to Metal MSL or HLSL by the driver. - Cache (
rendering_shader_container.cpp) — binary form is cached so re-used shaders skip recompilation.
Built-in shaders for clustered building, GI, post-process, and 2D primitives live in renderer_rd/shaders/. They are converted to C++ string constants by glsl_builders.py at build time.
shader_types.cpp enumerates the built-in uniforms, varyings, and modes available per shader type (canvas_item, spatial, particles, sky, fog).
2D rendering
renderer_canvas_cull.cpp (~101 KB) is the 2D analogue of the 3D culling pipeline:
- Walks
CanvasItemtrees, building draw command lists. - Resolves Z-ordering and clip rects.
- Hands batches to the active
RendererCanvasRender(RD or GLES3). - Implements 2D lights (
Light2D) via additive passes against shadow textures.
The 2D path supports custom shaders (canvas_item shader type), 2D shadow occluders (light_occluder_2d), back buffer copy (back_buffer_copy.cpp in scene/2d), and full multi-pass effects through CanvasGroup/SubViewport.
Key abstractions
| Abstraction | File | Role |
|---|---|---|
RenderingServer |
servers/rendering_server.h |
Public API |
RenderingServerDefault |
servers/rendering/rendering_server_default.h |
Owns the active RendererCompositor |
RendererCompositor |
servers/rendering/renderer_compositor.h |
Owns scene + canvas + storage trio |
RendererSceneRender |
servers/rendering/renderer_scene_render.h |
Per-backend 3D draw |
RendererCanvasRender |
servers/rendering/renderer_canvas_render.h |
Per-backend 2D draw |
RenderingMethod |
servers/rendering/rendering_method.h |
Forward+ / Mobile / Compat method abstraction |
RenderingDevice |
servers/rendering/rendering_device.h |
Vendor-neutral GPU API |
RenderingDeviceGraph |
servers/rendering/rendering_device_graph.h |
Command DAG + barrier scheduling |
RasterizerScene (per-backend) |
renderer_rd/forward_*/ and drivers/gles3/rasterizer_scene_gles3.cpp |
Concrete render-path implementation |
ShaderCompiler |
servers/rendering/shader_compiler.h |
Godot Shader Language → SPIR-V/GLSL |
Integration points
- Inputs: scene tree calls
RenderingServer::*fromViewport,MeshInstance3D,Light3D,Sprite2D,Camera3D, etc., to set up RIDs and update transforms. - Outputs: the active
RenderingDeviceDriver(Vulkan, D3D12, Metal) executes the GPU commands; or in Compatibility, the GLES3 driver issues GL calls. - The compositor effect API (
Compositor,CompositorEffect) lets games inject custom RD passes. Seescene/resources/compositor.h.
Entry points for modification
- Adding a new post-process effect → drop a shader into
renderer_rd/shaders/effects/, build a wrapper inrenderer_rd/effects/, and call it from the renderer's_render_buffers_post_processpath. Or, ship it as aCompositorEffectresource so users can attach it from GDScript. - Adding a new built-in shader uniform →
shader_types.cpp+ the relevant shader template. - Tweaking culling →
renderer_scene_cull.cppis monolithic but well-commented; profile with the engine's built-in profiler before changes. - Adding a new backend → implement
RenderingDeviceDriverfor the new GPU API and a newRenderingContextDriver. The Vulkan/D3D12/Metal drivers are the templates.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.