> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/3d-jian-mo-he-dong-hua/meshes.md).

# 网格

了解导入到 Decentraland 的 3D 模型支持哪些网格属性。

3D 模型有一个 *网格* 由三角形的 *面*. 这些面彼此在 *边* （它们相接的线）上相交，以及 *顶点* （它们的角连接的点）。

{% hint style="info" %}
**💡 提示**: 安装 [Decentraland Tools Blender 插件](https://extensions.blender.org/add-ons/decentraland-tools/)。它包含一些实用功能，可帮助你编辑和导出 3D 模型、穿戴物和表情动作。
{% endhint %}

## 空间限制

场景中的所有 3D 模型都必须位于其地块范围内。如果在预览运行时，你的模型有任何部分超出这些范围，这些超出的部分将被裁切且不会渲染。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c9f4c9448f2fb3c7a2d85a4dd16f31814b0878bf%2Fcut-train.png?alt=media)

在 Creator Hub 编辑器中，你会看到模型被染成红色，其包围盒也以红色标出。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-a44ea3779c9fc579f367e0cbefb2b4218369eab9%2Ftrain-out-of-bounds.png?alt=media)

{% hint style="info" %}
**📔 注意**: 在旧版 Decentraland Web 客户端中，出于性能原因，如果 3D 模型的任何部分超出范围，哪怕只是包围盒超出，整个模型也不会渲染。到了 Decentraland 2.0 桌面客户端，只有模型中超出范围的部分会被裁切。模型中位于场景内的部分会被渲染。
{% endhint %}

## 包围盒

如果你的模型所有顶点都整齐地位于场景区域内，但它有很大的包围盒，且大部分为空并延伸到场景限制之外，那么在 Creator Hub 中整个模型都会被标记为超出场景限制。模型中位于你的地块内的部分会正确渲染，而且你仍然可以发布你的场景。

每个网格都有一个包围盒，它包围着该形状的边界。为了让 3D 模型在 Decentraland 中更易用，请确保其包围盒不要比必要的范围更大地超出模型。

为避免这个问题，你可以清理你的 3D 模型，重置网格的位置和旋转，这样包围盒就不会超出它们所包裹的网格。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-3188e3d33635429246de0f2d7f8f810483135233%2F07-apply-rotations.gif?alt=media)

*在 Blender 中，你可以通过选中对象，按 Ctrl+A，然后应用“所有变换”来做到这一点。*

例如，在模型边缘附近旋转一个子网格时要小心。由于包围盒是立方体，即使网格是圆形的，在旋转 45° 之后，其包围盒的角也可能会伸出来。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-38697f7d74f05eee44d500f06cb076936d1c0eac%2F10-apply-rotation.png?alt=media)

我们建议你烘焙模型中每个网格的旋转和缩放，以确保没有不必要的包围盒超出它们应有的尺寸。

## 三角形限制

由于 Decentraland 是一个开放世界，充满了不同的场景和对象，这些内容会在运行时按需下载（并且位于同一个 3D 空间中），因此优化我们的网格非常重要，以便在游玩时获得良好性能。从这个意义上说，在处理网格时有一些我们始终需要牢记的场景限制：

> n 表示一个场景所占用的地块数量。

* **三角形：** n x 10000 场景中所有模型的三角形总数。
* **高度：** log2(n+1) x 20 高度（米）。
* **文件大小：** 每个地块 15 MB - 最多 300 MB 上传到内容服务器的文件总大小。包括 3D 模型和音频。不包括未上传的文件，例如 node.js 包。
* **单个文件最大 50 MB** 场景中的任何单个文件都不能超过 50 MB，无论场景有多少地块。

更多信息请查看所有场景限制 [这里。](https://docs.decentraland.org/creator/development-guide/scene-limitations/)

{% hint style="warning" %}
**🔥优化提示🔥：增加多边形数量** 一个很有价值的提示是始终跟踪模型的多边形数量。要在 Blender 中做到这一点，你需要在视口叠加面板中开启统计信息。

<img src="https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-b1595d1e8b5529e0d12e99de25246215f1bdc900%2F41-stats.gif?alt=media" alt="" data-size="original">
{% endhint %}

## 大型场景中的网格

创建网格时，我们应该牢记这 2 个最佳实践：

* **模块化：** 将大型网格拆分为更小的模块化部分。例如，不要为整栋建筑使用单个网格，而是可以将建筑拆分为每面墙、每层地板以及建筑的各个部分对应的独立网格。这样可以让 Unity 的视锥体剔除更有效地工作，因为只有可见部分需要被考虑用于渲染。这还会改善内存占用，因为同一个网格可以在不同位置多次重复使用于同一对象（要实现这一点，你需要在 SDK7 场景定义中引用相同网格，或者在从 Blender 导出场景时使用实例而不是重复对象）。
* **包围体**: 确保每个对象的包围体尽可能紧密贴合。包围体中多余的空间会导致对象在不可见时仍被渲染。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-dce0bc9b716ee8b44c7b8daf0d7b9b4e76bdeaa7%2F40-modularity.png?alt=media)

### 什么是视锥体剔除？

视锥体剔除是一种优化技术，它会禁用位于相机视野之外对象的渲染器（网格）。看这两个例子：

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-1330fc3816764d5c82d75f6381929f0321bf0412%2F18-frustum-culling.png?alt=media)

*一个迷宫般的室内关卡。这个普通场景视图显示了所有可见的游戏对象。*

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c33a68dba5eb29a0f36573d3dd2c4e8b73addd0f%2F19-frustum-culling-2.gif?alt=media)

*常规的视锥体剔除只会渲染相机视野内的对象。这是自动的，并且始终会发生。*

## 实例化对象与重复对象

在 Blender 中，复制对象会创建该对象的一个完全独立副本，而实例化对象会创建一个与原始对象共享相同数据的副本。

当对象被复制时，它会创建一个拥有完全独立数据集的新对象，包括其所有几何体、材质和动画。这意味着对原始对象所做的任何更改都不会反映到复制对象上，反之亦然。

另一方面，当对象被实例化时，对原始对象所做的任何更改都会反映到它的所有实例上，反之亦然。这是因为所有实例共享相同的底层数据。

就性能而言，实例化通常比复制高效得多，尤其是在处理复杂场景或大量对象时。这是因为实例化比复制使用更少的内存，因为它不会为每个实例创建新数据。此外，实例化还可以让 Blender 通过将所有实例视为单个对象来优化渲染过程，而不是分别渲染每个重复对象。

总的来说，实例化是提高 Blender 和你的 Decentraland 场景中的性能与工作流效率的强大工具，尤其是在处理大型复杂场景时。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-cc521f833d170857bee4aa12fec1d9f645c46446%2F20-duplicate-objects.png?alt=media)

在某些情况下，当复制树木、植物和路灯等对象时，实例化相比复制能显著提升性能。例如，这个场景有 14 个路灯，它们完全相同。我们知道每个路灯有两种不同的纹理，一种用于灯柱，另一种用于灯体。所以在这种情况下，我们将有两个绘制调用，每种纹理一个。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-717d26a8b05990d9e19f7b3becaac8122de944a3%2F21-duplicate-objects-2.png?alt=media)

在 Blender 中，当你处于克隆和放置元素到空间中的阶段时，你有三种选择：复制、实例化或合并对象。

让我们分析一下每个过程的优缺点。

### 复制对象

| 菜单：  | 对象 ‣ 复制对象 |
| ---- | --------- |
| 快捷键： | Shift-D   |

这会创建一个在视觉上与所选对象完全相同的副本，但它们会被视为不同的对象。因此，当你导出时，每个对象会有 2 次绘制调用，2 \* 14 = 28 次绘制调用，总磁盘占用为 320kb。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-36c86406e9de1a3c1029ab6a77bcbced976f77b7%2F22-duplicate-objects-3.png?alt=media)

### 实例化对象

| 面板：  | 工具栏 ‣ 工具 ‣ 编辑 ‣ 复制链接 |
| ---- | -------------------- |
| 菜单：  | 对象 ‣ 复制链接            |
| 快捷键： | Alt-D                |

这会创建一个新对象，其所有数据都链接到原始对象。如果你在编辑模式中修改其中一个链接对象，所有链接副本都会被修改。变换属性仍然是副本而不是链接，所以你仍然可以自由旋转、缩放和移动，而不会影响其他副本。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-e20a046d7790b5e3f03dce96a9d14e050257cfb5%2F23-instancing.png?alt=media)

*当我们导出这些模型时，绘制调用的数量仍然相同（28）。不过请注意，我们现在只有一个网格，这大大减少了磁盘占用（41 kb）。*

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-99e3bbd682033748343d03febe334f602aba3bcb%2F24-instancing-2.png?alt=media)

*为了保持井然有序，你可以简单地在场景中实例化集合，这样你就可以通过一个文件夹和一个源来控制所有实例。*

{% hint style="info" %}
**💡 提示**: 同样的逻辑也适用于 SDK 端。十四个实体都指向其 `GltfContainer` 相同的 *.glb* 文件时，其行为就像实例：文件只会下载一次，只会转换一次，而且其网格和纹理只会在内存中保存一份，无论有多少实体使用它。把相同内容拆分成十四个几乎相同的 *.glb* 文件相当于重复复制，会让你付出十四次下载和内存中十四份副本的代价。
{% endhint %}

### 合并对象

| 菜单：  | 对象 ‣ 合并 |
| ---- | ------- |
| 快捷键： | Ctrl-J  |

这会将所选对象连接成一个带有单个网格的对象。它在对象模式下工作，会把所有内容合并到最后选中的 *active* 对象中，并要求所有选中对象类型相同。材质会被保留并合并，所以我们的十四个路灯不再是十四个可渲染对象，而是变成一个，引擎只需通过 2 次绘制调用而不是 28 次来绘制它们——每种材质一次。

这三个选项中，只有这一种会真正减少绘制调用，而且值得说明原因：Decentraland 引擎是在运行时根据流式内容构建你的场景的，因此它无法像处理预先烘焙好的内容那样，替你自动分组或批处理重复对象。如果你需要更少的绘制调用，就必须在 Blender 中完成合并。

这种减少并不是没有代价的。合并会同时放弃几项内容：

* **磁盘占用又会增加。** 合并后的网格会存储全部十四个路灯的几何体，因此你失去了实例化带来的节省。
* **视锥体剔除变成要么全有，要么全无。** 只要合并对象的任何部分出现在屏幕上，它就会被完整绘制。沿街分布的十四个路灯几乎总会有一个路灯可见，所以你最终会一直绘制全部十四个——这很容易比你节省下来的绘制调用还要更耗性能。
* **这些部分不再能单独访问。** 你不能再单独移动、播放动画、点击或隐藏某一个路灯，因为最后只剩下一个对象。

要谨慎使用合并：适用于那些总是同时出现在同一地点、从不被交互、而且你已经确认对象数量才是性能瓶颈的许多小道具。对于其他所有情况，实例化才是更好的默认选择。

{% hint style="warning" %}
**📔 注意**: 将十四个独立对象导出到一个单独的 *.glb* 文件中是 **不是** 合并。引擎仍然会看到十四个对象，并且仍然会发出 28 次绘制调用。只有合并网格才会改变这个数量。
{% endhint %}

## 网格命名

为你的网格使用有意义的名称。名称应当提供资产被使用的位置或它所关联的对象部分的上下文。

用于资产命名时，可混合使用 `PascalCase` 和 `snake_case`，我们可以称之为 `PascalSnake_case`。基本规则如下——新词或分隔符（`_`）后面的词以 **大写字母开头。**

* 为你的网格使用有意义的名称 **示例：** 🟢 **建议** 名称 - `剧院`, `电车` 🔴 **避免** 名称 - `未命名.008`, `原始体(1)`, `圆柱体.091`, `_球体-AB`
* 使用下划线 `_` 作为分隔符，以为名称增加更多上下文。把更通用的内容放在前面，把具体信息放在后面。 **示例：** 🟢 **建议** 名称 - `喷泉雕像`, `剧院主墙`, `电车左轮` 🔴 **避免** 名称 - `北_主墙_剧院`, `电车_左前_轮子`

如果有多个对象使用相同的名称，在词后面加上数字： `喷泉雕像01、喷泉雕像02 等。`

## 创建模型的工具

有许多插件和外部工具可以帮助制作资源，让流程更快、更高效，其中有些是免费的，有些需要购买，举例如下：

### 减面

这是一个众所周知的修改器，可用于在保持模型表面结构的同时减少网格的三角面数量。虽然这是一个非常强大的模型优化工具，但请注意，一旦模型被减面，拓扑结构可能会受到影响，从而导致糟糕的拓扑（因为它会把几何体打散成不可预测的碎片）。另一方面，减面会把网格的四边面转换成三角形，使其在被使用后更难修改。从这个角度看 **减面适用于静态模型，但不适合动画模型。**

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-fa7269059815d6b0687b7b6c29ec632463318861%2F42-decimate-01.png?alt=media) ![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-8ae651d7fd4bd8a23c60469f60cc8a572c2ad714%2F43-decimate-02.png?alt=media)

使用减面优化网格的另一种方法是先对模型进行减面，然后再进行适当的重拓扑。这样可以确保结果更可预测，并获得干净的拓扑。

一些可能有用的重拓扑插件有（其中一些是付费的）：

* **Simplygon：** <https://www.simplygon.com/>
* **Speedretopo：** <https://blendermarket.com/products/speedretopo?ref=2>
* **Retopoflow：** <https://blendermarket.com/products/retopoflow>

### 镜像修改器

Blender 中的镜像修改器是一种通过将对象的一半朝任意方向（X、Y、Z）镜像来创建对称模型的工具。当你有对称模型时，它是一个很好的工具，因为它可以减少 3D 建模的时间、UV 展开的时间（因为你只需要展开模型的一部分，其余部分会共享相同的 UV 坐标），并且还能通过避免在本质上是镜像的部分上浪费纹理分辨率来优化你的纹理。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c6259ae5fe095f0e4a22d7af8f8a84f7adfc98c1%2F44-mirror-modifier.png?alt=media)

### 批量重命名

一种非常方便的、轻松更改命名约定的工具是使用 Blender 工具集中内置的批量重命名。要访问它，请到 *编辑* 然后 *批量重命名*.

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c02ecaff9c6765f3b0dcf164a506c4b39d015e9a%2F45-batch-rename.png?alt=media)

选中你想更改名称的对象，直接把默认对象名称替换成新的名称。这个工具提供了不同的方法和资产类型来重命名，所以它非常灵活，也可以用于网格、动画、骨骼等的命名更改。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-6a91a4b355df03a163ec1cb3570753eedd05fc8f%2F47-batch-rename-methods.png?alt=media) ![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-a6c301bd731a96d8813c4120ee554490e480f874%2F46-batch-rename-types.png?alt=media)

## 几何体最佳实践 [#](https://docs.decentraland.org/creator/3d-modeling/meshes/#best-practices-for-geometries)

* 要注意你为 3D 模型添加了多少面，因为面越多，渲染需求就越高。有关场景施加的限制，请参见 [**场景限制**](https://docs.decentraland.org/creator/development-guide/scene-limitations/) 。
* 确保没有隐藏的面，因为它们虽然看不见，但会增加三角形数量。
* 对于应当具有圆润边缘的形状，请将其设置为 *平滑* ，而不是添加额外的面。
* 确保所有面的 *法线* 都朝外而不是朝内。如果你模型中的某些面在渲染时似乎不见了，最可能的原因就是这个。
* 烘焙网格的旋转和缩放，以免其包围盒不必要地向外延伸。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-zh/3d-jian-mo-he-dong-hua/meshes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
