Skip to content
Back to Blog
how-to-convert

如何将 glTF 转换为 GLB(单文件 3D 模型)

2026-05-17 8 min read

glTF 与 GLB:这两种格式到底有什么不同

从本质上讲,glTF 和 GLB 是同一个东西。它们由同一个 Khronos Group 规范定义,共享相同的数据结构,支持相同的 PBR 材质、动画和场景层级。唯一真正的区别在于封装方式。 一个标准的 glTF 资产是必须放在一起的一整套文件。你会得到一个人类可读的 .gltf JSON 文件,它描述了场景、材质和网格拓扑。与之配套的,会有一个或多个 .bin 文件,用于存放原始的几何数据——顶点位置、法线、UV 等。然后还有一个存放纹理图片的文件夹,通常是 PNG 或 JPEG。一个中等复杂度的角色模型可能会包含 character.gltf、character0.bin 以及一个 textures/ 文件夹(内含十张图片)。只要丢了其中任何一个文件,模型就根本无法加载。 而 GLB 呢,则是二进制容器版本。它把 JSON、二进制数据和所有纹理都漂亮地打包进一个 .glb 文件里。所有这些内容由一个微小的 12 字节头部维系在一起,头部包含一个魔数(0x46546C67,也就是 ASCII 码中的 'glTF')、一个版本字段(目前是 2)和文件总长度。文件的其余部分就是一系列数据块。 这使得 GLB 文件完全自成一体。你可以通过电子邮件发送它,把它拖拽到一个基于网页的产品配置器中,或者把它交给客户,而不用担心路径损坏或纹理丢失。文件大小几乎总是在原始文件包的 1-3% 范围内,所以为了这种巨大的便利性,你几乎不用付出任何存储空间的代价。

什么时候应该(什么时候不应该)将 glTF 转换为 GLB

对于最终交付和部署,我的首选永远是 GLB。单个独立文件的简洁性实在太香了,不容错过。但在活跃的开发阶段,坚持使用多文件的 glTF 格式实际上可能是更明智的选择。 当你需要将模型部署到像 model-viewer、Babylon.js 或 Three.js 这样的网页查看器时,使用 GLB 的理由最为充分。一次网络请求总是比为每个二进制文件和纹理发起一连串的网络调用要好。在一个移动网络连接上,一个 4 MB 的 GLB 会比一个拆分成 120 KB .gltf、2.1 MB .bin 和六张共计 1.8 MB 纹理的同等模型加载速度明显更快。为什么?因为每个独立文件都需要一次独立的 HTTP 往返。当你向客户或市场分发模型时,也应该转换为 GLB;像 Unity Asset Store、Sketchfab 和苹果的 AR Quick Look 等平台都能与它无缝协作。 那么多文件 glTF 在哪里大放异彩呢?在内容创作阶段。如果一个纹理艺术家正在反复修改一张 2K 的粗糙度贴图,他们只需将新的 PNG 文件放入 textures 文件夹然后刷新即可。这比每次都重新打包整个资产要快得多。同样的逻辑也适用于自动化构建系统。如果你的流程需要运行纹理压缩来生成 KTX2 或 Basis Universal 变体,那么操作单个零散文件远比在每次构建时解包再重打包一个 GLB 要简单得多。 还有一个关键限制要记住:根据设计,GLB 无法引用外部纹理。如果你最初的 glTF 设置得很巧妙,链接到了 CDN 上的纹理——这是一种在多个模型间共享纹理图集的模式——那么转换为 GLB 会将纹理的本地副本嵌入进来,从而破坏这种共享资源的模式。

如何使用 CocoConvert 将 glTF 转换为 GLB

