丰田如何利用 Flutter + C++ 打造出主机级的游戏引擎

原始演讲:FOSDEM 2026
演讲者:Jamie Kerber(Very Good Ventures 资深工程师 / Fluorite 首席工程师)
代表人员:Joel Winarski(丰田北美互联公司 首席工程师 / Fluorite 创始人)
前言:当 Flutter 撞上 3D 性能之墙
丰田已经在量产车中搭载了 Flutter。2026 款 RAV4 的车载信息娱乐系统就运行在 Flutter 的嵌入式堆栈上。但传统的 Flutter 仅支持 2D 渲染,对于汽车应用场景来说,这还远远不够。
想象一下这个场景:你需要一个 3D 交互式车主手册,驾驶员可以旋转汽车模型,点击轮胎查看胎压,或者拖动滑块来调节悬架高度。实时硬件状态可视化、环境贴图投影------这一切都需要一个游戏引擎。
问题在于:现有的游戏引擎中,没有一个能与 Flutter 嵌入式系统完美集成。丰田互联(Toyota Connected)给出的答案?从零开始自研一个。
当我第一次看到这个演讲题目时,我以为这只是另一个"公司开源内部工具"的故事。但在看完之后,我意识到他们正在解决的问题远比我预期的要复杂。而且,这不仅仅是丰田一家公司面临的难题。
1. 为什么现有的游戏引擎行不通?
丰田团队并没有偷懒。他们测试了市场上每一个主流选项,结论非常明确:全部失败。
- 首先是商业闭源引擎: Unity 和 Unreal 要求在你的 Linux 发行版中携带闭源的二进制大对象(Proprietary Blobs)------这直接断绝了与 Yocto 的兼容性。在嵌入式 Linux 世界中,Yocto 是标准构建系统,你绕不开它。更糟的是,每个原生视图(Native View)都会生成一个完整的引擎实例,导致帧率大幅下降。再加上每年可能高达数百万美元的授权费,这对汽车制造商来说在财务上根本行不通。
- 那么开源方案 Godot 呢? 虽然没有授权费问题,但在树莓派 5(Raspberry Pi 5)上,仅启动就需要超过 20 秒。驾驶员上车、发动汽车、屏幕亮起,然后要等 20 秒才能看到 3D 界面?那是耐心测试,不是用户体验。
- 最后是 Flutter GPU (Impeller): 理论上它是完美契合的:原生 Flutter 集成、Dart 语言、热重载。实际上呢?它在 iOS 上很稳定,在 Android 上不稳定,而在 Linux / macOS / Windows 上简直无法使用。对于运行嵌入式 Linux 的车载系统来说,它等同于不存在。
在测试完所有方案后,丰田得出了一个冷酷的结论:目前没有任何方案能同时满足"Flutter 集成 + 嵌入式支持 + 高性能 3D + 开源授权"这四大需求。

于是,他们决定自研。
这反映出 Flutter 生态系统中一个更深层次的断层:Flutter 已经在 2D UI 领域拔得头筹,但当你需要底层图形能力的那一刻,你会发现脚下空无一物。无论是 AR 滤镜、点云可视化,甚至是稍显复杂的着色器(Shader)特效,都在逼着 Flutter 开发者不得不通过平台通道(Platform Channels)把工作丢回原生端去处理。Fluorite 正是试图为整个生态系统填补这一空白,而不只是为了丰田。
2. 什么是 Fluorite?
可以把它想象成盖房子。Flutter 是你的室内设计师------负责按钮、列表、动画和页面转场,它处理所有的 2D 事务。但现在你想在客厅装一面互动的 3D 屏幕墙,你不会为了装这面墙就把整座房子推倒重建,而是会找一个能嵌入现有结构的模块。
Fluorite 就是那个模块。
它是来自丰田互联(Toyota Connected)的开源 3D 游戏引擎,以 Flutter Package 的形式提供,直接集成到你的应用中。没有额外的运行环境,不需要复杂的原生视图黑科技(Platform View Hacks)。只需在 pubspec.yaml 中添加一行代码,你就拥有了一个 3D 引擎。
简而言之,FluoriteView 就是一个 Widget。
这个设计方向是正确的。Flutter 开发者对 Widget 的认知是"轻量、可组合、随处安放"。Fluorite 保留了这一心智模型,而不是丢给你一个需要特殊处理的"异物"。它遵循 Flutter 的布局系统,可以出现在任何地方:Column 内部、Stack 之上,或是 TabView 的某个标签页里。你甚至可以在同一个屏幕上放置多个 FluoriteView 实例,每个实例展示不同的 3D 视角。
而且,3D 游戏对象可以通过 Provider / Riverpod / Bloc 与 Flutter UI 组件进行交互。你已经掌握的每一种状态管理方案都能直接无缝协作。

