@[TOC] (基础一)
初识基础:
-
首先点和面的联系:三个点构成一个小三角形,然后面就是由无数的小三角形构成
另外相同位置的顶点可以复用,就像一个正方形,四个点即可
-
三角面有正反之分,关键看法线方向
发现朝外的,我们能看到,反过来就看不到了,可以参考unity的Plane
-
uv: 纹理坐标
目的是让我们的图片正确的显示到我们的图形上,也就是贴图吧
取值范围就是0到1
-
三角形序列(triangle)
都是三点倍数
emmmm关于以上的一些基础知识的定义呢,可以考虑其他大佬写的
基础的定义
mesh学习
代码创建一个mesh
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
}
}
RequireComponent表示在代码编译前需要先添加俩组件
上面代码创建一个空物体,把上面脚本拖上去即可
制作一个三角形面片
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
mesh.vertices = GetVertex();
mesh.triangles = GetTriangles();
}
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(1,0,0),
new Vector3(1,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
0,1,2
};
}
}
效果:
因为法线与摄像机方向相同了, 所以y轴旋转了180度
否则可以考虑GetTriangles 中的0,1,2 改成2,1,0
制作一个正方形
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
mesh.RecalculateNormals();
mesh.vertices = GetVertex();
mesh.triangles = GetTriangles();
}
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(1,0,0),
new Vector3(1,1,0),
new Vector3(0,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
2,1,0,
0,3,2
};
}
}
效果:
注意
z轴(蓝色的)和摄像机z轴同向,即沿着摄像头,顺时针方向的三个点,才能被我们看到
UV设计
通过以上方法,创建完正方形或者其他图形,拖上材质球,你会发现
图形并不能完全显示
所以就涉及到了UV
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
mesh.RecalculateNormals();
mesh.vertices = GetVertex();
mesh.triangles = GetTriangles();
mesh.uv = GetUV();
}
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(1,0,0),
new Vector3(1,1,0),
new Vector3(0,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
2,1,0,
0,3,2
};
}
private Vector2[] GetUV()
{
return new Vector2[]
{
new Vector2(0,0),
new Vector2(1,0),
new Vector2(1,1),
new Vector2(0,1),
};
}
}
简单找个材质球拖上图片测试一下
如果显示上有点问题,应该是shader的问题 改成这个:
原图
UV上的坐标是怎么得到的呢
位置坐标也就是GetVertex中的四个顶点的坐标 因为我的物体坐标点方向账号和uv上的同向
或者我把GtVertex调整一下位置,注意观察GetUV:即顺序要保持一致
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(0,1,0),
new Vector3(1,0,0),
new Vector3(1,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
0,1,3,
3,2,0
};
}
private Vector2[] GetUV()
{
return new Vector2[]
{
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,0),
new Vector2(1,1),
};
}
设置法线
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Mesh mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
mesh.RecalculateNormals();
mesh.vertices = GetVertex();
mesh.triangles = GetTriangles();
mesh.uv = GetUV();
mesh.normals = GetNormals();
}
private Vector3[] GetNormals()
{
return new Vector3[]{
Vector3.forward,
Vector3.forward,
Vector3.forward,
Vector3.forward
};
}
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(0,1,0),
new Vector3(1,0,0),
new Vector3(1,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
0,1,3,
3,2,0
};
}
private Vector2[] GetUV()
{
return new Vector2[]
{
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,0),
new Vector2(1,1),
};
}
}
注意 GetNormals() 法线数组的个数要和顶点的个数保持一致,即每个点的法线
网格切线: mesh.tangents
那么它有什么用呢,他具体影响的是法线贴图的显示
就是这种凹凸不平的贴图 具体发现贴图添加位置:
涉及代码:
void Update()
{
mesh.tangents = GetTangents();
}
private Vector4[] GetTangents()
{
return new Vector4[]{
tempTangent,
tempTangent,
tempTangent,
tempTangent
};
}
其中 tempTangent 是一个public 的Vector4 变量 ,放到Update中是为了方便看变化
详细代码
[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class Generate_Mesh1 : MonoBehaviour
{
public Vector4 tempTangent;
// Start is called before the first frame update
private Mesh mesh;
void Start()
{
mesh = new Mesh();
MeshFilter meshFilter = GetComponent<MeshFilter>();
meshFilter.mesh = mesh;
mesh.name = "lianxi1";
mesh.RecalculateNormals();
mesh.vertices = GetVertex();
mesh.triangles = GetTriangles();
mesh.uv = GetUV();
mesh.normals = GetNormals();
//mesh.RecalculateNormals();
}
void Update()
{
mesh.tangents = GetTangents();
}
private Vector4[] GetTangents()
{
return new Vector4[]{
tempTangent,
tempTangent,
tempTangent,
tempTangent
};
}
//private Vector3[] GetNormals()
//{
// return new Vector3[]{
// mesh.vertices[1] - mesh.vertices[0],
// mesh.vertices[2] - mesh.vertices[1],
// mesh.vertices[3] - mesh.vertices[2],
// mesh.vertices[0] - mesh.vertices[3]
// };
//}
private Vector3[] GetNormals()
{
return new Vector3[]{
Vector3.back,
Vector3.back,
Vector3.back,
Vector3.back
};
}
private Vector3[] GetVertex()
{
return new Vector3[]
{
new Vector3(0,0,0),
new Vector3(0,1,0),
new Vector3(1,0,0),
new Vector3(1,1,0)
};
}
private int[] GetTriangles()
{
return new int[]
{
0,1,3,
3,2,0
};
}
private Vector2[] GetUV()
{
return new Vector2[]
{
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,0),
new Vector2(1,1),
};
}
}