前言:
Unity自帶幾種簡單的模型,如cube等;一般情況下,其余模型有3D建模軟件生成,以合適的文件格式導入unity中;而mesh(以我目前很粗淺的了解)的一般用途就是:對現有的模型進行變形,以達到各種奇幻酷炫的表現效果。
但是由於自己的項目需要,需要由數據(外部解釋stl文件獲得)按照特定情況以及要求實時地產生各種幾何模型,故需要用Mesh進行建模。所以開始研究學習Mesh。
一、引入
3D世界中任何的面都是由三角形繪制完成的,因為任何無規則的集合圖形都可以由三角形來組成。比如四邊形,無論是正四邊形還是無規則四邊形都可以由兩個三角形拼接而成。如下圖,模型上的一個個小網格就是Mesh,這些Mesh有不同的三維頂點(Vector3),共同組成了一個3D模型。

二、正文
知識點說明:
1.Mesh、MeshFilter、MeshRenderer關系整理
在Unity3D中創建一個Cube,在Inspector可以看到其中含有MeshFilter、MeshRenderer組件。
MeshFilter含有一個Public成員 Mesh。
在Mesh中存儲着三維模型的數據:vertices(頂點數據數組Vector3[])、triangles(三角形頂點索引數組,int[])、normals(法線向量數組,Vector3[])、uv(紋理坐標數組,Vector2[])。
2.
Unity3D中Mesh的基本單位是三角形,故而從最基本最簡單的等腰三角形開始畫起。
Mesh是Unity內的一個組件,稱為網格組件。
- Mesh 網格
- MeshFilter 網格過濾器
- Mesh Renderer 網格渲染器
Mesh:是指模型的網格,建模就是建網格。細看Mesh,可以知道Mesh的主要屬性內容包括頂點坐標,法線,紋理坐標,三角形繪制序列等其他有用屬性和功能。因此建網格,就是畫三角形;畫三角形就是定位三個點。
Mesh Filter:內包含一個Mesh組件,可以根據MeshFilter獲得模型網格的組件,也可以為MeshFilter設置Mesh內容。
Mesh Render:是用於把網格渲染出來的組件。MeshFilter的作用就是把Mesh扔給MeshRender將模型或者說是幾何體繪制顯示出來。
它們之間的關系大概就是Unity中的對象就是GameObject,每個GameObject都可以有一個MeshFilter組件(也可以沒有),該組件又有Mesh屬性(這個一定有),而該屬性又有頂點坐標,法線等屬性。而如果GameObject里有MeshFilter,則必須要Mesh Renderer才能將此網格渲染出來,不然是看不見該網格的。
Mesh的屬性:
- 頂點坐標(vertex)
- 法線(normal)
- 紋理坐標(uv)
- 三角形序列(triangle)
頂點坐標:頂點坐標數組存放Mesh的每個頂點的空間坐標,假設某mesh有n個頂點,則vertex的size為n
法線:法線數組存放mesh每個頂點的法線,大小與頂點坐標對應,normal[i]對應頂點vertex[i]的法線
紋理坐標:它定義了圖片上每個點的位置的信息. 這些點與3D模型是相互聯系的, 以決定表面紋理貼圖的位置. UV就是將圖像上每一個點精確對應到模型物體的表面. uv[i]對應vertex[i]
三角形序列:每個mesh都由若干個三角形組成,而三角形的三個點就是頂點坐標里的點,三角形的數組的size = 三角形個數 * 3. 說白了:規定繪制的順序(點連接的順序)
例如:某mesh有四個頂點0,1,2,3,
V0(1, 1, 0),
V1(-1, 1, 0),
V2(1, -1, 0),
V3(-1, -1, 0)
那么它們可以組成這樣的一個網格,
tri[0] = ver[0],ver[3],ver[1],tri[1] = ver[0],ver[2],ver[3],

