Godot 3D Essentials (4.x)
Assemble a working 3D scene: transforms, camera, lights, environment/post, materials, and
GridMap blockouts. Targets Godot 4.7.
When to use
- Use when starting or fixing a 3D scene: positioning a
Camera3D, adding lights, setting
up a WorldEnvironment (sky, ambient, tonemap, glow/SSAO), assigning materials, or
building levels with GridMap.
When not to use: writing spatial shaders → godot-shaders; 3D physics bodies and
raycasts → godot-physics; character animation blending → godot-animation; full FPS
template → the fps-shooter genre skill.
Core workflow
- Everything 3D is a
Node3D with a Transform3D (position, rotation basis, scale).
Move with global_position, rotate with rotate_y(angle) or look_at(target).
- Add a
Camera3D. Mark it current (or call make_current()); set fov, near,
far. Parent it to a rig/pivot for orbit or follow cameras.
- Light the scene. A
DirectionalLight3D is the sun; OmniLight3D/SpotLight3D are
local. Enable shadows per light. Without lights and ambient, surfaces render black.
- Add a
WorldEnvironment with an Environment resource: background (sky/color),
ambient light, tonemap, and post (glow, SSAO, fog, adjustments).
- Give meshes materials (
StandardMaterial3D or a ShaderMaterial) on
MeshInstance3D.
- Block out levels with
GridMap, which places MeshLibrary items on a 3D grid
(the 3D analog of a tilemap).
Patterns
1. A follow camera (third-person, smoothed)
extends Camera3D
@export var target: Node3D
@export var offset := Vector3(0, 4, 8)
@export var smooth := 6.0
func _physics_process(delta: float) -> void:
if target == null:
return
var desired := target.global_position + offset
global_position = global_position.lerp(desired, smooth * delta) # smooth follow
look_at(target.global_position, Vector3.UP) # face the target
2. Sun + environment in code
func _ready() -> void:
var sun := DirectionalLight3D.new()
sun.rotation_degrees = Vector3(-45, -30, 0)
sun.shadow_enabled = true
add_child(sun)
var we := WorldEnvironment.new()
var env := Environment.new()
env.background_mode = Environment.BG_SKY
env.sky = Sky.new()
env.sky.sky_material = ProceduralSkyMaterial.new()
env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
env.tonemap_mode = Environment.TONE_MAPPER_FILMIC
env.glow_enabled = true
we.environment = env
add_child(we)
3. Assign a StandardMaterial3D from code
func tint_mesh(mesh: MeshInstance3D, color: Color) -> void:
var mat := StandardMaterial3D.new()
mat.albedo_color = color
mat.metallic = 0.0
mat.roughness = 0.6
mat.emission_enabled = true
mat.emission = color * 0.3
mesh.material_override = mat # overrides the mesh's surface materials
4. Place tiles into a GridMap
@onready var grid: GridMap = $GridMap # cell_size + mesh_library set in the editor
func build_floor(width: int, depth: int, item_id: int) -> void:
for x in width:
for z in depth:
# set_cell_item(Vector3i cell, int item, orientation = 0)
grid.set_cell_item(Vector3i(x, 0, z), item_id)
Pitfalls
- Scene renders black → no lights and no ambient. Add a
DirectionalLight3D and/or a
WorldEnvironment with ambient/sky. New scenes have neither by default.
- No camera / wrong camera. If nothing shows, no
Camera3D is current. Set
current = true or make_current(); only one camera renders per viewport.
- Confusing local vs global transforms.
position/rotation are relative to the
parent; global_position/global_transform are world space. Mixing them under a rotated
parent gives surprising results. look_at uses global coordinates.
- Scaling physics/lights. Non-uniform
scale on a Node3D distorts child collisions
and lights; prefer scaling the mesh asset or using uniform scale.
- Forgetting
from/up in look_at. look_at(target, up) — a target equal to the
node's position, or an up parallel to the look direction, produces NaNs/flips.
- GridMap with no
MeshLibrary places nothing. Create a MeshLibrary (from scenes)
and assign it; set_cell_item(cell, -1) clears a cell.
- HDR/glow too strong → check
tonemap_mode and glow thresholds; raw emissive values
bloom hard under filmic tonemapping.
References
- For Transform3D math, camera projection modes, light/shadow params, the full
Environment/post-processing options,
MeshLibrary creation, and ReflectionProbe/
LightmapGI lighting, read references/scene-and-environment.md.
Related skills
godot-physics — 3D bodies, areas, and raycasts.
godot-shaders — spatial shaders for custom 3D surfaces.
godot-animation — AnimationTree for 3D characters.
camera-systems — third-person orbit / first-person look rigs, framing, and collision.
performance-optimization — keep 3D scenes within frame budget (draw calls, lights, LOD).
fps-shooter — composes 3D movement, input, and AI into a game.
1---
2name: godot-3d-essentials
3description: >
4 Set up a Godot 4.7 3D scene: Node3D transforms, Camera3D, lighting
5 (DirectionalLight3D/OmniLight3D), WorldEnvironment for sky/ambient/tonemap/post,
6 MeshInstance3D materials, and GridMap for tile-based 3D levels. Use when building
7 a 3D scene in a Godot project, placing cameras/lights, configuring environment and
8 post-processing, or working with Node3D/.tscn 3D content and GridMap.
9---
10
11# Godot 3D Essentials (4.x)
12
13Assemble a working 3D scene: transforms, camera, lights, environment/post, materials, and
14`GridMap` blockouts. Targets **Godot 4.7**.
15
16## When to use
17
18- Use when starting or fixing a 3D scene: positioning a `Camera3D`, adding lights, setting
19 up a `WorldEnvironment` (sky, ambient, tonemap, glow/SSAO), assigning materials, or
20 building levels with `GridMap`.
21
22**When *not* to use:** writing spatial shaders → `godot-shaders`; 3D physics bodies and
23raycasts → `godot-physics`; character animation blending → `godot-animation`; full FPS
24template → the `fps-shooter` genre skill.
25
26## Core workflow
27
281. **Everything 3D is a `Node3D`** with a `Transform3D` (position, rotation basis, scale).
29 Move with `global_position`, rotate with `rotate_y(angle)` or `look_at(target)`.
302. **Add a `Camera3D`.** Mark it `current` (or call `make_current()`); set `fov`, `near`,
31 `far`. Parent it to a rig/pivot for orbit or follow cameras.
323. **Light the scene.** A `DirectionalLight3D` is the sun; `OmniLight3D`/`SpotLight3D` are
33 local. Enable shadows per light. Without lights and ambient, surfaces render black.
344. **Add a `WorldEnvironment`** with an `Environment` resource: background (sky/color),
35 ambient light, tonemap, and post (glow, SSAO, fog, adjustments).
365. **Give meshes materials** (`StandardMaterial3D` or a `ShaderMaterial`) on
37 `MeshInstance3D`.
386. **Block out levels with `GridMap`**, which places `MeshLibrary` items on a 3D grid
39 (the 3D analog of a tilemap).
40
41## Patterns
42
43### 1. A follow camera (third-person, smoothed)
44
45```gdscript
46extends Camera3D
47
48@export var target: Node3D
49@export var offset := Vector3(0, 4, 8)
50@export var smooth := 6.0
51
52func _physics_process(delta: float) -> void:
53 if target == null:
54 return
55 var desired := target.global_position + offset
56 global_position = global_position.lerp(desired, smooth * delta) # smooth follow
57 look_at(target.global_position, Vector3.UP) # face the target
58```
59
60### 2. Sun + environment in code
61
62```gdscript
63func _ready() -> void:
64 var sun := DirectionalLight3D.new()
65 sun.rotation_degrees = Vector3(-45, -30, 0)
66 sun.shadow_enabled = true
67 add_child(sun)
68
69 var we := WorldEnvironment.new()
70 var env := Environment.new()
71 env.background_mode = Environment.BG_SKY
72 env.sky = Sky.new()
73 env.sky.sky_material = ProceduralSkyMaterial.new()
74 env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
75 env.tonemap_mode = Environment.TONE_MAPPER_FILMIC
76 env.glow_enabled = true
77 we.environment = env
78 add_child(we)
79```
80
81### 3. Assign a StandardMaterial3D from code
82
83```gdscript
84func tint_mesh(mesh: MeshInstance3D, color: Color) -> void:
85 var mat := StandardMaterial3D.new()
86 mat.albedo_color = color
87 mat.metallic = 0.0
88 mat.roughness = 0.6
89 mat.emission_enabled = true
90 mat.emission = color * 0.3
91 mesh.material_override = mat # overrides the mesh's surface materials
92```
93
94### 4. Place tiles into a GridMap
95
96```gdscript
97@onready var grid: GridMap = $GridMap # cell_size + mesh_library set in the editor
98
99func build_floor(width: int, depth: int, item_id: int) -> void:
100 for x in width:
101 for z in depth:
102 # set_cell_item(Vector3i cell, int item, orientation = 0)
103 grid.set_cell_item(Vector3i(x, 0, z), item_id)
104```
105
106## Pitfalls
107
108- **Scene renders black** → no lights and no ambient. Add a `DirectionalLight3D` and/or a
109 `WorldEnvironment` with ambient/sky. New scenes have neither by default.
110- **No camera / wrong camera.** If nothing shows, no `Camera3D` is `current`. Set
111 `current = true` or `make_current()`; only one camera renders per viewport.
112- **Confusing local vs global transforms.** `position`/`rotation` are relative to the
113 parent; `global_position`/`global_transform` are world space. Mixing them under a rotated
114 parent gives surprising results. `look_at` uses global coordinates.
115- **Scaling physics/lights.** Non-uniform `scale` on a `Node3D` distorts child collisions
116 and lights; prefer scaling the mesh asset or using uniform scale.
117- **Forgetting `from`/`up` in `look_at`.** `look_at(target, up)` — a target equal to the
118 node's position, or an `up` parallel to the look direction, produces NaNs/flips.
119- **GridMap with no `MeshLibrary`** places nothing. Create a `MeshLibrary` (from scenes)
120 and assign it; `set_cell_item(cell, -1)` clears a cell.
121- **HDR/glow too strong** → check `tonemap_mode` and glow thresholds; raw emissive values
122 bloom hard under filmic tonemapping.
123
124## References
125
126- For Transform3D math, camera projection modes, light/shadow params, the full
127 Environment/post-processing options, `MeshLibrary` creation, and `ReflectionProbe`/
128 `LightmapGI` lighting, read `references/scene-and-environment.md`.
129
130## Related skills
131
132- `godot-physics` — 3D bodies, areas, and raycasts.
133- `godot-shaders` — spatial shaders for custom 3D surfaces.
134- `godot-animation` — `AnimationTree` for 3D characters.
135- `camera-systems` — third-person orbit / first-person look rigs, framing, and collision.
136- `performance-optimization` — keep 3D scenes within frame budget (draw calls, lights, LOD).
137- `fps-shooter` — composes 3D movement, input, and AI into a game.