一 模型的构成
在三维世界中,绘制一个模型并不是什么很复杂的问题。只要知道了基本原理一切需求便迎刃而解。
如下图所示,任何模型都是由点线面构成的,而面的最小单位是三角形。
任何一个多边形的面,都是由多个三角形构成的。比如一个四边形,就是由ab两个三角形构成的。
构成一个正方形的两个三角形,可以由四个点构成,也可以由六个点构成。下图就是由四个点构成的正方形,两个三角形分别是abc和adb。
一个三角形,由三个点组成。在计算机渲染图形的时候,会根据三个点的位置来对他们包围的图形区域进行补间操作,补间出来的部分就是我们看到的面。构成三角形的点叫顶点(vertex),而决定顶点顺序的(面的正反朝向)叫做索引(indect)。在unity中,只需要顶点信息和索引信息就可以完成建模。
二 关于建模的关键字
vertex / point :顶点。顶点相当于模型的骨架,顶点决定模型的具体形状,所有构成面的三角形都是根据点来生成的。所以顶点是基础,是核心,是根本。
face:面。由任意三个顶点构成的三角形,就是最基础的面。任何复杂的多边形都是由无数个三角形构成的面所组成的。
line:线。两点之间的直线。
indect:索引。我们已经有了一个模型的顶点,想要画出一个三角形,必须要知道想要用到哪几个顶点,以及这些顶点的顺序。所以保存面的构成信息的集合就叫索引。
例如上面这个正方形的面,他的顶点信息由abcd构成,而他的索引信息是:acbabd。
从这个索引信息我们可以看出:
1,你可能会发现这个集合是由acb,abd组成的,也就是说索引是由每三个一组的顶点编号组成的,索引的总数一定是可以被3整除的。
2,每组三角形索引都是有固定的顺序。逆时针的话渲染出来的面就是正向,顺时针就是逆向。顶点信息是可以乱序的,但索引的顺序不可以乱序。
三 unity绘制模型
通过以上的基础学习,我们知道了模型的渲染原理和结构成分,接下来我们试着用unity通过顶点信息绘制一个模型
以下代码 可以在unity场景中绘制一个模型
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BuildModel: MonoBehaviour
{
// 该组件用于在场景中渲染mesh,关于模型网格的一切操作都在这里进行
MeshFilter meshFilter;
//模型的顶点集合
List<Vector3> verts = new List<Vector3>();
//顶点序列
List<int> indices = new List<int>();
void Start()
{
meshFilter = GetComponent<MeshFilter>();
Generate();
}
void Generate()
{
ClearMeshData();
AddMeshData();
Mesh mesh=new Mesh();
mesh.vertices = verts.ToArray();
mesh.triangles = indices.ToArray();
//计算法线
mesh.RecalculateNormals();
//计算物体的边界
mesh.RecalculateBounds();
meshFilter.mesh = mesh;
}
void ClearMeshData()
{
verts.Clear();
indices.Clear();
}
void AddMeshData()
{
verts.Add(new Vector3(0, 0, 0));
verts.Add(new Vector3(0, 1, 0));
verts.Add(new Vector3(1, 1, 0));
verts.Add(new Vector3(1, 0, 0));
verts.Add(new Vector3(1, 0, 0));
verts.Add(new Vector3(1, 1, 0));
verts.Add(new Vector3(1, 1, 1));
verts.Add(new Vector3(1, 0, 1));
verts.Add(new Vector3(0, 1, 0));
verts.Add(new Vector3(0, 1, 1));
verts.Add(new Vector3(1, 1, 1));
verts.Add(new Vector3(1, 1, 0));
verts.Add(new Vector3(0, 0, 0));
verts.Add(new Vector3(1, 0, 0));
verts.Add(new Vector3(1, 0, 1));
verts.Add(new Vector3(0, 0, 1));
verts.Add(new Vector3(0, 0, 1));
verts.Add(new Vector3(1, 0, 1));
verts.Add(new Vector3(1, 1, 1));
verts.Add(new Vector3(0, 1, 1));
verts.Add(new Vector3(0, 0, 0));
verts.Add(new Vector3(0, 0, 1));
verts.Add(new Vector3(0, 1, 1));
verts.Add(new Vector3(0, 1, 0));
for (int i = 0; i <= 20; i+=4)
{
indices.Add(0 + i);
indices.Add(1 + i);
indices.Add(2 + i);
indices.Add(0 + i);
indices.Add(2 + i);
indices.Add(3 + i);
}
}
}