Unity Mesh 初體驗


什么是Mesh

Mesh是Unity中的一個組件,稱為網格組件。通俗的講,Mesh是指模型的網格,3D模型是由多邊形拼接而成,而一個復雜的多邊形,實際上是由多個三角面拼接而成。所以一個3D模型的表面是由多個彼此相連的三角面構成。三維空間中,構成這些三角面的點以及三角形的邊的集合就是Mesh。如下圖所示:

mesh.png

所以建模型就是就是要畫一些列的三角形,而定位一個三角形就是只需要3個頂點而已。很簡單哦。

比如我們要畫一個五邊形,如下:

demo1.png

它有五個頂點,但是在Unity中是通過把它轉換成一系列的三角形來繪制的。所以我們需要想一想用幾個三角形通過什么樣的組合才能拼成這個五邊形呢。

我們可以由(1, 2, 3), (1, 3, 4)和(1, 4, 5)三個三角形組成,

demo2.png

也可以由(2, 1, 5),(2, 4, 5) 和(2, 3, 4)三個三角形組成。

demo3.png

組成同一個形狀的三角形排列方案可以有很多種,但是並不是所有的方案都能組合成我們希望的圖形,比如下面這個:

demo4.png

在Unity Mesh這個類中,數組mesh.vertices就是用於存儲三角形頂點坐標。當頂點數超過3個的時候,我們連接點的順序不同,就會繪制出不同形狀的圖形,所以我們必須要獲得我們想要的連接點的順序。數組mesh.triangles就是用來記錄連接三角形的順序的。由於每繪制一個三角形需要知道其三個頂點的順序,那么繪制n個三角形就需要知道3*n個點的順序。即數組mesh.triangles的長度是3的倍數。

手寫代碼創建Mesh

為了簡單,我們先來學習下如何用代碼創建一個三角形Mesh。

