Search code examples
c#unity-game-enginemeshshadow

Why doesn't my procedurally-generated mesh have any shadows?


I have generated a mesh using C# and it worked but there are no shadows. I expected the shadows to just work like the built-in Terrain in Unity but it doesn't.

I have a directional light source above pointing at the mesh and the mesh renderer is set to both cast shadows and receive shadows = ON. Could it be something to do with shaders?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter))]
public class ChunkGeneration : MonoBehaviour
{
    Mesh mesh;

    Vector3[] vertices;
    int[] triangles;

    public int size = 100;
    // Start is called before the first frame update
    void Start()
    {
        //Create a new mesh 
        mesh = new Mesh();
        CreateShape();
        UpdateMesh();
        
        GetComponent<MeshFilter>().mesh = mesh;
        GetComponent<MeshCollider>().sharedMesh = mesh;
    }

    // Update is called once per frame
    void Update()
    {
    }

    void CreateShape() 
    {
        //Create vertices for mesh
        vertices = new Vector3[(size + 1 ) * (size + 1)];

        for (int i = 0, z = 0; z < size + 1; z++) {
            for (int x = 0; x < size + 1; x++) {

                float y = Mathf.PerlinNoise(x * .3f, z * .3f);
                vertices[i] = new Vector3(x, y, z); //WHY WHEN Z IN Y_VALUE IT WORK???
                i++;
            }
        }

        //Create triangles for mesh
        triangles = new int[size * size * 6];

        int vert = 0;
        int tris = 0;

        for (int z = 0; z < size; z++) 
        {
            for (int x = 0; x < size; x++) 
            {
                triangles[tris + 0] = vert + 0;
                triangles[tris + 1] = vert + size + 1;
                triangles[tris + 2] = vert + 1;
                triangles[tris + 3] = vert + 1;
                triangles[tris + 4] = vert + size + 1;
                triangles[tris + 5] = vert + size + 2;

                vert++;
                tris += 6;
            }
            vert++;
        }
    }

    void UpdateMesh() 
    {
        //Reset and update mesh
        mesh.Clear();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
    }
}

Solution

  • This is because you haven't calculated Normal yet. Therefore, MeshRenderer still does not recognize which side is the main direction of Face and how to calculate the light. Add the following line and the problem will be solved.

    void UpdateMesh() {
        //Reset and update mesh
        mesh.Clear();
    
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        
        mesh.RecalculateNormals(); // You need to calculate Normals..
    }