Procedural Mesh Geometry
Using the Mesh Class

网格剖析

网格由 3D 空间中排列的三角形组成,旨在产生实体对象的效果。三角形由其拐点或者顶点定义。在 Mesh 类中,顶点全部存储在单个数组中,并且每个三角形使用与顶点数组的索引对应的三个整数指定。这些三角形还将全部集合在一个整数数组中;从该数组的开头以三个为一组的方式解读数组中的整数,因此元素 0、1 和 2 定义第一个三角形,3、4 和 5 定义第二个三角形,依此类推。任何给定的顶点都可以根据需要,尽可能多的在三角形中重复使用,有些情况不需要这样做(请参阅下文)。

光照和法线

三角形足以定义对象的基本形状,但在大多数情况下需要额外的信息来显示网格。为了让对象正确着色以获得光照,必须为每个顶点提供法向矢量。法线是向外指向的矢量,垂直于与其相关联的顶点位置处的网格表面。在着色计算期间,会将每个顶点法线与入射光的方向进行比较(入射光也是矢量)。如果两个矢量完全对齐,则会在该位置表面正面接收光照,并会将全部光照亮度用于着色。与法向矢量完全相反的光不会在该位置表面产生任何光照。通常情况下,到达的光线与法线之间呈一定的角度,因此着色将介于全亮和全暗之间,具体取决于角度大小。

由于网格由三角形组成,因此法线在拐点处可能垂直于三角形平面。然而,对整个三角形插值计算两个拐点中间位置的表面方向的法线。如果三条法线指向同一个方向,则三角形将被完整照亮。单独给三角形均匀着色,三角形的边缘效果非常清晰并且明显不同。这种效果正是立方体模型或其他锋利边缘实体所需的,但可使用法线的插值创建平滑着色以便模拟曲面。

为了获得清晰的边缘,有必要在每条边上使顶点数量加倍,因为两个相邻的三角形都需要它们自己独立的法线。 对于曲面,通常在边上共享顶点,但往往需要通过直觉来确定共用法线的最佳方向。一条法线可能是周围三角形的平面法线的平均值。但是,对于像球体这样的对象,法线应该直接从球体的中心指向外部。

通过调用 Mesh.RecalculateNormals,让 Unity 通过对网格几何形状的“意义”进行一些假设来计算法线的方向;假设三角形之间共享的顶点表示光滑的表面,而加倍的顶点表示清晰的边缘。虽然在大多数情况下这不是糟糕的近似算法,在遇到一些纹理处理情况时重新计算法线会有问题,此类情况下即使表面光滑,顶点也必须加倍。

纹理

除了光照,模型通常还会使用纹理技术在其表面上创建精细的细节。纹理有点像在可拉伸的橡胶片上印刷的图像。每个网格三角形都要求定义纹理图像的三角形区域,并对纹理三角形进行拉伸和“固定”以拟合网格三角形。为了确保此过程顺利进行,每个顶点需要存储将顶点固定图像位置的坐标。这些坐标是二维坐标并缩放到 0..1 范围内(0 表示图像的左下角,1 表示右上角)。为了避免将这些坐标与 3D 世界的笛卡尔坐标混淆,称为 U 和 V 而不是更熟悉的 X 和 Y,因此通常称作 UV 坐标。

与法线一样,纹理坐标对于每个顶点都是唯一的,有时为了在边上获得不同的 UV 值,需要将顶点加倍。一个明显的例子是两个相邻的三角形使用纹理图像的不连续部分(例如,面部纹理上的眼睛)。此外,大多数完全封闭的对象都需要一条“接缝”,此处的一个纹理区域会环绕并连接在一起。接缝一侧的 UV 值与另一侧的 UV 值不同。

另请参阅

Procedural Mesh Geometry
Using the Mesh Class