0
\$\begingroup\$

I've been using Unity3D to procedurally generate terrain with Perlin Noise and I've come across a problem where the mesh that I've constructed only renders one set of triangles.

enter image description here

The following is my MeshGeneration code:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using NUnit.Framework.Internal.Execution;
using UnityEngine;

public static class MeshGenerator
{
    public static MeshData GenerateMesh(float[,] heightMap)
    {
        int height = heightMap.GetLength(0);
        int width = heightMap.GetLength(1);
        int vertexIndex = 0;
        
        MeshData meshData = new MeshData(width, height);

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                meshData.vertices[vertexIndex] = new Vector3(x, heightMap[y, x], y);
                meshData.uvs[vertexIndex] = new Vector2( x/(float)width, y/(float)height);
                 
                // If we are not on the edge, then add two triangles to the mesh
                if ((x != width - 1) && (y != height - 1))
                {
                    meshData.AddTriangle(
                        vertexIndex,
                        vertexIndex + width,
                        vertexIndex + width + 1
                    );
                    meshData.AddTriangle(
                        vertexIndex,
                        vertexIndex + 1,
                        vertexIndex + width + 1
                    );
                }
                
                vertexIndex++;
            }
        }

        return meshData;
    }
}

public class MeshData
{
    public Vector3[] vertices;
    public Vector2[] uvs;
    public int[] triangles;

    public int triangleIndex;
    public MeshData(int meshWidth, int meshHeight)
    {
        vertices = new Vector3[meshWidth * meshHeight];
        uvs = new Vector2[meshWidth * meshHeight];
        triangles = new int[(meshWidth - 1) * (meshHeight - 1) * 6];
    }

    public void AddTriangle(int a, int b, int c)
    {
        triangles[triangleIndex] = a;
        triangles[triangleIndex + 1] = b;
        triangles[triangleIndex + 2] = c;
        triangleIndex += 3;
    }

    public Mesh CreateMesh()
    {
        Mesh mesh = new Mesh();
        mesh.vertices = this.vertices;
        mesh.uv = this.uvs;
        mesh.triangles = this.triangles;
        
        mesh.RecalculateNormals();
        return mesh;
    }
}

I'm then passing in the mesh that I get from MeshData.CreateMesh() into the following function.

public void BuildMesh(MeshData meshData, Texture2D texture)
    {
        meshFilter.sharedMesh = meshData.CreateMesh();
        meshRenderer.sharedMaterial.mainTexture = texture;
    }

I'm following this tutorial: https://www.youtube.com/watch?v=4RpVBYW1r5M&list=PLFt_AvWsXl0eBW2EiBtl_sxmDtSgZBxB3&index=5

The Mesh generation code works by creating arrays of vertices, uvs, and triangles, and the populating them by iterating over a Vector3[] heightMap that I created with perlin noise.

\$\endgroup\$
1
\$\begingroup\$

Solved the problem myself. The remaining triangles were being generated on the other side of the mesh. This was I didn't know that the order of the vertices had to be in clockwise order.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.