3D开发

概述

学习目标

  • 理解 Bevy 3D 渲染的基本概念
  • 掌握如何创建简单的 3D 场景
  • 学会使用 PBR 材质和光照系统
  • 了解如何加载 GLTF 模型
  • 掌握后处理效果的使用
  • 理解透明度和多相机渲染

前置知识要求

  • Bevy 快速入门
  • ECS 基础
  • 资源管理基础
  • 2D 基础(可选)

核心概念

什么是 3D 渲染?

3D 渲染是在三维空间中显示模型和场景。Bevy 提供了强大的 3D 渲染系统,支持 PBR 材质、多种光照类型、阴影、后处理等功能。

为什么需要 3D 渲染?

  1. 游戏开发:大多数 3D 游戏需要 3D 渲染
  2. 视觉效果:3D 渲染可以提供更真实的视觉效果
  3. 沉浸感:3D 渲染可以增强游戏的沉浸感
  4. 灵活性:3D 渲染提供了更多的创作空间

3D 渲染的核心组件

Bevy 3D 渲染系统包含以下核心组件:

  • Mesh3d:3D 网格,用于定义 3D 模型的形状
  • MeshMaterial3d:3D 材质,用于定义 3D 模型的外观
  • Camera3d:3D 相机,用于控制 3D 视图
  • Transform:变换,用于控制位置、旋转、缩放
  • Light:光照,用于照亮场景

基础用法

创建简单的 3D 场景

创建并显示一个简单的 3D 场景。

源代码文件bevy/examples/3d/3d_scene.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}

/// 设置简单的 3D 场景
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// 圆形底座
commands.spawn((
Mesh3d(meshes.add(Circle::new(4.0))),
MeshMaterial3d(materials.add(Color::WHITE)),
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
));
// 立方体
commands.spawn((
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
Transform::from_xyz(0.0, 0.5, 0.0),
));
// 光照
commands.spawn((
PointLight {
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0),
));
// 相机
commands.spawn((
Camera3d::default(),
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
));
}

关键要点

  • 使用 Mesh3d 创建 3D 网格
  • 使用 MeshMaterial3d 应用材质
  • 使用 Transform 控制位置、旋转、缩放
  • 使用 PointLight 添加点光源
  • 使用 Camera3d 创建 3D 相机

说明
这是最简单的 3D 场景示例。它展示了如何创建基本的 3D 对象、添加光照和相机。

PBR 材质

使用 PBR(Physically Based Rendering)材质创建真实的材质效果。

源代码文件bevy/examples/3d/pbr.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let sphere_mesh = meshes.add(Sphere::new(0.45));

// 创建网格的球体,每个球体有不同的 PBR 参数
for y in -2..=2 {
for x in -5..=5 {
let x01 = (x + 5) as f32 / 10.0;
let y01 = (y + 2) as f32 / 4.0;
// 球体
commands.spawn((
Mesh3d(sphere_mesh.clone()),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Srgba::hex("#ffd891").unwrap().into(),
// 在网格的球体上变化关键的 PBR 参数以显示效果
metallic: y01,
perceptual_roughness: x01,
..default()
})),
Transform::from_xyz(x as f32, y as f32 + 0.5, 0.0),
));
}
}

// 无光照球体
commands.spawn((
Mesh3d(sphere_mesh),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Srgba::hex("#ffd891").unwrap().into(),
unlit: true,
..default()
})),
Transform::from_xyz(-5.0, -2.5, 0.0),
));

// 方向光
commands.spawn((
DirectionalLight {
illuminance: 1_500.,
..default()
},
Transform::from_xyz(50.0, 50.0, 50.0).looking_at(Vec3::ZERO, Vec3::Y),
));
}

关键要点

  • 使用 StandardMaterial 创建 PBR 材质
  • metallic 控制金属度
  • perceptual_roughness 控制粗糙度
  • base_color 控制基础颜色
  • unlit 可以禁用光照

说明
PBR 材质使用物理属性来模拟真实材质的外观。通过调整金属度和粗糙度,可以创建各种材质效果。

光照系统

使用不同类型的光照照亮场景。

源代码文件bevy/examples/3d/lighting.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (update_exposure, toggle_ambient_light, movement, animate_light_direction))
.run();
}

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// 地面平面
commands.spawn((
Mesh3d(meshes.add(Plane3d::default().mesh().size(10.0, 10.0))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::WHITE,
perceptual_roughness: 1.0,
..default()
})),
));

// 立方体
commands.spawn((
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::srgb_u8(124, 144, 255),
..default()
})),
Transform::from_xyz(0.0, 0.5, 0.0),
));

// 环境光
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 150.0,
});