使用 CocoConvert 的浏览器工具是获取 GLB 最简单的方法,因为它不需要安装任何软件。对于小于 100 MB 的文件,整个过程都在客户端进行,这意味着你宝贵的几何体和纹理数据甚至根本不会离开你的电脑。 第 1 步 — 准备文件。glTF 资产是一个打包交易,所以你需要把所有东西一起上传。唯一的方法是将你的 .gltf 文件、所有相关的 .bin 文件以及整个 textures 文件夹压缩成一个 zip 归档文件。保持内部文件夹结构完整至关重要。.gltf 文件依赖于像 ./textures/baseColor.png 这样的相对路径,转换器需要这些路径在 zip 文件内部是正确的。 第 2 步 — 打开转换器。前往 /convert/gltf-to-glb,然后点击上传区域,或者直接将你的 .zip 文件拖到页面上。这个工具很智能,能自动找到 glTF 的入口文件。如果你的 zip 文件因为某种原因包含了多个 .gltf 文件(比如 LOD 变体),页面上会出现一个下拉菜单,让你选择正确的根文件。 第 3 步 — 检查转换选项。CocoConvert 提供了一些设置。“嵌入纹理”默认是开启的,这正是你想要一个真正的单文件 GLB 所需要的。如果你关闭这个选项,输出的文件将会引用外部的纹理 URI,这就违背了转换的初衷。另一个选项是“合并缓冲区”。我的建议是?保持启用。它会将多个 .bin 文件合并成一个单独的二进制块,这是标准的 GLB 行为。 第 4 步 — 下载。就是这样。转换通常需要 5 到 20 秒,具体取决于你有多少纹理以及文件总大小。你会得到一个 .glb 文件,可以随时用于部署。

命令行替代方案:使用 gltf-pipeline 实现自动化工作流

当你在构建流程中需要转换几十个模型时,一个一个地使用网页界面根本不现实。对于任何类型的自动化工作流,来自 Cesium 团队的 gltf-pipeline Node.js 工具是目前最可靠的开源选项。 首先,用 npm 全局安装它:`npm install -g gltf-pipeline`。然后转换单个资产就很直接了:`gltf-pipeline -i scene.gltf -o scene.glb`。-i 标志指向你的输入 .gltf 文件。与网页工具不同,gltf-pipeline 会自动在同一目录中查找相关的 .bin 文件和纹理,所以不需要打包成 zip。当你的输出文件名以 .glb 结尾时,-b 标志(代表 --binary)是默认隐含的,这非常方便。 要批量处理整个目录,一个简单的 shell 循环是你的好帮手:`for f in models/*.gltf; do gltf-pipeline -i "$f" -o "${f%.gltf}.glb"; done`。在 Windows PowerShell 中等效的命令是 `Get-ChildItem -Filter *.gltf | ForEach-Object { gltf-pipeline -i $_.FullName -o ($_.FullName -replace '.gltf','.glb') }`。 gltf-pipeline 还支持通过 --draco.compressionLevel 标志(值为 0-10,默认为 7)进行 Draco 网格压缩。对于任何网格密集的模型,你都绝对应该启用这个功能。它可以将几何体大小削减 60-80%。一个 50 万多边形、未压缩时 18 MB 的扫描模型,在使用 Draco 7 级压缩后可以缩小到 4 MB 左右。在浏览器中稍长的解码时间几乎总是值得的。 这个工具的一个主要限制是它不处理纹理压缩(KTX2/Basis)。为此,你需要在流程中增加一个单独的步骤,在打包 GLB 之前或之后,使用像 toktx 或 basisu 这样的工具来处理。

部署前验证你的 GLB 输出文件

千万别跳过这一步。一个在一个查看器中能完美打开的 GLB,如果包含了不合规的数据,在另一个查看器中可能会静默失败。在你交付任何转换后的资产之前,请将验证作为流程的标准部分。 Khronos glTF 验证器是唯一的金标准。你可以在线使用它,网址是 validator.khronos.org——只需将你的 .glb 文件拖到页面上。它会输出一份结构化的 JSON 报告,详细说明错误、警告和其他信息。错误是致命的。像访问器 componentType 不匹配或缓冲区视图超出声明的缓冲区长度这类问题,会导致大多数加载器当场拒绝该文件。警告没那么严重,但仍然值得一读;一个常见的警告如“MESH_PRIMITIVE_UNUSED_TEXCOORD”只是意味着你有一个没有被任何材质使用的 UV 集。 对于自动化流程,你可以将验证器安装为一个 Node 包:`npm install -g gltf-validator`。然后运行 `gltf-validator scene.glb --stdout > report.json` 并将报告通过管道传送到 CI 检查中。如果错误数量大于零,构建过程绝对应该失败。 除了严格的规范合规性,一定要在至少两个不同的渲染器中进行视觉检查。我推荐 model-viewer (modelviewer.dev) 和 Babylon.js Sandbox (sandbox.babylonjs.com)。它们使用不同的 WebGL 实现,非常擅长暴露细微的材质问题。任何跟法线贴图斗争过的人都懂这种痛,它在你的 DCC 工具里看起来好好的,但在网页上却神秘地翻转了。glTF 规范要求使用 OpenGL 风格的法线(Y 轴向上),但许多工具默认导出 DirectX 风格(Y 轴向下)。如果你的光照看起来像是凹凸反了,翻转你法线贴图的绿色通道然后重新转换即可。

