Unity 代码创建的奇怪网格纹理
Strange mesh texture created by code in Unity
我正在学习如何在 Unity 中通过代码进行网格划分,但纹理与图像中的一样奇怪,有人知道这是为什么吗?
我按照代码中的原样创建了 UV 贴图,搜索了很多 Google 和 Unity 文档,发现我应该使用数组顶点来映射 UV,但我认为我做错了什么
我的代码:
public Vector3[] verts = {
new Vector3(-0.5f, 0.5f, 0f), new Vector3(0.5f, 0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f), new Vector3(-0.5f, -0.5f, 0f),
new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
new Vector3(-0.5f, 0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(0.5f, 0.5f, 0.1f), new Vector3(0.5f, -0.5f, 0.1f)
};
public int[] tris = {
0,1,4,1,5,4,1,2,5,2,6,5,2,3,6,3,7,6,3,0,7,0,4,7,8,9,12,9,13,12,9,10,13,10,14,13,10,11,14,11,15,14,11,8,15,8,12,15,20,0,3,20,3,21,0,20,46,0,46,1,1,46,47,1,47,2,3,2,42,2,47,45,46,20,17,20,16,17,20,19,16,20,32,15,31,14,15,31,47,14,47,46,14,46,17,14
};
MeshFilter mF = gameObject.GetComponent<MeshFilter> ();
Mesh msh = new Mesh ();
msh.vertices = verts;
msh.triangles = tris;
Vector2[] uvs = new Vector2[verts.Length];
for (int i = 0; i < uvs.Length; i++){ //uv map
uvs[i] = new Vector2(verts[i].x, verts[i].y);
}
msh.uv = uvs;
msh.RecalculateNormals ();
mF.mesh = msh;
我怀疑透视纹理校正在您的案例中被禁用,因为
Unity 2019.3:♫ 一切都很棒 ♫
由于您已经发现共享顶点导致了此问题,您可能想要测试此代码是否有效。可能在某些时候变得有用。它旨在在网格计算时分配 UV(不再需要特殊着色器),但 要求相邻三角形的独立法线之间的角度 > PI/4 不在任何地方共享顶点(换句话说:不共享立方体不同边之间的顶点)
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
[SerializeField] MeshFilter meshFilter = null;
Vector3[] vertices = { vertices goes here };
int[] triangles = { indices goes here };
void Start ()
{
Mesh mesh = new Mesh();
meshFilter.mesh = mesh;
Vector2[] uvs = new Vector2[ vertices.Length ];
int numTriangles = triangles.Length / 3;
for( int t=0 ; t<numTriangles ; t++ )
{
int ia = triangles[ t*3 ];
int ib = triangles[ t*3+1 ];
int ic = triangles[ t*3+2 ];
Vector3 va = vertices[ ia ];
Vector3 vb = vertices[ ib ];
Vector3 vc = vertices[ ic ];
Vector3 normal = Vector3.Cross( vb-va , vc-va ).normalized;
float dotForward = Vector3.Dot( normal , Vector3.forward );
float dotRight = Vector3.Dot( normal , Vector3.right );
float dotUp = Vector3.Dot( normal , Vector3.up );
if( dotForward>0.7071f )
{
// front projection
uvs[ ia ] = new Vector2{ x=-va.x , y=va.y };
uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.y };
uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.y };
}
else if( dotForward<-0.7071f )
{
// back projection
uvs[ ia ] = new Vector2{ x=va.x , y=va.y };
uvs[ ib ] = new Vector2{ x=vb.x , y=vb.y };
uvs[ ic ] = new Vector2{ x=vc.x , y=vc.y };
}
else if( dotRight>0.7071f )
{
// right projection
uvs[ ia ] = new Vector2{ x=-va.z , y=va.y };
uvs[ ib ] = new Vector2{ x=-vb.z , y=vb.y };
uvs[ ic ] = new Vector2{ x=-vc.z , y=vc.y };
}
else if( dotRight<-0.7071f )
{
// left projection
uvs[ ia ] = new Vector2{ x=va.z , y=va.y };
uvs[ ib ] = new Vector2{ x=vb.z , y=vb.y };
uvs[ ic ] = new Vector2{ x=vc.z , y=vc.y };
}
else if( dotUp>0.7071f )
{
// top projection
uvs[ ia ] = new Vector2{ x=-va.x , y=va.z };
uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.z };
uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.z };
}
else
{
// bottom projection
uvs[ ia ] = new Vector2{ x=va.x , y=va.z };
uvs[ ib ] = new Vector2{ x=vb.x , y=vb.z };
uvs[ ic ] = new Vector2{ x=vc.x , y=vc.z };
}
}
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.RecalculateNormals();
}
}
我正在学习如何在 Unity 中通过代码进行网格划分,但纹理与图像中的一样奇怪,有人知道这是为什么吗?
我按照代码中的原样创建了 UV 贴图,搜索了很多 Google 和 Unity 文档,发现我应该使用数组顶点来映射 UV,但我认为我做错了什么
我的代码:
public Vector3[] verts = {
new Vector3(-0.5f, 0.5f, 0f), new Vector3(0.5f, 0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f), new Vector3(-0.5f, -0.5f, 0f),
new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
new Vector3(-0.5f, 0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
new Vector3(0.5f, 0.5f, 0.1f), new Vector3(0.5f, -0.5f, 0.1f)
};
public int[] tris = {
0,1,4,1,5,4,1,2,5,2,6,5,2,3,6,3,7,6,3,0,7,0,4,7,8,9,12,9,13,12,9,10,13,10,14,13,10,11,14,11,15,14,11,8,15,8,12,15,20,0,3,20,3,21,0,20,46,0,46,1,1,46,47,1,47,2,3,2,42,2,47,45,46,20,17,20,16,17,20,19,16,20,32,15,31,14,15,31,47,14,47,46,14,46,17,14
};
MeshFilter mF = gameObject.GetComponent<MeshFilter> ();
Mesh msh = new Mesh ();
msh.vertices = verts;
msh.triangles = tris;
Vector2[] uvs = new Vector2[verts.Length];
for (int i = 0; i < uvs.Length; i++){ //uv map
uvs[i] = new Vector2(verts[i].x, verts[i].y);
}
msh.uv = uvs;
msh.RecalculateNormals ();
mF.mesh = msh;
我怀疑透视纹理校正在您的案例中被禁用,因为
Unity 2019.3:♫ 一切都很棒 ♫
由于您已经发现共享顶点导致了此问题,您可能想要测试此代码是否有效。可能在某些时候变得有用。它旨在在网格计算时分配 UV(不再需要特殊着色器),但 要求相邻三角形的独立法线之间的角度 > PI/4 不在任何地方共享顶点(换句话说:不共享立方体不同边之间的顶点)
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
[SerializeField] MeshFilter meshFilter = null;
Vector3[] vertices = { vertices goes here };
int[] triangles = { indices goes here };
void Start ()
{
Mesh mesh = new Mesh();
meshFilter.mesh = mesh;
Vector2[] uvs = new Vector2[ vertices.Length ];
int numTriangles = triangles.Length / 3;
for( int t=0 ; t<numTriangles ; t++ )
{
int ia = triangles[ t*3 ];
int ib = triangles[ t*3+1 ];
int ic = triangles[ t*3+2 ];
Vector3 va = vertices[ ia ];
Vector3 vb = vertices[ ib ];
Vector3 vc = vertices[ ic ];
Vector3 normal = Vector3.Cross( vb-va , vc-va ).normalized;
float dotForward = Vector3.Dot( normal , Vector3.forward );
float dotRight = Vector3.Dot( normal , Vector3.right );
float dotUp = Vector3.Dot( normal , Vector3.up );
if( dotForward>0.7071f )
{
// front projection
uvs[ ia ] = new Vector2{ x=-va.x , y=va.y };
uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.y };
uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.y };
}
else if( dotForward<-0.7071f )
{
// back projection
uvs[ ia ] = new Vector2{ x=va.x , y=va.y };
uvs[ ib ] = new Vector2{ x=vb.x , y=vb.y };
uvs[ ic ] = new Vector2{ x=vc.x , y=vc.y };
}
else if( dotRight>0.7071f )
{
// right projection
uvs[ ia ] = new Vector2{ x=-va.z , y=va.y };
uvs[ ib ] = new Vector2{ x=-vb.z , y=vb.y };
uvs[ ic ] = new Vector2{ x=-vc.z , y=vc.y };
}
else if( dotRight<-0.7071f )
{
// left projection
uvs[ ia ] = new Vector2{ x=va.z , y=va.y };
uvs[ ib ] = new Vector2{ x=vb.z , y=vb.y };
uvs[ ic ] = new Vector2{ x=vc.z , y=vc.y };
}
else if( dotUp>0.7071f )
{
// top projection
uvs[ ia ] = new Vector2{ x=-va.x , y=va.z };
uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.z };
uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.z };
}
else
{
// bottom projection
uvs[ ia ] = new Vector2{ x=va.x , y=va.z };
uvs[ ib ] = new Vector2{ x=vb.x , y=vb.z };
uvs[ ic ] = new Vector2{ x=vc.x , y=vc.z };
}
}
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.RecalculateNormals();
}
}