3. 技术架构
Fluorite 并不是凭空捏造出来的。你可以把它想象成一个"三明治"结构:顶层是供你调用的 Dart API,中层是负责性能处理的 C++ 核心,而底层则构建在两个经受过验证的开源引擎之上。
-
顶层:Dart API 开发者只需要接触这一层 ------ 创建实体(Entities)、挂载组件(Components)、编写行为脚本,这一切全都使用 Dart 语言完成。
-
中层:C++ ECS 核心 为什么不全部用 Dart 编写?因为嵌入式设备的内存和 CPU 资源非常有限。C++ 让团队能够精确控制内存分配和处理管线,从而从树莓派(Raspberry Pi)这类低端硬件中榨取最大性能。
-
底层:两大支柱
- Google Filament :负责 3D 渲染。它与驱动 Android 系统 UI 的是同一个引擎,在 Vulkan 1.1+ 上实现全硬件加速,支持 PBR(基于物理的渲染) 、HDR 光影,以及基于 GLSL 超集的自定义着色器管线。
- SDL3:负责跨平台 I/O,统一了不同嵌入式设备上的输入/输出和窗口管理。

用一句话总结这个架构:Dart 负责逻辑,C++ 负责性能,Filament 负责渲染,SDL3 负责平台抽象。
4. ECS ------ 其实你早就懂了
如果你曾经在 Unity 中给物体挂载过 Transform 组件,那么恭喜你 ------ 你已经使用过"实体组件系统"(ECS)了。
ECS 是游戏引擎中最流行的架构模式。你可以把它想象成乐高积木:一个"实体(Entity)"就是一块空白底板,它本身什么都不是;"组件(Components)"则是你按在上面的积木块 ------ 位置信息、碰撞体、3D 模型、行为脚本;而"系统(System)"每一帧都会扫描所有实体,寻找带有特定组件组合的对象并执行逻辑。
Fluorite 的 API 完全遵循这一模式 ------ 唯一的区别仅仅是编程语言从 C# 切换到了 Dart:
dart
// A bouncing ball --- looks almost identical to Unity's GameObject
final bouncingBall = Entity(
name: 'BouncingBall',
components: [
Transform(
position: Vector3(0, 5, 0), // Starting position: 5m in the air
scale: Vector3(1, 1, 1),
rotation: Quaternion.identity(),
),
SphereCollider(radius: 0.5), // Collision boundary
ModelRenderable(asset: 'assets/ball.glb'), // 3D model
BehaviorScript(
onCreate: (entity) { /* initialization logic */ },
onUpdateFrame: (entity, deltaTime) {
// Per-frame update: gravity, bounce, displacement
},
),
],
);
变换(Transform)、碰撞体(Collider)、可渲染体(Renderable)、行为脚本(Behavior Script)------如果你是从 Unity、Unreal 或 Godot 阵营过来的,闭着眼睛都能认出这些概念。

Fluorite 还提供了一个"层级场景图 (Hierarchical Scene Graph)",用于构建复杂的嵌套对象结构。车身是父级实体(Parent Entity),四个车轮是子级实体(Child Entities),每个车轮上又挂载了胎压传感器 ------ 这与任何其他主流游戏引擎完全一致。近乎零的迁移成本:如果你能在 Unity 中构建场景,你就能在 Fluorite 中构建。
话虽如此,"低迁移成本"主要适用于你有游戏开发经验的情况。如果你是一名从未接触过游戏引擎的纯 Flutter 开发者,ECS(实体组件系统)的心智模型与你习惯的 Widget 树大不相同。Widget 是声明式的 UI 描述,而 ECS 是基于每一帧的系统循环。这其中存在学习曲线。Fluorite 将 ECS 封装在 Dart API 之下,因此你不需要理解系统调度就能开始构建。但如果你想做出超越 Demo 级别的场景,理解 ECS 的数据流就变得至关重要了。
5. 艺术家与开发者如何协作
传统游戏开发有一个长期的痛点:艺术家创建 3D 模型,交给开发者,然后开发者花费数小时标记交互区域、设置碰撞边界并绑定事件。当艺术家修改模型时,开发者就得重做一遍。
Fluorite 的答案是:模型定义触摸触发区 (Model-Defined Touch Trigger Zones)。
核心思路:让 3D 艺术家直接在 Blender 中使用命名规范来标记交互区域。对于一个汽车模型,艺术家将每个轮胎标记为 trigger_tire_FL、trigger_tire_FR 等。在开发侧,你只需要写:"当 trigger_tire_FL 被点击时,打开胎压面板。"
实际操作中的表现:
- 点击 3D 汽车模型上的轮胎 → 调整胎压数值
- 拖动 Flutter 的 Slider 滑块 → 实时更新 3D 胎压指示器
- 游戏状态(Game State)与 Flutter UI 始终保持完美同步