注意:三角形的頂點順序必須是順時針,順時針表示正面,逆時針表示背面,而unity3d在渲染時默認只渲染正面,背面是看不見的。
那么該三角形可以表示為:
tri = new int[2 * 3]{0, 3, 1, 0, 2, 3};
如何要獲取第N個三角形對應的三個頂點坐標,則:v1 = tri[N*3 + 0], v2 = tri[N*3 + 1], v3 = tir[N*3 + 2]
參照的案例(配合上述的知識點)【此事例參照他人】
1.創建一個GameObject並添加MeshFilter以及MeshRender組件,並創建一個“CreateMesh.cs”腳本給它。
2.獲取該對象的filter組件,並創建一個mesh給它。
3.為該mesh設置屬性,這里先設置頂點,然后將三角形與頂點綁定
using UnityEngine;
using System.Collections;
public class CreateMesh : MonoBehaviour {
private MeshFilter filter;
private Mesh mesh;
// Use this for initialization
void Start () {
// 獲取GameObject的Filter組件
filter = GetComponent<MeshFilter>();
// 並新建一個mesh給它
mesh = new Mesh();
filter.mesh = mesh;
// 初始化網格
InitMesh();
}
// Update is called once per frame
void Update () {
}
/// <summary>
/// Inits the mesh.
/// </summary>
void InitMesh()
{
mesh.name = "MyMesh";
// 為網格創建頂點數組
Vector3[] vertices = new Vector3[4]{
new Vector3(1, 1, 0),
new Vector3(-1, 1, 0),
new Vector3(1, -1, 0),
new Vector3(-1, -1, 0)
};
mesh.vertices = vertices;
// 通過頂點為網格創建三角形
int[] triangles = new int[2 * 3]{
0, 3, 1, 0, 2, 3
};
mesh.triangles = triangles;
}
}
效果如圖:

3.網格已經成功生成,接下來該給網格貼圖了,在Inspector視圖里選中Mesh Render,並拖一個材質給它,
Mesh Render是負責渲染的,將Mesh Filter里的mesh通過自身的Materials渲染出來。
設置完材質后,我們需要將紋理貼圖與網格頂點一一對應起來,這樣才能渲染出來。
// 為mesh設置紋理貼圖坐標 Vector2[] uv = new Vector2[4]{ new Vector2(1, 1), new Vector2(0, 1), new Vector2(1, 0), new Vector2(0, 0) }; mesh.uv = uv;
效果如圖:

4.mesh還有兩個重要的屬性,法線和顏色,這兩個我不是很懂,暫時沒加入,
不過看了下自帶的cube模型的mesh,每個頂點的法線好像就是設置為那個頂點所在的面的法線。
不過肯定不是這樣的,畢竟要是兩個不在同一面的面共有一個頂點,那就不成立了。
自己做的案例:(最簡單粗暴地顯示出一個三角形)
1 using UnityEngine; 2 using System.Collections; 3 [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))] 4 public class triangle_mesh : MonoBehaviour 5 { 6 /* 7 creat a triangle by using Mesh 8 2016/11/19 9 ————Carl 10 */ 11 12 void Start() 13 { 14 MeshFilter meshfilter = new MeshFilter(); 15 meshfilter = GetComponent<MeshFilter>(); 16 Mesh mesh = new Mesh(); 17 Vector3[] vertices = new Vector3[3]; 18 vertices[0] = new Vector3(0, 0, 0); 19 vertices[1] = new Vector3(0, 0, 1); 20 vertices[2] = new Vector3(1, 0, 0); 21 int[] tris = new int[3]; 22 tris[0] = 0; tris[1] = 1; tris[2] = 2; 23 Vector2[] uvs = new Vector2[vertices.Length]; 24 for (int i = 0; i < uvs.Length; i++) 25 { 26 uvs[i] = Vector2.zero; 27 } 28 29 mesh.vertices = vertices; 30 mesh.triangles = tris; 31 mesh.uv = uvs; 32 meshfilter.mesh = mesh; 33 } 34 }
效果圖:

程序說明:
1)







2)
RequireComponent這一行,表示我們需要MeshRenderer和MeshFilter這兩個組件,當我們將TestTriangle的代碼掛在GameObject上的時候,會自動添加這兩個組件。而我們要移除MeshRenderer或MeshFilter的時候,編輯器就會提示不能移除。
ExecuteInEditMode表示會在編輯器模式下運行。
uv暫時我們用不到,所以全部設為零。在后面文章中將介紹uv的用法。
總結:
用Unity繪制三角形
首先,creat a gameobject
其次,掛在一個腳本,並且,添加 MeshRenderer,MeshFilter組件
再其次:給出Mesh的: mesh.vertices = vertices;//點 mesh.triangles = tris;//索引點 mesh.uv = uvs;//紋理
最后:meshfilter.mesh = mesh;//添加於MeshFilter組件
【歡迎轉載】
轉載請表明出處: 樂學習