// 方向光
commands.spawn((
DirectionalLight {
illuminance: 1_500.,
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
));

// 点光源
commands.spawn((
PointLight {
intensity: 1_500_000.0,
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0),
));

// 聚光灯
commands.spawn((
SpotLight {
intensity: 1_500_000.0,
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
));

// 相机
commands.spawn((
Camera3d::default(),
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
));
}

关键要点

  • AmbientLight 提供环境光
  • DirectionalLight 提供方向光(如太阳光)
  • PointLight 提供点光源(如灯泡)
  • SpotLight 提供聚光灯
  • 可以启用阴影来增强真实感

说明
光照系统是 3D 渲染的重要组成部分。不同类型的光照可以创建不同的视觉效果。Bevy 支持环境光、方向光、点光源和聚光灯。

加载 GLTF 模型

加载和使用 GLTF 模型。

源代码文件bevy/examples/3d/load_gltf.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use bevy::prelude::*;

fn main() {
App::new()
.insert_resource(DirectionalLightShadowMap { size: 4096 })
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, animate_light_direction)
.run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// 相机
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
EnvironmentMapLight {
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
intensity: 250.0,
..default()
},
));

// 方向光
commands.spawn((
DirectionalLight {
shadows_enabled: true,
..default()
},
CascadeShadowConfigBuilder {
num_cascades: 1,
maximum_distance: 1.6,
..default()
}
.build(),
));

// 加载 GLTF 场景
commands.spawn(SceneRoot(asset_server.load(
GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"),
)));
}

关键要点

  • 使用 SceneRoot 加载 GLTF 场景
  • 使用 GltfAssetLabel::Scene(0) 指定场景索引
  • GLTF 文件可以包含多个场景、网格、材质等
  • 可以使用环境贴图增强渲染效果

说明
GLTF 是一种标准的 3D 模型格式。Bevy 支持加载 GLTF 文件,包括场景、网格、材质、动画等。

进阶用法

后处理效果

使用后处理效果增强渲染效果。

源代码文件bevy/examples/3d/post_processing.rs

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, handle_keyboard_input)
.run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// 相机,包含色差效果
commands.spawn((
Camera3d::default(),
Hdr,
Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
DistanceFog {
color: Color::srgb_u8(43, 44, 47),
falloff: FogFalloff::Linear {
start: 1.0,
end: 8.0,
},
..default()
},
EnvironmentMapLight {
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
intensity: 2000.0,
..default()
},
// 包含色差效果组件
ChromaticAberration::default(),
));
}

关键要点

  • 使用 ChromaticAberration 添加色差效果
  • 使用 Hdr 启用 HDR 渲染
  • 使用 DistanceFog 添加距离雾效果
  • 后处理效果可以组合使用

说明
后处理效果可以在渲染完成后对图像进行处理。Bevy 支持多种后处理效果,如色差、色调映射、泛光等。

透明度

处理透明对象。

源代码文件bevy/examples/3d/transparency_3d.rs

关键信息

  • 使用 AlphaMode 控制透明度模式
  • AlphaMode::Blend 用于半透明对象
  • AlphaMode::Mask 用于带透明度的纹理
  • 透明对象需要正确的渲染顺序

说明
透明度是 3D 渲染中的重要特性。Bevy 支持多种透明度模式,可以创建玻璃、水、烟雾等效果。

多相机渲染

使用多个相机渲染不同的视图。

源代码文件bevy/examples/3d/multiple_windows.rs

关键信息

  • 可以创建多个相机
  • 每个相机可以渲染到不同的窗口
  • 可以使用 RenderTarget 指定渲染目标
  • 适合创建分屏或多显示器应用

说明
多相机渲染允许同时显示多个视图。这对于创建分屏游戏、多显示器应用或调试视图非常有用。

实际应用

在游戏开发中的应用场景

3D 渲染在游戏开发中有广泛的应用:

  1. 3D 游戏:创建 3D 游戏场景和角色
  2. 可视化:创建数据可视化应用
  3. 模拟:创建物理模拟和训练应用
  4. 艺术创作:创建 3D 艺术作品和动画

常见问题

问题 1:如何优化 3D 渲染性能?

解决方案:可以使用 LOD(细节层次)、遮挡剔除、视锥剔除等技术来优化 3D 渲染性能。

问题 2:如何处理透明对象?

解决方案:透明对象需要正确的渲染顺序。Bevy 会自动处理透明对象的排序。

问题 3:如何创建自定义材质?

解决方案:可以实现 Material trait 来创建自定义材质。可以参考 StandardMaterial 的实现。

性能考虑

  1. 网格优化:使用优化的网格减少顶点数量
  2. 材质优化:使用简单的材质减少渲染开销
  3. 光照优化:合理使用光照类型和阴影
  4. 剔除优化:使用视锥剔除和遮挡剔除减少渲染对象

相关资源

相关源代码文件

  • bevy/examples/3d/3d_scene.rs - 简单 3D 场景示例
  • bevy/examples/3d/pbr.rs - PBR 材质示例
  • bevy/examples/3d/lighting.rs - 光照系统示例
  • bevy/examples/3d/load_gltf.rs - GLTF 加载示例
  • bevy/examples/3d/post_processing.rs - 后处理效果示例
  • bevy/examples/3d/transparency_3d.rs - 透明度示例
  • bevy/examples/3d/multiple_windows.rs - 多相机渲染示例

官方文档链接

进一步学习建议

  • 学习相机系统,了解如何控制 3D 视图
  • 学习动画系统,了解如何为 3D 模型添加动画
  • 学习自定义渲染,了解如何创建自定义渲染效果

索引返回上级目录