常见转换错误及修复方法

大多数 glTF 到 GLB 的转换错误虽然令人沮丧,但好在都有直接的修复方法。以下是反复出现的一些问题。 输出文件中纹理丢失:这是头号问题。罪魁祸首几乎总是 .gltf 文件中的纹理 URI 路径在转换过程中没有被正确解析。要调试这个问题,用文本编辑器打开你的 .gltf 文件,找到 images 数组。你会看到类似 `"uri": "textures/Material_baseColor.png"` 这样的条目。你必须确保这些文件在你的 zip 归档或工作目录中,确切地存在于那个相对路径下。记住,在服务器上,路径分隔符和大小写是敏感的:`Textures/BaseColor.png` 和 `textures/baseColor.png` 是不一样的。 输出文件过大:如果你的 GLB 文件出乎意料地大,原因几乎肯定是你的纹理。一张 4096×4096 的 RGBA PNG 在内存中未经压缩就可能占用 64 MB。虽然 PNG 本身使用无损压缩,但 GLB 只是嵌入了原始的 PNG 文件字节。这意味着你 12 MB 的 PNG 纹理会给 GLB 增加 12 MB 的体积。对于网页应用,你应该认真考虑将纹理降采样到 2048×2048(视觉差异通常可以忽略不计),或者在打包 GLB 之前应用 KTX2 压缩。 动画不播放:如果你的源 glTF 文件有骨骼动画,但在 GLB 中却消失了,这很可能意味着动画数据从未被包含进来。一些 3D 导出器会将动画数据写入一个单独的 .bin 文件。如果在转换输入时这个文件丢失了,动画数据也就随之丢失了。修复方法是从你的 3D 工具中重新导出,确保所有二进制数据都写入一个单独的 .bin 文件,然后再进行转换。 如果 CocoConvert 检测到它在你的归档文件中找不到被引用的文件,它会在日志中报告一个警告。下载前一定要检查日志。

文件大小、性能以及在真实项目中的预期

我们不谈理论。具体的预期比模糊的承诺要好得多,所以下面我们来看看一些典型资产的转换过程实际上是怎样的。 一个简单的家具模型——一个网格,两种材质,四张 1K 纹理——开始时可能是一个 3.2 MB 的多文件 glTF 包。转换后,它变成一个 3.1 MB 的 GLB。文件体积的轻微减小来自于消除了 JSON 中的空白字符和合并了缓冲区的头部信息。在网络连接快的台式机上,你不会注意到加载时间的差异。但在 4G 移动网络上,那个单文件的 GLB 会因为避免了多次 HTTP 请求的开销而提前 300-500 毫秒开始渲染。 现在考虑一个带有骨骼动画、12 种材质和 2K 纹理的复杂角色。这可能是一个 28 MB 的 glTF 包。作为一个普通的 GLB,它大约是 27.4 MB。如果你为几何体添加 Draco 压缩,它可能会降到 22 MB 左右。但如果你先应用 KTX2 Basis Universal 纹理压缩,最终的 GLB 可能小到只有 9-11 MB。CocoConvert 能完美处理基础的 glTF 到 GLB 的打包,但它目前还不支持应用 Draco 或 KTX2。对于那些高级优化,你需要在单独的步骤中使用像 gltf-pipeline 和 toktx 这样的工具。 对于 AR 项目,文件大小至关重要。苹果的 AR Quick Look 和谷歌的 Scene Viewer 都有明确的限制。苹果建议将 GLB 保持在 20 MB 以下,以确保在移动网络上可靠加载。谷歌的硬性限制是 200 MB,但他们建议保持在 15 MB 以下以获得良好性能。如果你的转换后 GLB 超过了这些限制,不要立即去用几何体简化工具。你的第一步,也是影响最大的一步,几乎永远是纹理压缩。 在 /convert/gltf-to-glb 上的转换本身对于 3D 数据是无损的——几何体、材质、动画和场景层级都得到精确保留。你输入的是什么,输出的就是什么,只是重新打包以获得最佳的可移植性。

Ready to convert?

Try it now — fast, secure, and private.

Convert Now →
如何将 glTF 转换为 GLB(单文件 3D 模型) | CocoConvert Blog