Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
36 changes: 36 additions & 0 deletions gltfTutorial_cn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# glTF 教程

作者:Marco Hutter, [@javagl](https://github.com/javagl)

本教程介绍了 [glTF](https://www.khronos.org/gltf),即 GL 传输格式。它总结了 glTF 最重要的特性和应用场景,并描述了与 glTF 相关的文件结构。它解释了如何读取、处理 glTF 资产以及如何高效地使用它们显示 3D 图形。

假设您已经具备 [JSON](https://json.org/)(JavaScript 对象表示法)的一些基本知识。此外,还需要对常见的图形 API(如 OpenGL 或 WebGL)有基本的了解。本教程重点关注 [glTF 2.0 版本](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html),该版本引入了对*基于物理的渲染*的支持,但这里解释的其他概念与 [glTF 1.0 版本](https://github.com/KhronosGroup/glTF/tree/main/specification/1.0) 中的实现方式类似。


- [介绍](gltfTutorial_001_Introduction.md)
- [基本 glTF 结构](gltfTutorial_002_BasicGltfStructure.md)
- [示例:最小的 glTF 文件](gltfTutorial_003_MinimalGltfFile.md)
- [场景和节点](gltfTutorial_004_ScenesNodes.md)
- [缓冲区、缓冲区视图和访问器](gltfTutorial_005_BuffersBufferViewsAccessors.md)
- [示例:简单的动画](gltfTutorial_006_SimpleAnimation.md)
- [动画](gltfTutorial_007_Animations.md)
- [示例:简单的网格](gltfTutorial_008_SimpleMeshes.md)
- [网格](gltfTutorial_009_Meshes.md)
- [材质](gltfTutorial_010_Materials.md)
- [示例:简单的材质](gltfTutorial_011_SimpleMaterial.md)
- [纹理、图像和采样器](gltfTutorial_012_TexturesImagesSamplers.md)
- [示例:简单的纹理](gltfTutorial_013_SimpleTexture.md)
- [示例:高级材质](gltfTutorial_014_AdvancedMaterial.md)
- [示例:简单的相机](gltfTutorial_015_SimpleCameras.md)
- [相机](gltfTutorial_016_Cameras.md)
- [示例:简单的变形目标](gltfTutorial_017_SimpleMorphTarget.md)
- [变形目标](gltfTutorial_018_MorphTargets.md)
- [示例:简单的蒙皮](gltfTutorial_019_SimpleSkin.md)
- [蒙皮](gltfTutorial_020_Skins.md)


**致谢:**

- Patrick Cozzi, Cesium, [@pjcozzi](https://twitter.com/pjcozzi)
- Alexey Knyazev, [@lexaknyazev](https://github.com/lexaknyazev)
- Sarah Chow, [@slchow](https://github.com/slchow)
47 changes: 47 additions & 0 deletions gltfTutorial_cn/gltfTutorial_001_Introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[目录](README.md) | 下一章: [基本 glTF 结构](gltfTutorial_002_BasicGltfStructure.md)

# 使用 WebGL 的 glTF 介绍

越来越多的应用程序和服务都基于 3D 内容。在线商店提供带有 3D 预览的产品配置器。博物馆对其文物进行 3D 扫描,并允许游客在虚拟画廊中探索他们的收藏品。城市规划师使用 3D 城市模型进行规划和信息可视化。教育工作者创建人体的交互式动画 3D 模型。许多这些应用程序直接在网络浏览器中运行,这是可能的,因为所有现代浏览器都支持通过 WebGL 进行高效渲染。

<p align="center">
<img src="./gltfTutorial_cn/images/applications.png" /><br>
<a name="applications-png"></a>图 1a: 展示 3D 模型的各种网站和应用程序的截图。
</p>

各种应用程序对 3D 内容的需求不断增长。在许多情况下,3D 内容必须通过网络传输,并且必须在客户端高效地渲染。但直到现在,3D 内容创建和在运行时应用程序中高效渲染之间仍存在差距。

## 3D 内容管道

在客户端应用程序中渲染的 3D 内容来自不同的源,并存储在不同的文件格式中。[维基百科上的 3D 图形文件格式列表](https://en.wikipedia.org/wiki/List_of_file_formats#3D_graphics) 显示了一个庞大的数量,有超过 70 种不同的 3D 数据文件格式,服务于不同的目的和应用场景。

例如,原始 3D 数据可以通过 3D 扫描仪获取。这些扫描仪通常提供单个对象的几何数据,这些数据存储在 [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file)、[PLY](https://en.wikipedia.org/wiki/PLY_(file_format)) 或 [STL](https://en.wikipedia.org/wiki/STL_(file_format)) 文件中。这些文件格式不包含关于场景结构或对象应如何渲染的信息。

更复杂的 3D 场景可以使用创作工具创建。这些工具允许编辑场景的结构、灯光设置、相机、动画,以及当然还有场景中出现的对象的 3D 几何体。应用程序以自己的自定义文件格式存储这些信息。例如,[Blender](https://www.blender.org/) 将场景存储在 `.blend` 文件中,[LightWave3D](https://www.lightwave3d.com/) 使用 `.lws` 文件格式,[3ds Max](https://www.autodesk.com/3dsmax) 使用 `.max` 文件格式,而 [Maya](https://www.autodesk.com/maya) 使用 `.ma` 文件。

为了渲染这些 3D 内容,运行时应用程序必须能够读取不同的输入文件格式。必须解析场景结构,3D 几何数据必须转换为图形 API 所需的格式。3D 数据必须传输到图形卡内存,然后可以用图形 API 调用序列描述渲染过程。因此,每个运行时应用程序都必须为其支持的所有文件格式创建导入器、加载器或转换器,如 [图 1b](#contentPipeline-png) 所示。

<p align="center">
<img src="./gltfTutorial/images/contentPipeline.png" /><br>
<a name="contentPipeline-png"></a>图 1b: 当今的 3D 内容管道。
</p>

## glTF: 3D 场景的传输格式

glTF 的目标是为 3D 内容定义一个标准,以适合在运行时应用程序中使用的形式。现有的文件格式不适合这种用例:有些不包含任何场景信息,只有几何数据;其他一些则是为了在创作应用程序之间交换数据而设计的,它们的主要目标是保留关于 3D 场景的尽可能多的信息,这导致文件通常很大、很复杂且难以解析。此外,几何数据可能需要预处理,以便可以用客户端应用程序渲染。

现有的文件格式都不是为通过网络高效传输 3D 场景并尽可能高效地渲染它们而设计的。但 glTF 不是"又一种文件格式"。它是 3D 场景*传输*格式的定义:

- 场景结构用 JSON 描述,它非常紧凑且易于解析。
- 对象的 3D 数据以可以被常见图形 API 直接使用的形式存储,因此没有解码或预处理 3D 数据的开销。

现在,不同的内容创建工具可以提供 glTF 格式的 3D 内容。越来越多的客户端应用程序能够使用和渲染 glTF。[图 1a](#applications-png) 中显示了其中一些应用程序。因此,glTF 可能有助于弥合内容创建和渲染之间的差距,如 [图 1c](#contentPipelineWithGltf-png) 所示。

<p align="center">
<img src="./gltfTutorial/images/contentPipelineWithGltf.png" /><br>
<a name="contentPipelineWithGltf-png"></a>图 1c: 使用 glTF 的 3D 内容管道。
</p>

越来越多的内容创建工具直接提供 glTF 导入和导出功能。例如,Blender 手册记录了[如何使用 glTF 导入和导出 PBR 材质](https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html)。或者,其他文件格式可以使用 [glTF Project Explorer](https://github.khronos.org/glTF-Project-Explorer/) 中列出的开源转换工具之一创建 glTF 资产。转换器和导出器的输出可以使用 [Khronos glTF Validator](https://github.khronos.org/glTF-Validator/) 进行验证。

[目录](README.md) | 下一章: [基本 glTF 结构](gltfTutorial_002_BasicGltfStructure.md)
95 changes: 95 additions & 0 deletions gltfTutorial_cn/gltfTutorial_002_BasicGltfStructure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
上一章: [介绍](gltfTutorial_001_Introduction.md) | [目录](README.md) | 下一章: [最小的 glTF 文件](gltfTutorial_003_MinimalGltfFile.md)

# glTF 的基本结构

glTF 的核心是一个 JSON 文件。这个文件描述了整个 3D 场景的内容。它包含场景结构本身的描述,该结构由定义场景图的节点层次结构给出。场景中出现的 3D 对象使用附加到节点的网格来定义。材质(Materials)定义了对象的外观。动画(Animations)描述了 3D 对象如何随时间变换(例如,旋转或平移),而蒙皮(Skins)定义了对象的几何形状如何基于骨架姿势进行变形。相机(Cameras)描述了渲染器的视图配置。

## JSON 结构

场景对象存储在 JSON 文件中的数组中。可以使用对象在数组中的索引来访问它们:

```javascript
"meshes" :
[
{ ... }
{ ... }
...
],
```

这些索引也用于定义对象之间的*关系*。上面的例子定义了多个网格,一个节点可以使用网格索引引用其中一个网格,表明该网格应该附加到这个节点:

```javascript
"nodes":
[
{ "mesh": 0, ... },
{ "mesh": 5, ... },
...
]
```

下图(改编自 [glTF 概念部分](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#concepts))概述了 glTF 资产的 JSON 部分的顶级元素:

<p align="center">
<img src="./gltfTutorial/images/gltfJsonStructure.png" /><br>
<a name="gltfJsonStructure-png"></a>图 2a: glTF JSON 结构
</p>

这里快速总结了这些元素,以提供一个概述,并附有 glTF 规范相应部分的链接。在以下章节中将对这些元素之间的关系进行更详细的解释。

- [`scene`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-scene)(场景)是存储在 glTF 中的场景描述的入口点。它引用定义场景图的 `node`(节点)。
- [`node`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-node)(节点)是场景图层次结构中的一个节点。它可以包含变换(例如,旋转或平移),并且可以引用更多(子)节点。此外,它可以引用"附加"到节点的 `mesh`(网格)或 `camera`(相机)实例,或者引用描述网格变形的 `skin`(蒙皮)。
- [`camera`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-camera)(相机)定义了渲染场景的视图配置。
- [`mesh`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-mesh)(网格)描述出现在场景中的几何对象。它引用用于访问实际几何数据的 `accessor`(访问器)对象,以及定义渲染对象时外观的 `material`(材质)。
- [`skin`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-skin)(蒙皮)定义了顶点蒙皮所需的参数,顶点蒙皮允许基于虚拟角色的姿势对网格进行变形。这些参数的值从 `accessor` 获取。
- [`animation`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-animation)(动画)描述了某些节点的变换(例如,旋转或平移)如何随时间变化。
- [`accessor`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-accessor)(访问器)被用作任意数据的抽象源。它被 `mesh`、`skin` 和 `animation` 使用,并提供几何数据、蒙皮参数和时间相关的动画值。它引用 [`bufferView`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-bufferview)(缓冲区视图),它是包含实际原始二进制数据的 [`buffer`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-buffer)(缓冲区)的一部分。
- [`material`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-material)(材质)包含定义对象外观的参数。它通常引用将应用于渲染几何体的 `texture`(纹理)对象。
- [`texture`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-texture)(纹理)由 [`sampler`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-sampler)(采样器)和 [`image`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-image)(图像)定义。`sampler` 定义了 `image` 纹理应该如何放置在对象上。

## 对外部数据的引用

3D 对象的二进制数据,如几何体和纹理,通常不包含在 JSON 文件中。相反,它们存储在专用文件中,JSON 部分只包含指向这些文件的链接。这使得二进制数据可以以非常紧凑的形式存储,并且可以通过网络高效传输。此外,数据可以以可以直接在渲染器中使用的格式存储,而无需解析、解码或预处理数据。

<p align="center">
<img src="./gltfTutorial/images/gltfStructure.png" /><br>
<a name="gltfStructure-png"></a>图 2b: glTF 结构
</p>

如上图所示,有两种类型的对象可能包含这样的外部资源链接,即 `buffers`(缓冲区)和 `images`(图像)。这些对象将在后面更详细地解释。

## 读取和管理外部数据

读取和处理 glTF 资产从解析 JSON 结构开始。结构解析后,[`buffer`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-buffer) 和 [`image`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-image) 对象分别在顶级 `buffers` 和 `images` 数组中可用。这些对象中的每一个都可能引用二进制数据块。为了进一步处理,这些数据被读入内存。通常,数据将存储在一个数组中,以便可以使用与引用它们所属的 `buffer` 或 `image` 对象相同的索引查找它们。

## `buffers` 中的二进制数据

[`buffer`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-buffer) 包含一个指向包含原始二进制缓冲数据的文件的 URI:

```javascript
"buffer01": {
"byteLength": 12352,
"type": "arraybuffer",
"uri": "buffer01.bin"
}
```

这个二进制数据只是从 `buffer` 的 URI 读取的原始内存块,没有固有的含义或结构。[缓冲区、缓冲区视图和访问器](gltfTutorial_005_BuffersBufferViewsAccessors.md) 部分将展示如何用关于数据类型和数据布局的信息扩展这些原始数据。有了这些信息,一部分数据可能会被解释为动画数据,而另一部分可能会被解释为几何数据。以二进制形式存储数据可以使其通过网络传输比 JSON 格式更高效,而且二进制数据可以直接传递给渲染器,无需解码或预处理。

## `images` 中的图像数据

[`image`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-image) 可以引用可以用作渲染对象纹理的外部图像文件:

```javascript
"image01": {
"uri": "image01.png"
}
```

引用以 URI 的形式给出,通常指向 PNG 或 JPG 文件。这些格式显著减小了文件的大小,以便可以通过网络高效传输。在某些情况下,`image` 对象可能不引用外部文件,而是引用存储在 `buffer` 中的数据。这种间接的细节将在 [纹理、图像和采样器](gltfTutorial_012_TexturesImagesSamplers.md) 部分解释。

## 数据 URI 中的二进制数据

通常,`buffer` 和 `image` 对象中包含的 URI 将指向包含实际数据的文件。作为替代方案,数据可以使用 [数据 URI](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) 以二进制格式*嵌入*到 JSON 中。

上一章: [介绍](gltfTutorial_001_Introduction.md) | [目录](README.md) | 下一章: [最小的 glTF 文件](gltfTutorial_003_MinimalGltfFile.md)
Loading