如何解决垂直壁的正x轴和负x轴上的Unity Mesh UV问题
我正在尝试制作一种3D体素游戏,该游戏使用行进立方体算法来程序化地生成游戏世界。到目前为止,这工作正常,但在给定的世界/块网格垂直块的正负x侧的正好垂直侧,看起来uv坐标不太正确,因为它仅显示实心颜色而不是纹理。 [![debug块和越野车视图] [1]] [1]
在处您可以看到块状墙的外观,而在处您可以看到怪异的错误。仅在完全垂直的x边三角形上发生!图像中的那些网格是用于显示问题的调试块。 所有从噪点到地形的翻译都可以正常工作,而且我那里也没有任何错误。只是uvs会引起问题。 我正在使用以下代码填充Mesh.vertices,Mesh.triangles和Mesh.uv:
void MakeChunkMeshData()
{
for (int x = 0; x < Variables.chunkSize.x - 1; x++)
{
for (int y = 0; y < Variables.chunkSize.y - 1; y++)
{
for (int z = 0; z < Variables.chunkSize.z - 1; z++)
{
byte[] cubeCornersolidityValues = new byte[8]{
chunkMapsolidity[x,y,z],chunkMapsolidity[x + 1,y + 1,chunkMapsolidity[x,z + 1],z + 1]
};
marchOne(new Vector3Int(x,z),cubeCornersolidityValues);
}
}
}
}
void DrawChunk()
{
chunkMesh.vertices = vertices.ToArray();
chunkMesh.triangles = triangles.ToArray();
chunkMesh.SetUVs(0,uvs.ToArray());
chunkMesh.Recalculatenormals();
}
void ClearMesh()
{
chunkMesh.Clear();
}
void ClearChunkMeshAndData()
{
chunkMesh.Clear();
uvs = new List<Vector2>();
vertices = new List<Vector3>();
triangles = new List<int>();
}
/// <summary>
/// cube contains bytes for each corner of the cube
/// </summary>
/// <param name="cube"></param>
/// <returns></returns>
int GetCubeConfiguration(byte[] cube)
{
int u = 0;
int result = 0;
for(int corner = 0; corner < 8; corner++)
{
if (cube[corner] < Variables.solidityThreshold)
{
u++;
result |= 1 << corner;
}
}
return result;
}
Vector2[] getUvsPerTriangle(byte[] voxelTypes)
{
int resId = voxelTypes[0];
if (voxelTypes[1] == voxelTypes[2])
resId = voxelTypes[1];
resId = 1;
Vector2 normalized = getUvCoordFromTextureIndex(resId) / Constants.TextureAtlasSizeTextures;
float textureLength = 1f/Constants.TextureAtlasSizeTextures;
Vector2[] result = new Vector2[3] {
normalized + new Vector2(1,0) * textureLength,normalized + new Vector2(0,1) * textureLength,normalized + new Vector2(1,1) * textureLength
};
//Debug.Log(result);
return result;
}
/// <summary>
/// returns the absolute x and y coordinates of the given texture in the atlas (example: [4,1])
/// </summary>
/// <param name="textureIndex"></param>
/// <returns></returns>
Vector2 getUvCoordFromTextureIndex(int textureIndex)
{
int x = textureIndex % Constants.TextureAtlasSizeTextures;
int y = (textureIndex - x) / Constants.TextureAtlasSizeTextures;
return new Vector2(x,y);
}
/// <summary>
/// takes the chunk-wide mesh data and adds its results after marching one cube to it.
/// </summary>
/// <returns></returns>
void marchOne(Vector3Int offset,byte[] cube)
{
int configuration = GetCubeConfiguration(cube);
byte[] voxelTypes = new byte[3];
int edge = 0;
for (int i = 0; i < 5; i++) //loop at max 5 times (max number of triangles in one cube config)
{
for(int v = 0; v < 3; v++) // loop 3 times through shit(count of vertices in a TRIangle,who would have thought...)
{
int cornerIndex = VoxelData.TriangleTable[configuration,edge];
if (cornerIndex == -1) // indicates the end of the list of vertices/triangles
return;
Vector3 vertex1 = lwTo.Vec3(VoxelData.EdgeTable[cornerIndex,0]) + offset;
Vector3 vertex2 = lwTo.Vec3(VoxelData.EdgeTable[cornerIndex,1]) + offset;
Vector3Int vertexIndex1 = lwTo.Vec3Int(VoxelData.EdgeTable[cornerIndex,0]) + offset;
Vector3Int vertexIndex2 = lwTo.Vec3Int(VoxelData.EdgeTable[cornerIndex,1]) + offset;
Vector3 vertexPosition;
if (Variables.badGraphics)
{
vertexPosition = (vertex1 + vertex2) / 2f;
}
else
{
// currently using this "profile"
// this code determines the position of the vertices per triangle based on the value in chunksolidityMap[,]
float vert1solidity = chunkMapsolidity[vertexIndex1.x,vertexIndex1.y,vertexIndex1.z];
float vert2solidity = chunkMapsolidity[vertexIndex2.x,vertexIndex2.y,vertexIndex2.z];
float difference = vert2solidity - vert1solidity;
difference = (Variables.solidityThreshold - vert1solidity) / difference;
vertexPosition = vertex1 + ((vertex2 - vertex1) * difference);
}
vertices.Add(vertexPosition);
triangles.Add(vertices.Count - 1);
voxelTypes[v] = chunkMapVoxelTypes[vertexIndex1.x,vertexIndex1.z];
edge++;
}
uvs.AddRange(getUvsPerTriangle(voxelTypes));
}
}
编辑: 当仅稍微旋转块时,奇怪的问题立即消失。我不知道为什么,但是至少我现在知道这里发生了什么。 [1]:https://i.stack.imgur.com/kYnkl.jpg
解决方法
好吧,事实证明,这可能是一些来自统一的奇怪行为。当在网格填充过程之后将网格显式设置为meshFilters的网格时,它工作得很好。另外,我必须调用mesh.RecalculateTangents()使其起作用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。