本文目录 7 个章节
WebGL显示链路
HTML/CSS/DOM(可选)
│
▼ JS 引擎(V8/SpiderMonkey…)
JavaScript 业务逻辑 ──► **WebGL API (ES 2.0/3.0 语义)**
│ │ ↳ 生成 GPU 命令缓冲
▼ ▼
浏览器驱动层 ─────────► GPU 驱动(OpenGL ES / Metal)
│
▼
帧缓冲 → 显示器
- 核心要点
- HTML / DOM 只是创建
<canvas>的容器;WebGL 本身完全脱离 DOM 渲染流程。 - WebGL 1/2 只是 OpenGL ES 2.0/3.0 的 JavaScript 绑定。API 调用被 JS 引擎打包为 GPU 命令。
- 所有顶点/片元运算都在 开发者自编写的 GLSL ES 着色器 中完成;没有固定功能管线。
- HTML / DOM 只是创建
Unity3D与.wasm
| 目标 | Unity 的做法 | 结果 |
|---|---|---|
| 让 C#/C++ 逻辑在浏览器跑 | IL2CPP 把 C# ➜ C++ ➜ 交给 Emscripten 编译成 WebAssembly (.wasm) | 把 CPU 密集逻辑、物理、ECS 等全部搬进高性能 Wasm VM |
| 调用浏览器 API | Emscripten 生成 Glue JS (framework.js),负责:• 加载 .wasm• 把 JS 字符串 ↔ Wasm 内存• 把 Wasm 函数导出给 JS(Module.xxx) |
JS ↔ Wasm 像互调 DLL;渲染仍通过 gl.* |
| 保证性能与安全 | Wasm 经过 JIT → 机器码,沙盒隔离 | 速度接近原生,避免 JS 动态开销 |
.wasm处在链路里的位置
JavaScript Glue (framework.js)
│ ↕ FFI(import/export)
▼
WebAssembly VM (unity.wasm)
│ ↕ 调用 WebGL API / Audio / Input
▼
GPU 驱动 …
- 渲染指令:Wasm 内部调用 Emscripten‑提供的
glBindBuffer等函数,这些又回到浏览器的 WebGL 实现;因此.wasm主要承担 CPU 侧游戏逻辑,GPU 命令仍走 WebGL。- 生命周期:下载
.wasm→WebAssembly.instantiateStreaming()➜Module.onRuntimeInitialized→ 游戏开始。(Unity Documentation)
Unity WebGL 小游戏 vs 纯微信小游戏:技术栈对照
| 维度 | Unity WebGL 转小游戏 | 原生微信小游戏(小游戏 IDE) |
|---|---|---|
| 主语言 | C# (逻辑) + Wasm C++(编译后) + 少量 JS Glue | JavaScript/TypeScript |
| 运行时 | unity.wasm + framework.js + minigame‑unity‑webgl‑transform 适配层 (GitHub) |
WeChat Game Runtime(基于 QQ Game Engine),直接跑 JS |
| 渲染层 | Unity 自带渲染管线 ➜ WebGL context(单 Canvas) | 微信提供 wx.createCanvas() ➜ WebGL/2D context |
| 脚本热更 | IL2CPP 编译期静态;热更需 AssetBundle / Lua / C# 热更新框架 | JS 热重载、分包加载 |
| 资源管线 | Unity Importer ➜ AssetBundle ➜ LZ4 压缩 | IDE & 自定义打包;纹理可 KTX2, Basis |
| 包体体积 | .wasm + 引擎数据 5‑15 MB 起;首包常借微信「分包加载」拆分 |
JS+资源,一般 < 4 MB 首包,动态拉取其余 |
| 多线程 | WebAssembly Pthreads ⚠ 仅在特定浏览器/小游戏版本开放,需 SharedArrayBuffer 安全头;小游戏端仍在灰度 |
Worker 线程可做下载/解析,但 WebGL context 只能在主线程 |
| 平台能力 | 通过转换工具桥接到 wx.* API (支付、分享、云开发) |
直接调 wx.* |
| 调试 | 浏览器 DevTools + WeChat DevTools (查看 wasm) | WeChat DevTools (调 JS) |
使用场景取舍
- 如果你已有完整 Unity 项目、需要重用 C# 生态→ 适配方案节省大量人天。
- 若从零做轻量小游戏、包体/加载时长极敏感→ JS/TS 原生小游戏更轻。
WebGL及Unity3D WebGL框架速览
graph TD
%% ───────── 物理硬件 ─────────
subgraph Hardware
CPU([CPU])
GPU([GPU])
end
%% ───────── 操作系统抽象层 ─────────
subgraph OS["Windows • macOS • Linux • Android …"]
Kernel["内核 & 驱动(文件、进程、GPU Driver)"]
GraphicsAPI["平台图形 APIDirectX · OpenGL · Metal · Vulkan"]
end
Hardware --> Kernel
Kernel --> GraphicsAPI
%% ───────── 浏览器可移植代码库 ─────────
subgraph Browser["浏览器通用代码库 (C/C++)"]
Engine["排版 & 渲染引擎Blink / WebKit / Gecko"]
JSVM["JavaScript VMV8 / SpiderMonkey / JSC"]
NetStack["网络栈HTTP/2 · TLS · Cache"]
WebGL_Impl["WebGL 实现 + ANGLEOpenGL ES 语义 → 平台 API"]
end
GraphicsAPI --> WebGL_Impl
Engine --> WebGL_Impl
JSVM --> Engine
NetStack --> Engine
%% ───────── Web 内容运行时 ─────────
subgraph Runtime["Web 内容"]
HTML_Node["HTML / CSS"]
JS_Node["JavaScript"]
Wasm_Node["WebAssembly"]
end
HTML_Node --> Engine
JS_Node --> JSVM
Wasm_Node --> JSVM
%% ───────── 宿主基座 / WebView ─────────
subgraph Hosts["宿主基座 (App WebView)"]
WeChat["WeChat Mini‑Game"]
TikTok["TikTok In‑App Browser"]
FB["Facebook In‑App Browser"]
end
Engine -. 嵌入 .-> Hosts
Hosts -. 调用系统 WebView .-> Browser

浏览器跨平台的根本是 “通用代码 + 薄适配”,而 WebGL 跨平台靠 标准 JS API + ANGLE 翻译层;无论是桌面浏览器还是嵌入式 WebView(微信、抖音、Facebook),只要内核遵守同一规范并映射到本地 GPU 驱动,同一份 Web 内容 & WebGL 代码即可无差别运行。
1. 浏览器为何跨平台?
| 关键点 | 说明 |
|---|---|
| 同一份 C/C++ 代码 | Chrome/Firefox/Safari 内核 95 % 以上用标准 C/C++ 实现。只需为不同 OS 重新编译(Clang/LLVM、MSVC、Xcode),就能得到本机可执行文件。 |
| 平台抽象层 | 内核中有 Platform 模块,把文件、线程、网络、窗口、GPU 等统一抽象;各 OS 只写少量适配。 |
| 标准化 Web 语法 | HTML5、CSSOM、ECMAScript 由 W3C/WHATWG/TC39 统一;渲染和 JS 行为在所有操作系统一致。 |
2. WebGL 为什么跨平台?
| 链条 | 作用 |
|---|---|
| WebGL 规范 | 定义 OpenGL ES 2/3 的 JS 绑定;写死函数名、状态机和 GLSL ES 行为。 |
| 浏览器实现层 | Blink/Gecko 不直接调用 OpenGL;而是先经过 ANGLE——一个把 OpenGL ES 调到 DirectX / Metal / Vulkan / EGL 的翻译库。所以 同一段 JS WebGL 代码 在任何系统都能落到可用的底层 API。 |
| GPU 驱动负责最后一步 | 各厂商驱动把平台图形 API 指令变成本机指令;因此只要系统有合规 GPU 驱动,WebGL 就能跑。 |
3. .wasm、JS、HTML 如何一起跑?
- HTML/CSS ➜ 排版引擎(树 + 盒模型)。
- JS ➜ JS VM (V8…) 解释 → JIT,调用 DOM/Canvas/WebGL。
- WebAssembly ➜ JS VM 中的 Wasm Runtime 验证 → baseline JIT → 优化 JIT ➜ 本机机器码。
- JS ↔ Wasm ↔ Web APIs (含 WebGL) 通过导入/导出函数与共享内存交互。
JS 与 Wasm 都 跑在同一 JS 引擎里,因此跨平台能力继承自浏览器本身。
4. 为何同一 WebGL 可跑在微信/抖音/FB?
- 这些 App 内嵌系统 WebView(Android WebView、iOS WKWebView、Chromium Embedded),本质还是浏览器内核 ➜ 承袭同一跨平台链条。
- 宿主只额外提供 JS Bridge (
wx.*,tiktok.*) → 业务层调用,不影响 WebGL API。 - 仅需注意 WebView 版本差异(低版本可能缺 WebGL 2 / 线程 / WebAssembly SIMD)。