Godot 3D 基础(4.x)
组装可用的 3D 场景:变换、摄像机、灯光、环境/后处理、材质以及 GridMap 灰盒块。目标为 Godot 4.7。
何时使用
- 在开始或修复 3D 场景时使用:定位
Camera3D、添加灯光、设置
WorldEnvironment(天空、环境光、色调映射、辉光/SSAO)、分配材质,或 使用 GridMap 构建关卡。
**何时*不*使用:** 编写空间着色器 → godot-shaders;3D 物理体和 射线检测 → godot-physics;角色动画混合 → godot-animation;完整 FPS 模板 → fps-shooter 类型技能。
核心工作流
- 所有 3D 内容都是
Node3D,带有Transform3D(位置、旋转基、缩放)。
使用 global_position 移动,使用 rotate_y(angle) 或 look_at(target) 旋转。
- 添加
Camera3D。 将其标记为current(或调用make_current());设置fov、near、
far。将其父级设为装置/枢轴,以制作环绕或跟随摄像机。
- 为场景打光。
DirectionalLight3D是太阳;OmniLight3D/SpotLight3D是
局部光源。为每个灯启用阴影。没有灯光和环境光时,表面会渲染为黑色。
- 添加
WorldEnvironment,带有Environment资源:背景(天空/颜色)、
环境光、色调映射和后处理(辉光、SSAO、雾、调整)。
- 为网格赋予材质(
StandardMaterial3D或ShaderMaterial),位于
MeshInstance3D。
- 使用
GridMap做关卡灰盒,它会在 3D 网格上放置MeshLibrary项目
(图块地图的 3D 对应物)。
模式
1. 跟随摄像机(第三人称,平滑)
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. 代码中的太阳 + 环境
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. 从代码分配 StandardMaterial3D
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. 将图块放置到 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)
常见陷阱
- 场景渲染为黑色 → 没有灯光也没有环境光。添加
DirectionalLight3D和/或带有
环境光/天空的 WorldEnvironment。新场景默认两者都没有。
- 没有摄像机 / 摄像机不正确。 如果什么都不显示,说明没有
Camera3D为current。设置
current = true 或 make_current();每个视口只有一个摄像机渲染。
- 混淆局部与全局变换。
position/rotation相对于
父节点;global_position/global_transform 是世界空间。在已旋转的 父节点下混用它们会产生意外结果。look_at 使用全局坐标。
- 缩放物理/灯光。 在
Node3D上使用非均匀scale会扭曲子节点碰撞
和灯光;优先缩放网格资产或使用均匀缩放。
- 忘记
look_at的from/up。look_at(target, up)— 目标等于
节点位置,或 up 与视线方向平行,会产生 NaN/翻转。
- 没有
MeshLibrary的GridMap不会放置任何内容。创建MeshLibrary(来自场景)
并分配它;set_cell_item(cell, -1) 会清除单元格。
- HDR/辉光过强 → 检查
tonemap_mode和辉光阈值;原始自发光值
在电影级色调映射下会产生强烈泛光。
参考资料
- 如需了解 Transform3D 数学、摄像机投影模式、灯光/阴影参数、完整的
Environment/后处理选项、MeshLibrary 创建,以及 ReflectionProbe/ LightmapGI 光照,请阅读 references/scene-and-environment.md。
相关技能
godot-physics— 3D 物理体、区域和射线检测。godot-shaders— 用于自定义 3D 表面的空间着色器。godot-animation— 用于 3D 角色的AnimationTree。camera-systems— 第三人称环绕 / 第一人称视角装置、取景和碰撞。performance-optimization— 让 3D 场景保持在帧预算内(绘制调用、灯光、LOD)。fps-shooter— 将 3D 移动、输入和 AI 组合成游戏。