public class MeshDemo : MonoBehaviour { // Use this for initialization void Start () { this.GetTriangle (); } // Update is called once per frame void Update () { } public GameObject GetTriangle () { GameObject go = new GameObject ("Triangle"); MeshFilter filter = go.AddComponent (); // 構建三角形的三個頂點,並賦值給Mesh.vertices Mesh mesh = new Mesh (); filter.sharedMesh = mesh; mesh.vertices = new Vector3[] { new Vector3 (0, 0, 1), new Vector3 (0, 2, 0), new Vector3 (2, 0, 5), }; // 構建三角形的頂點順序,因為這里只有一個三角形, // 所以只能是(0, 1, 2)這個順序。 mesh.triangles = new int[3] {0, 1, 2}; mesh.RecalculateNormals (); mesh.RecalculateBounds (); // 使用Shader構建一個材質,並設置材質的顏色。 Material material = new Material (Shader.Find ("Diffuse")); material.SetColor ("_Color", Color.yellow); // 構建一個MeshRender並把上面創建的材質賦值給它, // 然后使其把上面構造的Mesh渲染到屏幕上。 MeshRenderer renderer = go.AddComponent (); renderer.sharedMaterial = material; return go; } }

代碼比較簡單,里面關於MeshFilter和MeshRenderer,以及Shader相關的知識,這部分我另外會單獨介紹,大家可以先關注Mesh相關的部分。

下面我們再來創建一個稍微復雜一點的五邊形。

public GameObject GetPentagon () { GameObject go = new GameObject ("Pentagon"); MeshFilter filter = go.AddComponent (); Mesh mesh = new Mesh (); filter.sharedMesh = mesh; mesh.vertices = new Vector3[] { new Vector3 (0, 0, 0), new Vector3 (0, 2, 0), new Vector3 (2, 0, 0), new Vector3 (2, -2, 0), new Vector3 (1, -2, 0), }; mesh.triangles = new int[9] {0, 1, 2, 0, 2, 3, 0, 3, 4}; mesh.RecalculateNormals (); mesh.RecalculateBounds (); Material material = new Material (Shader.Find ("Diffuse")); material.SetColor ("_Color", Color.yellow); MeshRenderer renderer = go.AddComponent (); renderer.sharedMaterial = material; return go; }

代碼也很簡單,不再廢話。大家可以自己動手試試看,改變mest.triangles中三角形的順序,看看會產生什么不同的結果。

 

Mesh是Unity內的一個組件,稱為網格組件。3D網格是Unity中最重要的圖形元素。在Unity中存在多種組件用於渲染標准網格或者蒙皮網格、拖尾或者3D線條。

在Unity-》Component-》Mesh組件內,有Mesh Filter,Text Mesh, Mesh Render三個子項。在聖典中可以看到,有四項內容:

比較通俗的理解就是,Mesh是指模型的網格,建模就是建網格。細看Mesh,可以知道Mesh的主要屬性內容包括頂點坐標,法線,紋理坐標,三角形繪制序列等其他有用屬性和功能。因此建網格,就是畫三角形;畫三角形就是定位三個點。

而Mesh Filter內包含一個Mesh組件,可以根據MeshFilter獲得模型網格的組件,也可以為MeshFilter設置Mesh內容。

Mesh Render是用於把網格渲染出來的組件。MeshFilter的作用就是把Mesh扔給MeshRender將模型或者說是幾何體繪制顯示出來。

梳理一下內容,大概就是Unity中的對象就是GameObject,每個GameObject都可以有一個MeshFilter組件(也可以沒有),該組件又有Mesh屬性(這個一定有),而該屬性又有個Ver貼上,也就是一個Vector3數組,儲存着頂點信息。

網格(Mesh)對象擁有頂點及其相關數據(法線和UV坐標)和三角形屬性的屬性。頂點可以任何順序提供,但是法線和UV數組必須有序,這樣索引均與頂點對應(即法線數組的元素0提供頂點0的法線,等等)。頂點為Vector3,代表對象局部空間的點。法線為標准化的Vector3,再一次在本地坐標中代表方向。UV指定為Vector2,但由於Vector2類型沒有成為U和V的字段,因此也就相應的將其轉換為了X和Y。

三角形指定為在頂點數組中充當索引的整數三元組。數組不使用特殊類類表示三角形,而只是一個簡單的整數指數列表。每一個三角形都是以三個為一組,因此,前三個元素定義為第一個三角形,后面三個元素定義為第二個三角形,並依此類推。

三角形的一個重要細節就是拐角處頂點的順序。盡管從哪個拐角開始並不重要,但頂點應予以排序,這樣當俯視三角形的可見外表面時,各個拐角會按順時針轉動。

 

此處也應該知道了UV坐標表示的是什么。

抓取百度百科的信息:

“UV”這里是指u,v紋理貼圖坐標的簡稱(它和空間模型的X, Y, Z軸是類似的). 它定義了圖片上每個點的位置的信息. 這些點與3D模型是相互聯系的, 以決定表面紋理貼圖的位置. UV就是將圖像上每一個點精確對應到模型物體的表面.

扯到UV坐標,想起來有人問的材質,貼圖和紋理有什么區別。其實,除了看到Textures文件夾內都是圖形,和Materials文件夾內都是材質球外,我也不知道這三者有什么區別。對了,材質球可以根據光照、貼圖、紋理進行生成,然后扔給GameObject的Render組件里的Material屬性。

知乎上的回答如下:

 

整個 CG 領域中這三個概念都是差不多的,在一般的實踐中,大致上的層級關系是:
材質 Material包含貼圖 Map,貼圖包含紋理 Texture。

紋理是最基本的數據輸入單位,游戲領域基本上都用的是位圖。此外還有程序化生成的紋理 Procedural Texture。

貼圖的英語 Map 其實包含了另一層含義就是“映射”。其功能就是把紋理通過 UV 坐標映射到3D 物體表面。貼圖包含了除了紋理以外其他很多信息,比方說 UV 坐標、貼圖輸入輸出控制等等。

材質是一個數據集,主要功能就是給渲染器提供數據和光照算法。貼圖就是其中數據的一部分,根據用途不同,貼圖也會被分成不同的類型,比方說 Diffuse Map,Specular Map,Normal Map 和 Gloss Map 等等。另外一個重要部分就是光照模型 Shader ,用以實現不同的渲染效果。

對了,如果導入的模型的網格具有蒙皮信息,Unity會自動創建一個Skinned Mesh Renderer.

注意:在使用Mesh Filter的時候必須同時提供一個Mesh Renderer組件,因為需要將其渲染出來,否則你不見他。

Text Mesh :文件過濾器,用於顯示3D文字的。

Mesh Renderer :網格渲染器。用於渲染網格顯示游戲對象。

Mesh Renderer的Materials可以放置多張貼圖,用於顯示在游戲對象的外表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM