The GLES3 backend is Godot's OpenGL ES 3.0 rendering path. It lives in drivers/gles3/ and implements the same abstract rendering interfaces as the RenderingDevice-based backends (Vulkan, D3D12, Metal), but targets lower-end hardware, mobile platforms, and embedded environments. This page covers the rasterizers, storage subsystems, material and shader management, and the GLSL shader structure specific to GLES3.
For the RenderingDevice-based backends (Vulkan, D3D12, Metal), see 7.2. For the forward clustered and forward mobile pipelines that run on RenderingDevice, see 7.3. For the shader language parser and compiler shared by all backends, see 7.4.
The GLES3 backend is composed of two rasterizers and a set of storage singletons.
Top-level class diagram:
Sources: drivers/gles3/rasterizer_scene_gles3.h1-200 drivers/gles3/rasterizer_canvas_gles3.h1-100 drivers/gles3/storage/material_storage.h1-100
RasterizerSceneGLES3RasterizerSceneGLES3 in drivers/gles3/rasterizer_scene_gles3.cpp implements RendererSceneRender. Its central responsibility is managing geometry instances, building render lists, and issuing OpenGL draw calls for 3D scenes.
RenderDataGLES3Every render call receives a RenderDataGLES3 struct (drivers/gles3/rasterizer_scene_gles3.h98-146) that carries:
| Field | Type | Purpose |
|---|---|---|
render_buffers | Ref<RenderSceneBuffersGLES3> | Render targets and intermediate textures |
cam_transform | Transform3D | Camera world transform |
cam_projection | Projection | Camera projection matrix |
view_count | uint32_t | Number of views (1 for mono, 2 for XR) |
instances | PagedArray<RenderGeometryInstance*>* | Visible geometry |
lights | PagedArray<RID>* | Active lights |
environment | RID | Current environment resource |
directional_light_count | uint32_t | How many directional lights |
luminance_multiplier | float | For physical light unit normalization |
Geometry is sorted into three render lists, typed by RenderListType:
| Constant | Value | Usage |
|---|---|---|
RENDER_LIST_OPAQUE | 0 | Opaque geometry |
RENDER_LIST_ALPHA | 1 | Transparent geometry |
RENDER_LIST_SECONDARY | 2 | Shadows and other auxiliary passes |
Passes are identified by PassMode:
PASS_MODE_COLOR / PASS_MODE_COLOR_TRANSPARENTPASS_MODE_SHADOWPASS_MODE_DEPTHPASS_MODE_MATERIALPASS_MODE_MOTION_VECTORSEach visible 3D object is represented as a GeometryInstanceGLES3, which caches resolved surface/material data as a linked list of GeometryInstanceSurface entries.
Geometry instance lifecycle:
Sources: drivers/gles3/rasterizer_scene_gles3.cpp56-511
GeometryInstanceSurface Pass FlagsWhen _geometry_instance_add_surface_with_material() creates a GeometryInstanceSurface, it computes flags that determine which render passes this surface participates in:
| Flag | Meaning |
|---|---|
FLAG_PASS_OPAQUE | Rendered in the opaque pass |
FLAG_PASS_ALPHA | Rendered in the alpha-transparent pass |
FLAG_PASS_DEPTH | Included in depth prepass |
FLAG_PASS_SHADOW | Contributes to shadow maps |
FLAG_USES_SCREEN_TEXTURE | Requires screen texture read |
FLAG_USES_DEPTH_TEXTURE | Requires depth texture read |
FLAG_USES_SHARED_SHADOW_MATERIAL | Shadow pass uses the default material instead of the object's material (optimization) |
FLAG_USES_STENCIL | Uses stencil buffer operations |
Sources: drivers/gles3/rasterizer_scene_gles3.cpp216-329
Sky resources are tracked via RasterizerSceneGLES3::Sky and managed with a dirty-list pattern identical to materials. The key steps are:
_setup_sky() — uploads directional light data to sky_globals.directional_light_buffer (UBO at SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION)._update_dirty_skys() — allocates GL_TEXTURE_CUBE_MAP radiance and raw radiance textures when a sky becomes dirty._draw_sky() — binds the sky shader version, sets uniforms (orientation, projection, time, fog parameters), and issues a full-screen draw.The sky shader is managed through material_storage->shaders.sky_shader, a SkyShaderGLES3 instance with modes MODE_BACKGROUND and MODE_CUBEMAP.
Sources: drivers/gles3/rasterizer_scene_gles3.cpp513-891
RasterizerCanvasGLES3RasterizerCanvasGLES3 in drivers/gles3/rasterizer_canvas_gles3.cpp implements 2D rendering for all CanvasItem-based nodes (sprites, polygons, text, particles in 2D).
canvas_render_items(p_to_render_target, p_item_list, p_modulate,
p_light_list, p_directional_light_list,
p_canvas_transform, ...)
The function executes the following steps each frame:
reset_canvas()._allocate_instance_data_buffer().state.light_uniforms[0..N] for directional lights, uploads to state.canvas_instance_data_buffers[...].light_ubo.state.light_uniforms slots.StateBuffer (screen transform, canvas transform, modulate, time, SDF params)._render_items() which batches draws and issues glDrawArraysInstanced or glDrawElements.The canvas renderer uses up to 3 in-flight instance data buffers (canvas_instance_data_buffers[3]), each guarded by a GLsync fence. This avoids stalling the CPU waiting for the GPU to finish a previous frame's data.
Sources: drivers/gles3/rasterizer_canvas_gles3.cpp107-390
The LightUniform struct is packed into a UBO at LIGHT_UNIFORM_LOCATION. Each entry holds:
position[2] — canvas-space positionmatrix[8] — 2x4 light transformshadow_matrix[8] — 2x4 shadow transformcolor[4], shadow_color[4]flags — blend mode and shadow filteratlas_rect[4] — texture atlas coordinatesSources: drivers/gles3/rasterizer_canvas_gles3.cpp144-318
GLES3::MaterialStorageGLES3::MaterialStorage in drivers/gles3/storage/material_storage.cpp manages the entire lifecycle from Godot's high-level shader source to compiled OpenGL programs and bound material data.
Material and shader data flow:
Sources: drivers/gles3/storage/material_storage.cpp1-200 drivers/gles3/storage/material_storage.h1-100
| Class | Shader Type | Backing GL shader |
|---|---|---|
SceneShaderData | shader_type spatial | SceneShaderGLES3 |
SkyShaderData | shader_type sky | SkyShaderGLES3 |
CanvasShaderData | shader_type canvas_item | CanvasShaderGLES3 |
Each ShaderData subclass implements set_code(), which runs the source through ShaderCompiler to produce GLSL, then compiles it into an OpenGL shader version.
Each MaterialData subclass (e.g., SceneMaterialData) holds:
ShaderDatauniform_set_updated dirty flagbind_uniforms() — uploads parameters to ubo:3next_pass — pointer to the next material pass RID for multi-pass rendering_fill_std140_variant_ubo_value() at drivers/gles3/storage/material_storage.cpp49 converts Godot Variant values into std140-layout bytes for each ShaderLanguage::DataType. Arrays use write_array_std140<T>() which pads each element to a 4-float stride as required by std140.
The GLES3 backend uses a custom .glsl format with two special header sections:
#[modes] — defines named compilation variants. Each mode becomes a separately linked GL program.#[specializations] — defines boolean #define flags resolved at shader-bind time, creating shader variants without full recompilation.drivers/gles3/shaders/scene.glsl)Modes:
| Mode | Defines | Purpose |
|---|---|---|
mode_color | (none) | Standard opaque color pass |
mode_color_instancing | USE_INSTANCING | Instanced color pass |
mode_depth | MODE_RENDER_DEPTH | Depth/shadow pass |
mode_depth_instancing | MODE_RENDER_DEPTH, USE_INSTANCING | Instanced depth pass |
Key specializations:
| Specialization | Default | Purpose |
|---|---|---|
DISABLE_LIGHT_DIRECTIONAL | false | Skip directional light computation |
DISABLE_LIGHT_OMNI | false | Skip omni light computation |
DISABLE_LIGHT_SPOT | false | Skip spot light computation |
USE_LIGHTMAP | false | Sample baked lightmap |
USE_MULTIVIEW | false | Stereo/XR rendering |
RENDER_SHADOWS | false | Shadow depth encoding |
SHADOW_MODE_PCF_5 | false | 5-tap PCF shadow filtering |
SHADOW_MODE_PCF_13 | false | 13-tap PCF shadow filtering |
APPLY_TONEMAPPING | true | Apply tonemapping in scene pass |
USE_ADDITIVE_LIGHTING | false | Additive light accumulation pass |
ADDITIVE_OMNI | false | Additive omni light sub-pass |
ADDITIVE_SPOT | false | Additive spot light sub-pass |
BASE_PASS | true | Base lighting pass (vs. additive) |
Sources: drivers/gles3/shaders/scene.glsl1-42
The scene vertex and fragment shaders use fixed binding points matching the SceneUniformLocation enum:
SceneData (at ubo:2) is a large struct that includes projection/view matrices, viewport size, ambient light color, fog parameters, z-near/far, shadow bias, and frame time.
Sources: drivers/gles3/shaders/scene.glsl179-237 drivers/gles3/rasterizer_scene_gles3.h64-96
drivers/gles3/shaders/canvas.glsl)The canvas shader has a single mode (mode_default) and is specialized via flags at bind time:
| Specialization | Purpose |
|---|---|
DISABLE_LIGHTING | Skip all light computation (true by default) |
USE_RGBA_SHADOWS | Use RGBA-encoded shadow depth (for mobile) |
USE_NINEPATCH | Enable nine-patch rect rendering |
USE_PRIMITIVE | Triangle/line primitive mode |
USE_ATTRIBUTES | Per-vertex attribute arrays (polygon rendering) |
USE_INSTANCING | Instanced 2D sprite rendering |
Instance data is packed into vertex attributes attrib_A through attrib_H at locations 8–15, carrying world transform, color, UV rect, source rect, flags, and light indices.
Sources: drivers/gles3/shaders/canvas.glsl1-90
drivers/gles3/shaders/sky.glsl)| Mode | Defines | Purpose |
|---|---|---|
mode_background | (none) | Draw sky into screen framebuffer |
mode_cubemap | USE_CUBEMAP_PASS | Render sky into cubemap face |
Specializations include USE_MULTIVIEW, USE_INVERTED_Y, and APPLY_TONEMAPPING.
Sources: drivers/gles3/shaders/sky.glsl1-20
Each storage class is a singleton in the GLES3 namespace and manages a specific resource type using RID_Owner allocators.
| Class | File | Manages |
|---|---|---|
GLES3::MeshStorage | drivers/gles3/storage/mesh_storage.cpp | Meshes, multimeshes, skeletons |
GLES3::TextureStorage | drivers/gles3/storage/texture_storage.cpp | Textures, render targets, texture atlas |
GLES3::LightStorage | drivers/gles3/storage/light_storage.cpp | Lights, shadow atlases, light instances |
GLES3::ParticlesStorage | drivers/gles3/storage/particles_storage.cpp | GPU particles, particle trails |
GLES3::MaterialStorage | drivers/gles3/storage/material_storage.cpp | Shaders, materials, global uniforms |
GLES3::Utilities | drivers/gles3/storage/utilities.cpp | Texture memory tracking, base type queries |
GLES3::Config | drivers/gles3/storage/config.cpp | Runtime GL capability flags and limits |
GLES3::ConfigConfig is queried throughout the backend for hardware limits, e.g.:
max_renderable_lights — caps get_max_lights_total()max_lights_per_object — caps GeometryInstanceGLES3::pair_light_instance()max_texture_image_units — used when binding atlas and shadow textures in canvas_render_items()Sources: drivers/gles3/rasterizer_scene_gles3.cpp78-84 drivers/gles3/rasterizer_canvas_gles3.cpp309-317
Effect helpers live in drivers/gles3/effects/:
| File | Class | Purpose |
|---|---|---|
effects/copy_effects.cpp | CopyEffects | Blit, copy, and downsample passes |
effects/cubemap_filter.cpp | CubemapFilter | Specular convolution for radiance maps |
effects/feed_effects.cpp | FeedEffects | Camera feed texture rendering |
effects/post_effects.cpp | PostEffects | Tonemapping, glow, adjustments |
These are invoked from RasterizerSceneGLES3 after the main geometry passes.
Sources: drivers/gles3/rasterizer_scene_gles3.cpp37-41
Several codepaths branch on RasterizerUtilGLES3::is_gles_over_gl() to accommodate differences between desktop OpenGL and GLES3:
glTexImage2D + glGenerateMipmap; GLES uses glTexStorage2D.glMapBufferRange with GL_MAP_UNSYNCHRONIZED_BIT; WebGL uses glBufferSubData (no explicit sync).Sources: drivers/gles3/rasterizer_scene_gles3.cpp588-617 drivers/gles3/rasterizer_canvas_gles3.cpp293-302
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.