最大的赢点在于:艺术家和开发者可以完全并行工作。艺术家在 Blender 中调整模型,而开发者在 Dart 中编写交互逻辑,双方通过 GLTF/GLB 格式交换资源,无需互相等待。
6. 以 Dart 为中心的开发体验
使 Fluorite 脱颖而出的原因可以用一句话总结:你在 Dart 中编写游戏逻辑,在 Flutter 中编写 UI,两者都在同一个项目中完成。
在实践中这究竟意味着什么?
UI 和游戏逻辑都使用 Dart 编写。无需在 C# 和 Dart 之间进行上下文切换。状态管理、模型类以及工具函数全都是共享的;不需要维护两套代码库。热重载(Hot Reload)、Widget Inspector 以及 DevTools 全都可用。微调一下摄像机的轨道距离,点击保存,3D 场景在不到一秒钟内就会更新。相比之下,其他游戏引擎的编译时间往往长达数十秒。而且,整个 pub.dev 生态系统都可以直接调用。
以下是它与其他备选方案的对比:

Fluorite 是目前唯一能勾选该表所有选项的解决方案。
7. 现实考量:风险在哪里?
技术本身很扎实,但在投入之前,有几件事值得深思。
- Impeller 的阴影: Flutter 官方的 Impeller 渲染引擎仍在活跃开发中。如果两年后 Impeller 增加了 Linux 和桌面端的 3D 能力,Fluorite 的定位会变得有些尴尬。你是选择官方方案,还是第三方引擎?虽然 Fluorite 提供的 ECS 架构和嵌入式优化是 Impeller 不具备的,但两者功能的重叠值得持续关注。
8. 路线图与资源格式
已完成
- C++ ECS 核心引擎
- Filament 3D 渲染集成
- Dart API 层
- 层级场景图 (Hierarchical Scene Graph)
- 模型定义的触摸触发区
- 热重载 (Hot Reload) 支持
- PBR 材质 + HDR 光照
- 自定义着色器管线
进行中 / 计划中
- Jolt 物理引擎集成 ------ 刚体/软体物理模拟,以组件(Components)形式挂载
- CLI / GUI 工具 ------ 支持设计师与开发者的工作流
- 全跨平台支持 ------ 嵌入式 Linux (包含 Yocto)、iOS、Android、macOS、Windows、游戏主机
- SDL3 Dart API ------ 将 SDL3 的能力作为 Package 开放给 Flutter 社区
资源格式
- 当前支持格式:3D 模型使用 GLTF / GLB (完全兼容 Blender);纹理支持 KTX、HDR 等常见格式;着色器使用 GLSL 超集。
- 如果你已有来自 Unity / Unreal / Godot 的 GLTF 资源,几分钟内即可将其迁移至 Fluorite。
9. 这对 Flutter 开发者意味着什么
Fluorite 是一款 3D 游戏引擎,但更宏观的意义在于:Flutter 正在从"UI 工具包"演变为"应用平台"。
Flutter 始于纯移动端框架,随后扩展至 Web、桌面和嵌入式。每一次人们都说"Flutter 不适合这个",但每一次都有团队用量产产品证明他们错了。Fluorite 是最新的跨越。丰田证明了 Flutter 可以运行主机级的 3D 渲染。
这并不意味着每个 Flutter 开发者明天都要去学 ECS。但如果你下一个项目需要 3D 产品展示、AR 交互、数据可视化或简单的游戏,你不再需要离开 Flutter 生态。
你现在可以做的:
- 关注
fluorite.game以获取仓库公开的动态。一旦公开,运行一下示例项目。即使你最终不用它,花一个小时感受一下"Dart + 3D"也是值得的。 - 跟踪 Impeller 的桌面端进展。如果你看重 3D 但不需要嵌入式支持,Impeller 可能更轻量。同时关注两者,在时机成熟时做出选择。
- 审视当前项目。哪些地方受到了 2D 的限制?产品模型展示、空间数据可视化、游戏化引导。这些过去需要 WebView 或平台通道绕路实现的功能,现在有了原生选项。
Fluorite 目前还没有公开仓库,但我正在盯着 fluorite.game。开放的那一刻,我会立即尝试。有些东西不能仅凭一场演讲来判断,你必须亲手写代码。
Flutter 的 3D 故事才刚刚开始。Fluorite 可能不是最终答案,但它是目前唯一在认真尝试的方案。