最近unity开了一个shader的入门教程,感觉还是蛮不错的,趁着这个机会写一个学习笔记吧。

Mesh 是指模型的网格,建模就是建网格。细看Mesh,可以知道Mesh的主要属性内容包括顶点坐标,法线,纹理坐标,三角形绘制序列等其他有用属性和功能。
而MeshFilter中包含Mesh属性,感觉可以理解为是一个Mesh的控制器,我们输入的Mesh数据最终是通过MeshFilter去选择并呈现出来的。如上图,我们可以在MeshFilter的Mesh属性中选择其他类型的Mesh,最终模型会呈现出不同的形状。
可进一步参考:
Unity中Mesh Filter、Mesh Renderer的作用_穿行高原的博客-CSDN博客_meshfilter
一个Mesh通常会包含以下几种属性。
1)Vertices 顶点数组 Vector3[]
2)Topology 拓扑类型:可以理解为它是图形表面排列结构的组成方式,Unity给我们提供了5种拓扑类型,三角面、四边形、线条、虚线、点阵,最常用的则是三角面。往往由Index data 索引数据的个数决定是什么类型。
3)Indices 索引数组 int[]:它是每个三角面顶点 的索引,可以理解为他存储了构网格三角面所用到的顶点索引。
5)Normal 法线 Vector3[]
6)Tangent 切线 Vector3[]
7)UV 纹理坐标 Vector2[]:上面所说的UV坐标其实就是它,U增长的方向就是切线的方向,它和三维空间的X, Y, Z较为类似,它是一个二维的坐标系统,模型网格除了有三维空间的xyz坐标外,还有一个二维的UV坐标,在UV坐标中,U和V分别代表顶点在Texture水平和垂直方向上的采样坐标,这些坐标通常位于(0,0)和(1,1)之间,(0,0)代表最左下角,而(1,1)代表最右上角。这就跟平时装修房子贴墙纸一样,可以理解为它是Texture映射到模型表面的依据,模型顶点 会依据UV坐标对Texture进行采样。
8)Index data 索引数据:这个数据取决于拓扑类型,如果是三角面他储存的就是[0,1,2],四边形储存的就是[0,1,2,3],这个索引数值对应的就是顶点数组的下标。
可以说MeshFilter 网格过滤器与Mesh 网格决定了这个物体是什么形状的,而MeshRenderer与Material决定这个gameobject会呈现出怎么样的色彩变化,Mesh是骨骼,Material是皮肤。
与MeshFilter跟Mesh的关系类似。MeshRenderer 可以理解为是一个Material 的控制器,我们输入的Material 数据最终是通过MeshRenderer 去选择并呈现出来的。

将下面的代码附在一个plane上,便可以看到通过脚本创建的正方体了。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CH1 : MonoBehaviour
- {
- // 顶点数组 模型空间顶点坐标
- Vector3[] vertices =
- {
- // Front
- // point[1]
- new Vector3(-2.0f, 5.0f, -2.0f),//[0]
- // point[2]
- new Vector3(-2.0f, 0.0f, -2.0f),//[1]
- // point[3]
- new Vector3(2.0f, 0.0f, -2.0f),//[2]
- // point[4]
- new Vector3(2.0f, 5.0f, -2.0f),//[3]
-
- // Left
- new Vector3(-2.0f, 5.0f, -2.0f),//[4]
- new Vector3(-2.0f, 0.0f, -2.0f),//[5]
- new Vector3(-2.0f, 0.0f, 2.0f),//[6]
- new Vector3(-2.0f, 5.0f, 2.0f),//[7]
-
- // Back
- new Vector3(-2.0f, 5.0f, 2.0f),//[8]
- new Vector3(-2.0f, 0.0f, 2.0f),//[9]
- new Vector3(2.0f, 0.0f, 2.0f),//[10]
- new Vector3(2.0f, 5.0f, 2.0f),//[11]
-
- // Right
- new Vector3(2.0f, 5.0f, 2.0f),//[12]
- new Vector3(2.0f, 0.0f, 2.0f),//[13]
- new Vector3(2.0f, 0.0f, -2.0f),//[14]
- new Vector3(2.0f, 5.0f, -2.0f),//[15]
-
- // Top
- new Vector3(-2.0f, 5.0f, 2.0f),//[16]
- new Vector3(2.0f, 5.0f, 2.0f),//[17]
- new Vector3(2.0f, 5.0f, -2.0f),//[18]
- new Vector3(-2.0f, 5.0f, -2.0f),//[19]
-
- // Bottom
- new Vector3(-2.0f, 0.0f, 2.0f),//[20]
- new Vector3(2.0f, 0.0f, 2.0f),//[21]
- new Vector3(2.0f, 0.0f, -2.0f),//[22]
- new Vector3(-2.0f, 0.0f, -2.0f),//[23]
- };
- // 索引数组
- int[] triangles =
- {
- // Front
- 2,1,0,
- 0,3,2,
-
- // Left
- 4,5,6,
- 4,6,7,
-
- // Back
- 9,11,8,
- 9,10,11,
-
- // Right
- 12,13,14,
- 12,14,15,
-
- // Top
- 16,17,18,
- 16,18,19,
-
- // Buttom
- 21,23,22,
- 21,20,23,
- };
- // UV数组
- Vector2[] uvs =
- {
- // point[1]
- new Vector2(0.0f, 1.0f),
- // point[2]
- new Vector2(0.0f, 0.0f),
- // point[3]
- new Vector2(1.0f, 0.0f),
- // point[4]
- new Vector2(1.0f, 1.0f),
-
- // Left
- new Vector2(1.0f, 1.0f),
- new Vector2(1.0f, 0.0f),
- new Vector2(0.0f, 0.0f),
- new Vector2(0.0f, 1.0f),
-
- // Back
- new Vector2(1.0f, 1.0f),
- new Vector2(1.0f, 0.0f),
- new Vector2(0.0f, 0.0f),
- new Vector2(0.0f, 1.0f),
-
- // Right
- new Vector2(1.0f, 1.0f),
- new Vector2(1.0f, 0.0f),
- new Vector2(0.0f, 0.0f),
- new Vector2(0.0f, 1.0f),
-
- // Top
- new Vector2(0.0f, 1.0f),
- new Vector2(1.0f, 1.0f),
- new Vector2(1.0f, 0.0f),
- new Vector2(0.0f, 0.0f),
-
- // Bottom
- new Vector2(0.0f, 0.0f),
- new Vector2(1.0f, 0.0f),
- new Vector2(1.0f, 1.0f),
- new Vector2(0.0f, 1.0f),
- };
- // Start is called before the first frame update
- void Start()
- {
- GameObject g = new GameObject("MyCube");
- g.AddComponent
(); - g.AddComponent
(); - // 新建一个Mesh
- Mesh mesh = new Mesh();
- // 用构建的数据初始Mesh
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- mesh.uv = uvs;
- // 法线是根据顶点数据计算出来的,所以在修改完顶点后,需要更新一下法线
- mesh.RecalculateNormals();
- // 将构建好的Mesh替换上
- g.GetComponent
().mesh = mesh; - g.GetComponent
().material = gameObject.GetComponent().material; - }
- }