Lighting is the single biggest factor separating amateur 3D scenes from production-quality ones. In Godot 4, the WorldEnvironment node is your control center for everything from ambient sky color to tone mapping, fog, and screen-space effects. Get it wrong and even the best geometry looks flat. Get it right and even simple meshes look photoreal. This guide walks through the complete environment lighting pipeline — from node setup to custom sky shaders to PBR calibration.
Understanding WorldEnvironment and the Environment Resource
The WorldEnvironment node wraps an Environment resource that controls the global rendering context for your scene. Every 3D scene should have one. If you don't add one explicitly, Godot uses a default environment defined in your project settings — but relying on defaults will make your scenes look inconsistent across platforms.
To get started:
- Add a
WorldEnvironmentnode to the root of your 3D scene. - In the Inspector, create a new
Environmentresource. - Set
Background Modeto Sky for realistic outdoor scenes, or Color for controlled indoor environments.
The Environment resource controls six major subsystems: background, ambient light, reflected sky, fog, glow, and tone mapping. Each one interacts with the others — changing tone mapping will affect perceived ambient brightness, for example. Work top-down through the property groups rather than tweaking values at random.
Key properties to set first:
| Property | Recommended Starting Value | Notes |
|---|---|---|
| Background Mode | Sky | Use Color for interior-only scenes |
| Ambient Light Source | Sky | Picks up sky color for ambient |
| Ambient Energy | 0.3–0.8 | Lower = harder shadows |
| Tone Mapper | ACES | Filmic response, industry standard |
| Exposure | 1.0 | Adjust once lights are placed |
| Glow Enabled | true | Enable after other settings are stable |
Configuring the Sky and DirectionalLight3D
![]()
Godot 4 ships with a ProceduralSkyMaterial that generates a physically-based atmosphere at runtime. It's fast, configurable, and produces accurate Rayleigh scattering without any texture assets. Pair it with a DirectionalLight3D rotated to match your sun position, and your scene immediately reads as outdoor lighting.
# Procedural sky setup via code
var env = Environment.new()
var sky_mat = ProceduralSkyMaterial.new()
sky_mat.sky_top_color = Color(0.1, 0.4, 0.8) # zenith blue
sky_mat.sky_horizon_color = Color(0.6, 0.7, 0.9) # haze
sky_mat.ground_bottom_color = Color(0.2, 0.15, 0.1)
sky_mat.sun_angle_max = 25.0
sky_mat.sun_curve = 0.12
var sky = Sky.new()
sky.sky_material = sky_mat
env.background_mode = Environment.BG_SKY
env.sky = sky
env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
env.ambient_light_energy = 0.5
env.tonemap_mode = Environment.TONE_MAPPER_ACES
$WorldEnvironment.environment = env
The DirectionalLight3D must match your sky's sun position for the lighting to read as coherent. Rotate the light on the X axis (around -30° to -60° for a high midday sun, -5° to -15° for golden hour) and rotate on Y to set the sun's compass direction. Enable shadow_enabled = true and set directional_shadow_mode to PARALLEL_SPLIT for exterior scenes with large view distances.
Shadow quality settings for exterior scenes:
DirectionalLight3D
shadow_enabled: true
directional_shadow_mode: PARALLEL_SPLIT
directional_shadow_split_1: 0.1
directional_shadow_split_2: 0.25
directional_shadow_split_3: 0.5
directional_shadow_max_distance: 200.0
directional_shadow_pancake_size: 20.0
Lower directional_shadow_pancake_size eliminates shadow pop-in on objects near the camera. Adjust directional_shadow_max_distance based on your scene scale.
Writing a Custom Sky Shader
![]()
ProceduralSkyMaterial covers most use cases, but for stylized games — cel-shaded, low-poly, or sci-fi — you'll want a custom sky shader. Godot 4's ShaderMaterial assigned to a Sky resource gives you full control over sky appearance and can sample from panoramic HDRIs or synthesize any look from scratch.
Create a new Shader (type: sky) and assign it via ShaderMaterial to a Sky resource:
shader_type sky;
uniform vec3 top_color : source_color = vec3(0.05, 0.1, 0.3);
uniform vec3 horizon_color : source_color = vec3(0.5, 0.6, 0.8);
uniform vec3 sun_color : source_color = vec3(1.0, 0.9, 0.6);
uniform float sun_size = 0.02;
uniform float horizon_sharpness = 4.0;
void sky() {
float horizon = pow(1.0 - abs(EYEDIR.y), horizon_sharpness);
vec3 base = mix(top_color, horizon_color, horizon);
// Sun disc
float sun_dist = distance(EYEDIR, LIGHT0_DIRECTION);
float sun = smoothstep(sun_size, sun_size * 0.5, sun_dist);
base = mix(base, sun_color, sun);
COLOR = base;
}
The LIGHT0_DIRECTION built-in automatically tracks your first DirectionalLight3D, so rotating the light also moves the sun disc in your shader — no manual synchronization needed.
For HDRI-based environments (best for product visualization or realistic interiors), assign a PanoramaSkyMaterial and load a 4K HDRI as the panorama texture. Set Energy to control exposure and Filter to Linear Mipmap for smooth sampling at all viewing angles.
Tuning PBR Materials for Your Lighting Setup
Environment lighting only looks correct if your PBR materials are calibrated to physically-based ranges. In Godot 4's StandardMaterial3D:
- Metallic: 0.0 (dielectric) or 1.0 (metal). Avoid mid-range values — real materials are almost never partially metallic.
- Roughness: 0.0 (mirror) to 1.0 (fully diffuse). Most real surfaces sit between 0.3–0.9.
- Specular: 0.5 for most dielectrics (water = 0.25, gemstones = 0.6–0.8). Don't change this without a physical reference.
A common mistake is brightening ambient energy to compensate for dark-looking PBR materials. The real fix is calibrating roughness and albedo, not over-driving ambient light. Albedo values for common surfaces:
| Surface | Linear Albedo (approx) |
|---|---|
| Fresh snow | 0.9–0.95 |
| Concrete | 0.3–0.5 |
| Dry soil | 0.1–0.2 |
| Dark asphalt | 0.04–0.08 |
| Raw metal (iron) | See metallic map |
To preview material response against your sky, use Godot's built-in SDFGI (Signed Distance Field Global Illumination) for indirect bounce lighting. Enable it in Environment > SDFGI. It approximates multi-bounce GI in real time and dramatically improves how PBR materials read under environment light.
Performance Optimization for Environment Lighting
Environment effects are often the biggest performance bottleneck in 3D scenes. Apply these settings before shipping:
- Disable SDFGI on mobile: it's GPU-heavy. Use
ReflectionProbenodes instead for key reflective surfaces. - Cap glow iterations:
Glow > Levelsshould be 4–5 max on mid-range hardware. - Use SSR only where needed: Screen-Space Reflections (
SSR) are expensive. Restrict to key surfaces (floors, water) using aReflectionProbefor everything else. - Set fog start distance carefully: Fog adds fill pass cost. Start it beyond your primary action zone.
- Bake GI where possible: For static geometry,
LightmapGIbaked light removes runtime GI cost entirely while still reading correctly against yourWorldEnvironmentsky color.
Exporting platform-specific project settings? Override environment properties per-platform using Godot's feature tags in Project Settings > Rendering. Set SDFGI to disabled for Android/iOS builds without changing your desktop scene files.
Next Steps: Pre-Built Assets and HDRI Resources
Building environment lighting from scratch takes time. If you need production-ready 3D assets that are already calibrated for PBR lighting — characters, props, environments, and vehicles — browse the library at BitSoul Marketplace. Every asset is tested for correct metallic/roughness values and ships in GLB format ready for Godot 4 import.
For HDRIs, Poly Haven (polyhaven.com) provides free CC0 panoramic images in 4K and 8K. Download a .hdr file, import into Godot with Compress Mode: VRAM Uncompressed, assign to a PanoramaSkyMaterial, and you have studio-grade reference lighting in under five minutes.
PBR-correct environment lighting is not optional — it's the foundation that makes every asset in your scene look credible. Set it up right once, calibrate your materials to it, and your scenes will look significantly more polished than projects that treat lighting as an afterthought. Check BitSoul Marketplace for assets built to these same PBR standards and ready to drop into your Godot 4 project today.
Need drop-in assets for this workflow? Grab the 82-model Vehicle Bundle on the BitSoul marketplace and drop them straight into your project.