Web 原生 2D / 3D 图形引擎概览
这篇文章解决一个经常被混淆的问题:Canvas、Phaser、three.js 到底各自是什么、彼此是什么关系、做游戏时该怎么选。正文以官方规范、官方文档和项目主页为主线,先拆底层图形能力,再拆 2D 游戏框架与 3D 渲染库,最后补齐 three.js 周边可用于 3D 游戏或交互式 3D 产品的代表性框架与引擎方案。
核心结论 1
Canvas 2D 是浏览器原生绘图 API,不是游戏引擎,更像图形底座。
核心结论 2
Phaser 是建在 Canvas / WebGL 之上的 2D 游戏框架,帮你组织场景、资源、输入、物理和渲染。
核心结论 3
three.js 是 3D 库,不是完整游戏引擎。它解决 3D 场景与渲染,不自动解决游戏全栈问题。
核心结论 4
如果你坚持走 three.js 生态,真正更接近“3D 游戏引擎”的是 Rogue Engine 和 enable3d。
一、研究边界与一张总图
这次调研只关注 Web 原生运行时,也就是浏览器里直接可用的图形与游戏技术栈,不讨论 Unity、Unreal、Godot 的 Web 导出路线。问题的关键不在“谁最强”,而在于先把层级分清:底层图形 API、上层 2D 游戏框架、3D 场景库、以及再上一层的编辑器或游戏引擎壳,根本不是同一类东西。
浏览器图形 / 游戏栈的大致层级 应用 / 游戏逻辑层 ├─ 你的关卡、玩法、UI、数据与状态 ├─ 2D 游戏框架:Phaser └─ 3D 交互 / 3D 游戏框架:Rogue Engine / enable3d / A-Frame / R3F / Threlte 图形抽象层 ├─ 2D 绘图 API:Canvas 2D ├─ 3D 渲染库:three.js └─ 低层 GPU 通道:WebGL / WebGPU 平台层 └─ 浏览器、输入系统、音频、网络、DOM、Worker、存储
Canvas 是什么
浏览器原生 2D 绘图接口,提供像素、路径、文本、图像绘制等基础能力。
Phaser 是什么
面向 2D 游戏的组织层,把资源加载、场景管理、输入、相机、动画和物理串起来。
three.js 是什么
JavaScript 3D 库,提供场景图、相机、几何体、材质、灯光、动画与渲染器。
二、Canvas:Web 2D 图形的基础地板
Canvas API 是 HTML 平台内建的绘图能力。你通过 <canvas> 元素和 CanvasRenderingContext2D 获取一个可写像素表面,然后用 JavaScript 发出绘图命令。它不是引擎,也不保留“对象场景树”;它更像一块画布和一支极快的笔。
1. 工作原理
Canvas 2D 采用的是即时模式(immediate-mode)渲染:绘图命令直接修改底层像素缓冲,不会自动记录“这个圆是谁”“那个精灵属于哪个层”。因此,复杂场景想要更新时,通常需要你自己管理状态并在下一帧重绘。
2. 它擅长什么
- 像素级绘制、滤镜、视频帧处理、签名板、简单白板和图像处理。
- 自己掌控渲染循环的 2D 动画、小游戏、粒子系统、可视化面板。
- 作为更高层框架的渲染后端或中间缓冲层。
3. 它不擅长什么
- 大规模复杂对象的保留式交互。对象拾取、命中检测、层级关系要自己管理。
- 复杂游戏工程组织。资源系统、关卡系统、相机、动画时间线、物理、UI 一般都要自己搭。
- 原生 3D 场景。3D 不是 Canvas 2D 的职责边界。
| 维度 | Canvas 2D 的表现 | 工程含义 |
|---|---|---|
| 抽象层级 | 低 | 自由度高,但组织成本也高 |
| 渲染模型 | 即时模式 | 每帧通常自己重绘 |
| 交互系统 | 原生没有对象层事件 | 命中检测需要自己做 |
| 游戏能力 | 无内建玩法框架 | 适合自研,不适合直接当“现成引擎” |
| 学习成本 | 中等偏低 | 入门快,但做大项目很快会撞上工程组织问题 |
因此,Canvas 更适合被理解成 图形底座。很多人说“我用 Canvas 做游戏”,本质上往往是在说“我基于 Canvas 自己搭了一套游戏循环和对象系统”。
三、Phaser:建在 Canvas / WebGL 之上的 2D 游戏框架
Phaser 的官方定位一直非常清晰:它是一个面向浏览器的 HTML5 游戏框架,重点是2D 游戏开发。截至 2026-06-18,其 GitHub Releases 页面显示最新正式发布版本为 v4.1.0,但官方示例、教程与大量生态资料依然大量围绕 Phaser 3 展开,因此学习和工程落地时通常要同时参考 v3 文档与 v4 发布状态。
1. Phaser 的核心原理
Phaser 的价值不在于“帮你画图”,而在于它把做 2D 游戏反复会遇到的能力统一组织起来。它有自己的 Game 生命周期、Scene 场景模型、资源加载器、输入系统、动画系统、相机、音频和物理模块,底层则根据配置与设备能力选择 WebGL、Canvas 或 Headless 渲染路径。
Phaser 典型运行模型 Game Config -> 选择渲染器 (AUTO / WEBGL / CANVAS) -> 注册 Scene -> 初始化输入、纹理、动画、缓存、声音 Scene 生命周期 preload() -> 加载图片、图集、音频、数据 create() -> 创建精灵、文本、按钮、相机、物理体 update() -> 每帧推进角色状态、碰撞、动画和逻辑 Game Objects -> sprite / image / text / tilemap / container / particles ... -> 可选接入 input / physics / tween / camera
2. Scene 是 Phaser 的主心骨
Phaser 的核心组织单元是 Scene。每个 Scene 可以拥有自己的显示列表、输入管理、相机和更新循环,并且多个 Scene 可以并行运行,比如“主游戏场景 + HUD 场景 + 暂停菜单场景”。这比直接在 Canvas 上写一堆全局状态更像真正的游戏工程结构。
3. 输入系统与交互模型
Phaser 会把鼠标、触摸、键盘、手柄等输入统一接进自己的输入层,但一个 Game Object 默认并不会自动接收点击或悬停事件,通常要显式调用 setInteractive()。这意味着 Phaser 提供了对象级交互抽象,而不是让你自己在 Canvas 坐标系里手搓命中测试。
4. 物理系统
Phaser 官方长期维护两套主要物理路线:
- Arcade Physics:轻量、易懂、适合平台跳跃、俯视角动作、简单碰撞和休闲玩法。
- Matter.js:更完整的刚体物理,支持复杂碰撞体、约束和复合体,适合更重的物理交互。
这两套系统的取舍,体现了 Phaser 的工程哲学:多数小游戏先用轻量方案闭环,真的需要刚体世界再升级,而不是把所有项目都拖进重物理。
5. Text、动画和渲染细节
Phaser 文档对一个细节交代得很直接:Text 对象底层会先在隐藏 Canvas 上绘制,再上传成纹理。因此,Phaser 虽然是游戏框架,但仍然会把浏览器原生图形能力吸收进自己的渲染链路中。这正说明它和 Canvas 不是替代关系,而是上层框架复用下层能力的关系。
资源加载
通过 Loader 统一接管图片、纹理图集、音频、JSON、tilemap 等资源,减少手写资源生命周期管理。
对象模型
Sprite、Image、Text、Tilemap、Container、Particles 等 Game Object 已经是现成游戏构件,而不是裸绘图指令。
渲染后端
Phaser 不是只能跑 Canvas。它会根据配置走 WebGL 或 Canvas;Canvas 只是它可用的底层通道之一。
四、Phaser 的实践、社区与典型案例
1. 实践层面最适合什么项目
Phaser 最擅长的是 2D 游戏,尤其是这些场景:
- 平台跳跃、跑酷、俯视角射击、弹幕、生存类小游戏。
- Roguelike、解谜、卡牌、回合制、塔防、叙事驱动的 2D 作品。
- 品牌活动、社交平台内嵌游戏、Discord Activity、教育类小游戏。
官方教程、示例和书籍也主要围绕这些方向展开。下载页明确强调了 2000+ 官方示例与大量教程,说明 Phaser 的学习资源不是零散社区文章,而是体系化的官方材料。
2. 社区生态
Phaser 主站公开提供了 Discord、Forum、Reddit、Newsletter 等社区入口。工程上,这比“有 GitHub 仓库”更重要,因为它意味着你在踩坑时能找到长期维护的问答、示例和讨论,而不是只能依赖旧博客。
3. 工具链
官方还提供 Phaser Editor 与下载页的工具入口。对纯代码型开发者,这不是必须;但对想把关卡、资源、动画和可视化编辑工作提前收束的人来说,这能显著降低工程摩擦。
4. 典型案例判断
| 场景 | Phaser 是否适合 | 原因 |
|---|---|---|
| 2D 小游戏合集 | 非常适合 | 有现成场景、输入、动画、粒子和轻物理支持 |
| HTML5 活动页互动游戏 | 非常适合 | 浏览器部署轻、跨桌面与移动端容易 |
| 复杂 UI 驱动的运营小游戏 | 适合 | 游戏层和 UI 层可分 Scene 或与 DOM 混合 |
| 3D 世界探索 | 不适合 | Phaser 的主定位是 2D,不是完整 3D 引擎 |
| 写实 3D 游戏 | 不适合 | 需求已经超出 Phaser 的设计边界 |
五、three.js:3D 场景库,不是完整游戏引擎
three.js 官方首页的定位非常直接:它是一个 JavaScript 3D Library。这句话很重要,因为它把 three.js 的职责边界说得足够清楚了。three.js 解决的是 3D 场景、相机、几何体、材质、灯光、动画与渲染器,而不是替你把游戏全栈打包好。
1. 它真正提供了什么
- 场景图模型:
Scene、Object3D、层级变换。 - 相机系统:透视、正交、轨道控制等。
- 几何体与材质系统:网格、线段、点云、PBR 材质、纹理。
- 光照与阴影:环境光、方向光、点光源、阴影贴图。
- 动画与加载器:GLTF、FBX、贴图、骨骼动画等。
- WebGL 渲染器,以及持续演进的 WebGPU 路线。
2. 它没有默认提供什么
- 完整的 3D 游戏规则层、任务系统、关卡系统和游戏状态编排。
- 开箱即用的物理世界。刚体、车辆、角色控制、射线碰撞通常要接 Cannon、Rapier、Ammo 等外部方案。
- Unity/Godot 那种一体化编辑器、资源导入工作流和项目管理能力。
- 完整 UI、音频、存档、联网和工具链抽象。
所以如果你说“我用 three.js 做游戏”,更准确的说法通常是:我基于 three.js 搭了一套 3D 应用或游戏框架。three.js 是 3D 渲染和场景组织的核心件,但不是整台机器。
3. three.js 最适合的实践方向
3D 交互产品
商品展示、数字展厅、建筑预览、数据空间、3D 可视化和创意网站,这些是 three.js 最成熟的落地方向。
轻量 3D 游戏与原型
第三人称原型、第一人称探索、解谜展示、低复杂度物理互动,都可以在 three.js 上逐步搭起来。
一旦项目需求开始触碰角色控制器、关卡编辑器、多人同步、重物理和内容生产工作流,three.js 自身就不再够用,你需要更上一层的框架或引擎壳。
六、基于 three.js 的 3D 游戏引擎 / 框架生态
用户经常问“有没有基于 three.js 的 3D 游戏引擎”。答案是:有,但多数不是 Unity 那种全栈重引擎,而是框架、编辑器或增强层。真正接近“引擎”这一说法的,只有少数几个项目。
| 项目 | 定位 | 更像什么 | 强项 | 限制 |
|---|---|---|---|---|
| Rogue Engine | 官方直接称自己是 three.js game engine | 编辑器驱动的 Web 3D 游戏引擎 | 最接近 Unity 式工作流;有场景编辑、脚本与案例 | 生态规模与通用性仍小于主流独立引擎 |
| enable3d | three.js 的 3D / 物理框架 | 程序员导向的游戏增强层 | 补齐物理和常见 3D 游戏能力;也支持 Phaser 扩展路线 | 编辑器工作流不如真正引擎完整 |
| A-Frame | 建立在 three.js 之上的 WebXR 框架 | 3D / VR / AR 场景框架 | 实体组件模型清晰,XR 场景开发门槛低 | 不以传统游戏引擎为主定位 |
| React Three Fiber | three.js 的 React 渲染器 | 3D 应用开发框架 | 与 React 生态深度整合,适合产品型 3D 交互 | 不是完整游戏引擎,很多系统要自己搭 |
| Threlte | three.js 的 Svelte 3D 框架 | Svelte 技术栈下的 3D 应用框架 | 声明式、响应式、适合 Svelte 项目 | 同样不是开箱即用游戏引擎 |
1. 谁最像“真正的游戏引擎”
如果只在 three.js 生态内部挑,Rogue Engine 是最接近“引擎”这个词的。它不是只给你一个渲染 API,而是试图给出更完整的编辑器、场景和工作流。
2. 谁更适合程序员自己掌控
enable3d 更像技术型开发者的路线。它的思路不是替你完全包起来,而是在 three.js 上把 3D 游戏常见的物理和框架能力补上,让你仍能保留足够高的代码控制权。
3. 哪些其实不该硬叫“游戏引擎”
A-Frame、React Three Fiber、Threlte 都很有价值,但更准确的表述应分别是 XR 框架、React 3D 渲染器、Svelte 3D 框架。它们能做游戏,但主卖点不在“完整游戏引擎”。
七、Phaser、Canvas、three.js 的关系到底是什么
这三个名字经常被放在一张表里比较,但它们其实分属不同层:
| 维度 | Canvas 2D | Phaser | three.js |
|---|---|---|---|
| 本质 | 浏览器原生绘图 API | 2D 游戏框架 | 3D 场景与渲染库 |
| 主要目标 | 把像素画出来 | 把 2D 游戏做出来 | 把 3D 场景渲染与组织起来 |
| 场景维度 | 2D | 2D | 3D |
| 是否内建游戏系统 | 否 | 是,较完整 | 否,需要自己组装 |
| 与底层 GPU 的关系 | 浏览器实现 | 内部可走 Canvas 或 WebGL | 主要依赖 WebGL,逐步支持 WebGPU |
| 最合适的问题 | 低层绘图与轻量交互 | 2D 小游戏与网页游戏 | 3D 交互与 3D 应用 |
1. Phaser 和 Canvas 的关系
不是替代关系,而是框架与底层能力的关系。Canvas 负责提供绘图表面,Phaser 负责提供游戏结构。你可以不用 Phaser 直接写 Canvas,但那意味着你要自己补齐很多 Phaser 已经替你处理好的工程问题。
2. Phaser 和 three.js 的关系
也不是直接竞争关系。Phaser 的主战场是 2D 游戏,three.js 的主战场是 3D 场景。只有在“我要做游戏”这个大前提下它们才会被放到一个选型问题里,但它们处理的问题根本不同。
3. Canvas 和 three.js 的关系
Canvas 2D 是 2D 绘图 API;three.js 则建立在 WebGL 之上做 3D 场景组织。两者并不处于同一抽象层,也不是简单的一高一低关系。
八、典型案例与真实选型逻辑
1. 什么时候应该选 Canvas
- 你要做的是图表、白板、签名板、粒子背景、视频特效、图像处理,而不是完整游戏工程。
- 你需要的是底层可控性,而不是框架抽象。
- 项目规模小,或者本来就准备自己搭渲染循环和对象系统。
2. 什么时候应该选 Phaser
- 目标明确是 2D 网页游戏。
- 你希望尽快拿到资源加载、场景管理、相机、动画、碰撞和输入系统。
- 你不想自己从 Canvas 或裸 WebGL 重新造一个 2D 游戏框架。
3. 什么时候应该选 three.js
- 核心问题是 3D 场景、模型、材质、镜头和空间交互。
- 你在做的是 3D 产品展示、数字空间、数据空间、交互艺术或 3D 游戏原型。
- 你接受“需要自己再组装一层游戏系统或产品框架”的现实。
4. 什么时候应该选 three.js 生态上的引擎或框架
- 已经确定是 three.js 路线,但不想纯手工拼所有 3D 能力。
- 希望有编辑器、脚本组件、物理层或更工程化的组织方式。
- 团队技术栈已经偏 React / Svelte / XR,需要把 3D 融入现有产品架构。
最低成本路线
简单 2D 绘图选 Canvas;明确的 2D 游戏选 Phaser;明确的 3D 交互选 three.js。
更工程化路线
如果坚持走 three.js 做 3D 游戏,优先评估 Rogue Engine 与 enable3d,而不是从裸 three.js 直接把整套玩法框架全补出来。
九、最终结论
Web 原生图形栈没有“万能主角”。Canvas 是地板,Phaser 是 2D 游戏框架,three.js 是 3D 场景库。把这三者放在一起比较,真正有意义的不是“谁更高级”,而是你的问题属于哪一层。
如果你的目标是做 2D 游戏,Phaser 通常比裸 Canvas 更合理;如果你的目标是做 3D 交互或 3D 游戏原型,three.js 是核心底座;如果你在 three.js 生态里继续追求更完整的 3D 游戏工作流,那么 Rogue Engine 和 enable3d 是最值得优先调研的两条路线。工程判断的关键从来不是“技术名词是否流行”,而是 抽象层是否对得上你的真实问题。