Skip to main content

网格

概念

什么是Mesh(网格)?

  • 定义:Mesh是Unity中描述3D模型形状的数据结构,由顶点(Vertices)、**边(Edges)三角面(Triangles)**构成。
  • 作用:图形硬件通过Mesh数据渲染物体,所有可见的3D模型(如角色、场景)均依赖Mesh呈现。

Mesh的组成要素

  • 顶点(Vertices):三维空间中的坐标点(Vector3数组),定义模型的基础形状。
  • 三角面(Triangles):通过顶点索引(int数组)连接三个顶点形成的面,顺序决定法线朝向(顺时针为正面)。
  • 法线(Normals):垂直于三角面的向量(Vector3数组),影响光照计算。
  • UV坐标:二维纹理映射坐标(Vector2数组),控制贴图如何包裹模型

渲染流程

  • Mesh Filter:存储Mesh数据(如顶点、三角面)。
  • Mesh Renderer:接收Mesh数据并渲染,依赖材质(Material)决定外观。

面试题

1. Mesh Filter和Mesh Renderer的作用与区别?

答案

  • Mesh Filter:存储网格数据(顶点、三角面等),不参与渲染。

  • Mesh Renderer:负责将Mesh Filter中的网格数据渲染到屏幕上,依赖材质(Material)和光照。

  • 扩展:修改Mesh Filter.mesh会创建新实例,而MeshFilter.sharedMesh共享同一网格数据。

2. 如何动态生成或修改网格?

Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[] { /* 定义顶点 */ };
int[] triangles = new int[] { /* 定义三角面索引 */ };
mesh.vertices = vertices;
mesh.triangles = triangles;
GetComponent<MeshFilter>().mesh = mesh;
  • 注意:需手动计算法线(mesh.RecalculateNormals())和UV坐标。

3. LOD(Level of Detail)的实现原理与优化策略?

答案

  • 原理:根据摄像机距离切换不同精度的网格(如高模→低模→广告牌)。

  • 实现:使用LOD Group组件,设置不同距离的渲染器。

  • 优化

  • 动态生成LOD网格(如边折叠算法)。

  • 基于屏幕覆盖度调整切换阈值。

4. 静态合批(Static Batching)与动态合批(Dynamic Batching)的条件与限制?

静态合批

  • 条件:物体标记为Static,使用相同材质。

  • 限制:增加内存占用(合并后的网格不可动态修改)。

  • 动态合批

  • 条件:顶点数≤300,使用相同材质和光照参数。

  • 限制:不支持SkinnedMeshRenderer。

5. 网格简化(Mesh Simplification)的常用算法与工具?

算法

  • 边折叠:合并相邻边,保留几何特征(如UnityMeshSimplifier插件)。

  • 顶点聚类:快速但精度低(适合背景物体)。

  • 工具:Simplygon、Unity ProBuilder(基础简化功能)。

6. Skinned Mesh Renderer的工作原理?如何优化骨骼动画性能?

答案

  • 原理:顶点受骨骼权重影响,骨骼变换时驱动顶点变形。

  • 优化

  • 减少骨骼数量(如角色≤30根)。

  • 使用GPU蒙皮(SkinnedMeshRenderer.skinningMode = SkinningMode.BoneMatrix)。

7. 如何实现网格溶解或切割效果?

  • Shader方案

  • 溶解:通过噪声图控制片元裁剪(clip(noise.r - threshold))。

  • 切割:使用几何着色器(Geometry Shader)生成剖面网格。

8. 如何检测网格导致的性能瓶颈?

工具

  • Frame Debugger:查看DrawCall和合批情况。

  • Profiler:分析Rendering.MeshAnimation.Skinning耗时。

  • 常见问题

  • 未合批的网格:材质实例过多或动态修改顶点。

  • 高蒙皮开销:骨骼数量过多或未启用GPU蒙皮。

9. MeshCollider与其他碰撞器的性能对比?

  • MeshCollider

  • 优点:精确匹配网格形状。

  • 缺点:性能开销大(需转换为物理引擎支持的凸包)。

  • 替代方案:简单碰撞器(Box/Sphere Collider)或凸包近似。

10. 为什么修改网格后看不到渲染结果?

原因

  • 未调用mesh.UploadMeshData(true)提交修改。
  • 法线/UV数据缺失导致光照或贴图错误。

11. 如何实现动态地形编辑(如挖洞)?

方案

  • 运行时修改顶点:移除或移动三角面顶点。
  • Marching Cubes算法:基于体素生成新网格。