结论:本文解决自建Mesh时,因为法线的问题而导致的贴图受光照问题。
本文的代码前瞻(成功创建Mesh并且可以赋予贴图的也许不必要观看):https://blog.csdn.net/weixin_47220117/article/details/147404303?spm=1001.2014.3001.5501
1.先理解法线
法线就是垂直于一个面的一条向量,它对该面的受光照程度影响较大。
2.如何创建法线
第一种方式:
遇到这样的问题时,明显就是贴图的受光照计算受到了影响,对于自建的Mesh中可以这么写:
//法线
Vector3[] normals = new Vector3[4];
Vector3 edge1 = vertices[1] - vertices[0];
Vector3 edge2 = vertices[0] - vertices[3];
Vector3 normal = Vector3.Cross(edge1, edge2).normalized;
//由于只有一个面,所以四条法线是一样的,赋予相同的即可
for(int i = 0; i < normals.Length; i ++)
{
normals[i] = normal;
}
//这里是赋予你的Mesh这四条法线,几个顶点就有几条法线
mesh.normals = normals;
完整代码:
using UnityEngine;
public class AMesh : MonoBehaviour
{
public MeshFilter meshFilter;//网格拥有者组件
[ContextMenu(nameof(Create))]
public void Create()
{
//顶点坐标
Vector3[] vertices = new Vector3[]
{
new Vector3(-0.5f, 0, -0.5f),//左下角
new Vector3(0.5f, 0, -0.5f),//右下角
new Vector3(0.5f, 0, 0.5f),//右上角
new Vector3(-0.5f, 0, 0.5f),//左上角
};
//需要顺时针构建三角形
int[] triangle = new int[]
{
0, 2, 1,//第一个三角形
0, 3, 2,//第二个三角形
};
//UV
Vector2[] uv = new Vector2[]
{
new Vector2(0, 0),//左下角
new Vector2(1, 0),//右下角
new Vector2(1, 1),//右上角
new Vector2(0, 1),//左上角
};
//法线
Vector3[] normals = new Vector3[4];
Vector3 edge1 = vertices[1] - vertices[0];
Vector3 edge2 = vertices[0] - vertices[3];
//进行叉积运算
Vector3 normal = Vector3.Cross(edge1, edge2).normalized;
//由于只有一个面,所以四条法线是一样的,赋予相同的即可
for(int i = 0; i < normals.Length; i ++)
{
normals[i] = normal;
}
//构建Mesh实例
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangle;
mesh.uv = uv;
mesh.normals = normals;
meshFilter.mesh = mesh;
}
}
!!! 如果你发现写完后,光照计算还是出现问题,那么很可能就是法线是背光的,叉积计算遵循右手定则!!!遇到这个问题的解决办法是:
把这句代码:Vector3 normal = Vector3.Cross(edge1, edge2).normalized;
改成:Vector3 normal = -Vector3.Cross(edge1, edge2).normalized;
这样法线就不会背光了。
第二种方式:
一句搞定,还基本不会出错!
即可直接使用Unity自带的api:
mesh.RecalculateNormals();
完整代码:
using UnityEngine;
public class AMesh : MonoBehaviour
{
public MeshFilter meshFilter;//网格拥有者组件
[ContextMenu(nameof(Create))]
public void Create()
{
//顶点坐标
Vector3[] vertices = new Vector3[]
{
new Vector3(-0.5f, 0, -0.5f),//左下角
new Vector3(0.5f, 0, -0.5f),//右下角
new Vector3(0.5f, 0, 0.5f),//右上角
new Vector3(-0.5f, 0, 0.5f),//左上角
};
//需要顺时针构建三角形
int[] triangle = new int[]
{
0, 2, 1,//第一个三角形
0, 3, 2,//第二个三角形
};
//UV
Vector2[] uv = new Vector2[]
{
new Vector2(0, 0),//左下角
new Vector2(1, 0),//右下角
new Vector2(1, 1),//右上角
new Vector2(0, 1),//左上角
};
//构建Mesh实例
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangle;
mesh.uv = uv;
mesh.RecalculateNormals();
meshFilter.mesh = mesh;
}
}
解决后的效果: