Bevy 引擎中的坐标系统详解

ZoOL 撰写的 Bevy 坐标系统完整指南,版本 0.16。原文是一份系统性的概念讲解,覆盖从世界空间到 NDC 的全链路。

坐标系统概览

Bevy 使用多套坐标系统,各自服务于不同任务:

坐标系统原点Y轴方向用途
世界空间 (2D)屏幕中心向上2D 游戏元素定位
世界空间 (3D)游戏定义向上3D 场景全局参考
局部空间 (Transform)父实体原点相对于父层级对象姿态
屏幕/UI 空间左上角向下UI 布局、鼠标输入
视口空间视口左上角向下渲染目标子区域
NDC投影中心向上渲染管线中间步骤

核心概念

世界空间:右手坐标系,Y轴向上

+X → 右
+Y → 上
+Z → 观察者(2D),-Z 为前进方向(3D)
  • Godot、Maya、OpenGL 相同
  • Unity 不同(Unity 是左手坐标系)
  • 2D/3D 使用一致坐标系,简化跨维度逻辑共享

Transform vs GlobalTransform

组件含义由谁修改
Transform局部位置/旋转/缩放(相对于父实体)开发者
GlobalTransform世界绝对变换(仿射变换)Bevy 内部自动计算

关键细节:

  • 修改 Transform 后,GlobalTransform 不会立即更新
  • 更新发生在 PostUpdate 阶段的 TransformSystem::TransformPropagate
  • 如果在同一帧 Update 阶段先改 Transform 再查 GlobalTransform,会得到过时数据
  • TransformHelper 系统参数可在传播前获取最新值,但有性能开销

GlobalTransformAffine3A 存储而非简单 Vec3+Quat,因为复杂层级可能产生剪切(shearing),矩阵表示更鲁棒。

UI / 屏幕坐标

  • 原点:左上角
  • +X → 右,+Y →
  • 单位:逻辑像素(已 DPI 缩放补偿)
  • 光标位置遵循此约定

NDC(归一化设备坐标)

  • X/Y: [-1, 1]
  • Z(深度): [0, 1]
  • 渲染管线的标准化中间空间
  • GPU 光栅化器在此空间操作

坐标转换 API

Camera 组件提供核心转换方法:

方法输入输出用例
world_to_viewport世界坐标 Vec3屏幕像素 Vec23D → 2D 屏幕点
viewport_to_world屏幕点 Vec2射线 Ray3d3D 拾取
viewport_to_world_2d屏幕点 Vec2世界坐标 Vec22D 游戏/正交相机
world_to_ndc世界坐标 Vec3NDC Vec3投影变换
ndc_to_worldNDC Vec3世界坐标 Vec3逆投影

设计影响

  1. 层级动画:父子 Transform 天然支持复杂关节结构(角色肢体、载具炮塔)
  2. 同步延迟:Transform/ GlobalTransform 不同步窗口可能导致难察觉的 bug
  3. 渲染解耦:视口允许分屏、小地图、渲染到纹理等灵活呈现

与其他引擎对比

引擎坐标系Z轴
Bevy右手Y上,-Z前进
Unity左手Y上,+Z前进
Godot右手Y上,-Z前进
OpenGL右手Y上,-Z前进

文件位置

/Users/zool/workspace/ZoOL's Valut/Bevy 引擎中的坐标系统详解.md