3
\$\begingroup\$

I wrote a script that Creates a mesh procedurally

        mr = gameObject.AddComponent<MeshRenderer>();
        mf = gameObject.AddComponent<MeshFilter>();
        //
        mf.mesh = new Mesh
            {
                vertices = GetVertices(),
                triangles = GetTriangles()
                uvs = UpdateUVMap();
            };
 
        //assign material + shader.
        mr.sharedMaterial = new Material( Shader.Find("Shader Graphs/surface") );

(the mesh is a sphere for this example)

I created my Shader in shader-graph (any shader seems to have the same result)

When played, all seems good except that the object is black. What's happening?

//basic uv map example from docs

    public Vector2[] UpdateUVMap()
    {
        Vector2[] uv = new Vector2[this.vertices.Count];
        
        for (int i = 0; i < uv.Length; i++)
        {
            uv[i] = new Vector2(vertices[i].x, vertices[i].z);
        }

        return uvs.ToArray();

        //uvs.Clear();
        //uvs.AddRange(uv);
    }

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Did you remember to set or calculate normals for your mesh? \$\endgroup\$
    – DMGregory
    May 21 '20 at 21:27
  • \$\begingroup\$ The triangles are clockwise so the normals are facing outward. Even if they were random I should still see something since the uv example is straight from the documents... \$\endgroup\$
    – kei
    May 22 '20 at 1:23
  • 1
    \$\begingroup\$ Did you ask Unity to calculate normals for you based on vertex winding, or did you leave them at their default of (0,0,0)? \$\endgroup\$
    – DMGregory
    May 22 '20 at 1:29
  • \$\begingroup\$ oh pfft, question averted! I was thinking the normal's were implied by the winding direction. didn't realize they were calculated/set separately. i been staring at this screen too long \$\endgroup\$
    – kei
    May 22 '20 at 8:35
3
\$\begingroup\$

If you don't explicitly provide normals to your newly-made mesh, they'll be left at their default values, and the default value of a Vector3 is (0, 0, 0).

Any light vector dotted with a zero vector yields zero, so you effectively get no lighting this way: total blackness, just as you're observing.

If you want Unity to automatically compute normals for you based on the triangle information, call mesh.RecalculateNormals();

Note that this will give a smooth shading seam anywhere you have shared vertices, but it will create a hard crease where you have vertex splits (say, along a UV texturing seam). If that's not desired, you should compute your own normals and assign them the way you're doing with your vertex positions and texture coordinates.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .