EntityComponentSystemSamples 实战:在 Entities Graphics 中正确使用多子网格(Submesh)与多材质烘焙
2026/9/16 14:05:26 网站建设 项目流程

EntityComponentSystemSamples 实战:在 Entities Graphics 中正确使用多子网格(Submesh)与多材质烘焙

【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples

本文是 EntityComponentSystemSamples 仓库中 HDRP Samples 项目的技术指南,围绕 Submesh 示例场景 展开。该场景演示了 Entities Graphics 如何烘焙带多个 sub-mesh 的 Mesh,以及"一个 Entity 只能绑定一个 Material"这一核心约束下,多材质 GameObject 会被拆分为多个 Entity 的底层行为。读完本文,你将理解 sub-mesh 与材质的对应关系、烘焙拆分的触发条件,并能通过 Entities Hierarchy 窗口亲手验证这一拆分过程,为后续处理复杂网格资源打下基础。

一、示例场景概述

在 HDRP Samples 项目中,Submesh场景位于 6. Misc 目录,是官方用于演示Entities Graphics 多子网格支持的样例。项目主 README 对它的定位是:"Demonstrates using a Mesh with multiple sub-meshes with Entities Graphics"(GraphicsSamples/HDRPSamples/README.md)。

整个场景的构成非常精简:

  • 一个"空壳"主场景 Submesh.unity,只包含 Main Camera、Directional Light、一个地面 Plane 和一个带有AutoLoadScene: 1的 SubScene 组件;
  • 一个 SubScene.unity,内部仅有一个名为Cubes的 authoring GameObject。

也就是说,演示逻辑全部收敛在 SubScene 的单个 GameObject 上——这正是观察"多材质被拆分为多 Entity"的最干净样本。

二、场景里到底有什么:一个 Mesh、三个 Sub-Mesh、三个材质

2.1 Mesh 资源的子网格结构

SubScene 中的CubesGameObject 通过MeshFilter引用了 Cubes.asset 这个 Mesh 资源。打开该资产的 YAML 序列化文件,可以看到m_SubMeshes数组中定义了三个子网格

子网格firstByteindexCountvertexCount包围盒中心 (x)对应立方体
SubMesh 0036240第 1 个立方体
SubMesh 17236243.25第 2 个立方体
SubMesh 214436241.62第 3 个立方体

每个子网格indexCount: 36(即 12 个三角形),vertexCount: 24,正好是一个立方体的标准面数/顶点数;三个子网格共享同一个顶点缓冲区(m_VertexCount: 72),通过firstByte区分各自的索引段。从顶点数据(_typelessdata中的坐标分量)可以看到,三个立方体被放置在 x 轴上的不同位置,最终 Mesh 的整体包围盒为m_Center: {x: 1.625, y: 0, z: 0}m_Extent: {x: 2.125, y: 0.5, z: 0.5}

2.2 材质的挂接方式

CubesMeshRenderer组件上挂了一个长度为 3 的材质数组,分别指向 SceneAssets 下的三个 HDRP Lit 材质(通过.meta中的 guid 可确认对应关系):

  1. Red.mat(guid45b59214118ecdb448f7015259ff6d38)——_BaseColor{r: 1, g: 0, b: 0}
  2. Green.mat(guid02e0265043393054c90dd96499c50df8)——绿色
  3. Blue.mat(guidc45ea55d5584dec4d917f1447b823b5d)——蓝色

材质本身是标准的 HDRP Lit 材质(m_Shader指向 HDRP Lit shader,m_SurfaceType: 0为 Opaque,m_CustomRenderQueue: 2225),未使用任何纹理,仅通过_BaseColor区分颜色,目的就是让拆分结果在 Entities Hierarchy 中一目了然。

在传统 GameObject 渲染管线中,MeshRenderer会把第 N 个材质按顺序应用到第 N 个子网格上,即"红、绿、蓝"三色立方体由一个 GameObject 一次绘制完成。

三、核心机制:为什么一个 GameObject 会被烘焙成多个 Entity

3.1 Entities Graphics 的"一 Entity 一材质"约束

这是本示例要演示的最关键原理Entities 只支持一个 Entity 绑定一个 Material(原文:"Entities support only a single Material per Entity")。

Entities Graphics 的数据组织以RenderMesh组件为核心,一个 Entity 对应一份 Mesh + Material 的组合。因此当烘焙器(Baker)遇到"一个 Mesh 带多个子网格 + 多个材质"的 authoring GameObject 时,无法用一个 Entity 完整表达,只能执行拆分策略:

把该 GameObject 按"材质"维度拆分为若干 Entity,每个 Entity 持有原始 Mesh 的一个子网格,并绑定对应的那个 Material。

场景中的Cubes有 3 个子网格、3 个材质,于是被烘焙成3 个独立的 Entity,分别对应红色立方体、绿色立方体、蓝色立方体。每个 Entity 的 Mesh 都是原始CubesMesh 的其中一个 sub-mesh,材质则各取其一。

3.2 与烘焙管线的对应关系

这一行为发生在 SubScene 的 baking 阶段。从场景配置可以验证:

  • Submesh.unity 中的 SubScene 组件引用 SubScene.unity;
  • SubScene 内的Cubes在烘焙时由MeshRenderer组件触发生成RenderMesh相关组件;
  • 多材质导致拆分后,运行时 / Entities Hierarchy 中呈现为多个 Entity,但它们共享同一个网格顶点缓冲与索引缓冲(体现在Cubes.asset中三份子网格共享m_VertexData),只是绘制时各自取用对应的子网格索引区间和材质。

换句话说,拆分是"逻辑层"的拆分,GPU 侧的顶点数据仍然是一份,这保证了拆分的开销很小。

四、动手验证:在 Entities Hierarchy 中观察拆分结果

4.1 操作步骤

原文档给出了完整的验证流程,逐条对照执行即可:

  1. 确保 Hierarchy 中 SubScene 处于关闭状态——SubScene 未打开时,其中的内容以 Entity 形式存在于实体世界中,而不是作为 GameObject 暴露在普通场景层级中;
  2. 打开菜单Window > Entities > Hierarchy,调出实体层级窗口;
  3. 在窗口中定位到该 SubScene(导航到 SubScene 对应节点);
  4. 展开其下"带层级结构的 Entity"(即烘焙自Cubes的那组 Entity);
  5. 观察:存在三个 Entity,它们全部由同一个 authoring GameObject 烘焙而来。

4.2 预期看到的验证结果

展开后,你会看到类似下面的结构(以官方描述为准,具体节点命名以打开场景时为准):

  • 一个父级 Entity(对应烘焙后的整体,通常携带 Transform 等信息);
  • 其下 3 个子 Entity:
    • Entity A —— 红色立方体(Cubes 子网格 0 + Red.mat)
    • Entity B —— 绿色立方体(Cubes 子网格 1 + Green.mat)
    • Entity C —— 蓝色立方体(Cubes 子网格 2 + Blue.mat)

这 3 个 Entity 的 Mesh 引用都指向同一个CubesMesh 资源,区别在于子网格索引与材质引用不同。这就是"多材质 GameObject → 多 Entity"的最直观证据。

五、延伸思考:多子网格资源在实际项目中的处理建议

5.1 何时该用多子网格

Unity 的 Mesh 支持"一个资源含多个子网格",常见于以下场景:

  • 共享顶点数据的组合体:多个部件(如汽车车身、车轮、车窗)合并成一个 Mesh 资源,但需要不同材质;
  • 美术 DCC 工具导出的合并网格:模型在建模软件中合并导出后自带多个 material slot;
  • LOD / 部件分离:运行时按需绘制部分子网格。

在上述场景中引入 Entities Graphics 时,本示例揭示的拆分行为会自动生效:无需手动改造美术资源,烘焙器会自动按材质把资源拆成多个 Entity

5.2 从拆分机制出发的实用建议

  • 性能权衡:拆分会增加 Entity 数量与 Draw Call 数量(一个子网格+一个材质 = 一次绘制)。如果某些子网格使用同一材质,可以考虑在 DCC 工具中合并,减少拆分后的 Entity 数量;
  • 材质一致性:由于拆分粒度是"按材质",保证同一视觉单元的子网格尽量使用同一材质,可以让烘焙结果更紧凑;
  • 运行时修改:拆出来的每个 Entity 拥有独立的RenderMesh数据,运行时可按 Entity 单独替换材质或隐藏/显示,这比在传统管线中切换整个 Renderer 的材质数组更符合 ECS 的数据驱动风格(仓库中 MaterialMeshChange 场景对此有更专门的演示);
  • URP 同样适用:本示例在 URPSamples 项目中也有对应副本,说明该拆分行为是 Entities Graphics 的通用规则,与渲染管线(HDRP/URP)无关。

六、相关资源索引

  • 示例 README:GraphicsSamples/HDRPSamples/Assets/SampleScenes/6. Misc/Submesh/README.md
  • 运行效果截图:GraphicsSamples/HDRPSamples/READMEimages/Submesh.png
  • 主场景:Submesh.unity(含 SubScene 组件与基础灯光/相机)
  • SubScene 内容:Subscenes/SubScene.unity(含唯一的Cubesauthoring GameObject)
  • 多子网格 Mesh 资源:SceneAssets/Cubes.asset(3 个子网格,共享 72 个顶点)
  • 三个材质:Red.mat、Green.mat、Blue.mat
  • HDRP 项目样例总览:GraphicsSamples/HDRPSamples/README.md
  • URP 同款示例:GraphicsSamples/URPSamples/Assets/SampleScenes/6. Misc/Submesh/README.md

七、小结

通过本示例可以确认 Entities Graphics 对多子网格 Mesh 的处理规则:一个 Entity 只能持有一种材质,因此带多材质子网格的 authoring GameObject 会在烘焙时被自动拆分为多个 Entity,每个 Entity 共享网格数据、各自绑定一个子网格和一个材质。在实际项目中,理解这一机制有助于预估 Entity 数量与 Draw Call 开销,并为美术资源合批策略提供决策依据。如果你需要进一步探索 Entities Graphics 的其他能力,仓库中的 MaterialMeshChange(运行时换材质/网格)与 RenderMeshUtilityExample(运行时创建渲染实体)场景是很好的下一站。

【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询