【问题标题】:Unity3D - How to add textures to a meshUnity3D - 如何向网格添加纹理
【发布时间】:2021-02-09 09:38:28
【问题描述】:

我正在制作一个立方体素游戏。我已经完成了块、世界、块和网格的生成,但是有一个问题 - 我无法进行纹理处理。

我需要的只是在 3D 网格的一侧添加纹理(每个纹理都不同!)。我见过一些实现,但很难阅读别人的代码(我试过使用它们,但没有用)。我自己尝试过,但没有结果。

谁能解释一下怎么做?

这是我当前的代码:

[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class Chunk : MonoBehaviour
{
    private ushort[] _voxels = new ushort[16 * 16 * 16];
    private MeshFilter meshFilter;
    private Vector3[] cubeVertices = new[] {
        new Vector3 (0, 0, 0),
        new Vector3 (1, 0, 0),
        new Vector3 (1, 1, 0),
        new Vector3 (0, 1, 0),
        new Vector3 (0, 1, 1),
        new Vector3 (1, 1, 1),
        new Vector3 (1, 0, 1),
        new Vector3 (0, 0, 1),
    };
    private int[] cubeTriangles = new[] {
        // Front
        0, 2, 1,
        0, 3, 2,
        // Top
        2, 3, 4,
        2, 4, 5,
        // Right
        1, 2, 5,
        1, 5, 6,
        // Left
        0, 7, 4,
        0, 4, 3,
        // Back
        5, 4, 7,
        5, 7, 6,
        // Bottom
        0, 6, 7,
        0, 1, 6
    };

    public ushort this[int x, int y, int z]
    {
        get { return _voxels[x * 16 * 16 + y * 16 + z]; }
        set { _voxels[x * 16 * 16 + y * 16 + z] = value; }
    }

    void Start()
    {
        meshFilter = GetComponent<MeshFilter>();
    }

    private void Update()
    {
        GenerateMesh();
    }

    public void GenerateMesh()
    {
    Mesh mesh = new Mesh();
    List<Vector3> vertices = new List<Vector3>();
    List<int> triangles = new List<int>();

    for (var x = 0; x < 16; x++)
    {
        for (var y = 0; y < 16; y++)
        {
            for (var z = 0; z < 16; z++)
            {
                var voxelType = this[x, y, z];
                if (voxelType == 0)
                    continue;
                var pos = new Vector3(x, y, z);
                var verticesPos = vertices.Count;
                foreach (var vert in cubeVertices)
                    vertices.Add(pos + vert);
                foreach (var tri in cubeTriangles)
                    triangles.Add(verticesPos + tri);
            }
        }
    }

    mesh.SetVertices(vertices);
        mesh.SetTriangles(triangles.ToArray(), 0);
    meshFilter.mesh = mesh;
    }
}

注意:这是一篇经过多次修改的转贴,因此它专注于一个问题,并且有更好的解释。很抱歉。

【问题讨论】:

    标签: c# unity3d minecraft voxel


    【解决方案1】:

    与您的SetVertices()SetTriangles() 一样,您可以调用SetUVs() 并列出纹理上每个顶点的UV 坐标。

    UV 列表大小必须与顶点列表大小匹配!

    UV 坐标表示为 Vector2,其值介于 0 和 1 之间。 例如,要将整个纹理应用到立方体的正面,前 4 个 uv 如下所示:

    private Vector2[] cubeUVs = new[] {
        new Vector2 (0, 0),
        new Vector2 (1, 0),
        new Vector2 (1, 1),
        new Vector2 (0, 1),
        ...
    }
    
    ...
    
    mesh.SetUVs(0, cubeUVs);
    

    如果你的纹理不是正方形,那么它将被拉伸。

    您还应该在 GenerateMesh() 方法的末尾调用 RecalculateBounds()RecalculateNormals() 以避免以后出现一些问题。

    编辑

    如果您真的希望立方体的每一面都使用不同的纹理文件,那么对我而言最简洁和最高效的解决方案是为立方体的每一面设置不同的 VertexColor,例如。 (1,0,0), (0,1,0), (0,0,1), (1,1,0), (1,0,1) 和 (0,1,1)。
    但是,您必须将所有顶点复制 3 次。 (因为顶点颜色绑定到一个顶点,而立方体的每个顶点都属于3条边)
    (你仍然需要像我之前说的那样设置 UV,但每一面都有整个纹理,而不是只有纹理的一部分)

    然后,您必须创建一个自定义着色器,其中包含 6 个输入纹理(每侧一个)。
    并且在片段函数中,根据顶点颜色选择合适的纹理颜色。
    你可以为此做一些 if 来选择纹理,但它的性能不是很好:

    float3 finalColor;
    if(vertexColor.r > 0.5f && vertexColor.g < 0.5f && vertexColor.b < 0.5f)
    {
        finalColor = text2D(_TopTexture, in.uv);
    }
    else if(...)
    {
        ...
    }
    ...
    

    或者如果你想要更多的性能(有很多立方体),你可以做一些乘法来选择正确的纹理:

    float3 topTexColor = text2D(_TopTexture, in.uv) * vertexColor.r * (1.0f - vertexColor.g) * (1.0f - vertexColor.b);
    float3 frontTexColor = ...;
    ...
    float3 finalColor = topTexColor + frontTexColor + ...;
    

    【讨论】:

    • 对不起,我的意思是每一面都有不同的纹理。我只是不擅长提问?,忘记提了
    • 然后,您可以制作一个包含所有立方体边在内的纹理,并且您可以为每一边设置不同的 UV 值:例如。从 (0, 0) 到 (0.5, 0.5) 的正方形用于正面,从 (0.5, 0) 到 (1, 0.5) 的正方形用于顶部,从 (0, 0.5) 到 (0.5, 1) 的正方形用于底部等。
    猜你喜欢
    • 1970-01-01
    • 2020-11-02
    • 2019-08-23
    • 2016-01-24
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多