Black tris on generated mesh

I am cutting a mesh along a plane. When the plane passes through a tri, I calculate new vertex points and create new tris. I then lerp the new vertex normals and uvs.

Unfortunately, when I attach a texture material, the new tris show up as black. This doesn’t happen however when I use an unlit shader.

I know all the tris are facing the right direction. I also know that the normals are facing the right direction. the uvs seem a little off so I think the problem lies in the uvs but I’m not sure exactly where

standard shader
4734398--448592--blacktris.PNG

unlit shader
4734398--448595--blacktris2.PNG

Does anyone have any idea how to get the black tris working?

How do you know the normals are fine? UVs are unlikely to be the issue if they work fine with unlit.

Maybe this unity answers topic will help.

I made it draw the normals as lines, and they all face the right direction, I’ll read through the post you linked to see if I missed something though

Perhaps if you post your code we can figure out what’s going on.

here are the relevant parts:

if (AreLinePlaneIntersecting(CutMeshPlane.transform.up, CutMeshPlane.transform.position, transform.TransformPoint(m_vertices[triList[i]]), transform.TransformPoint(m_vertices[triList[i + 1]])))
                    {
                        AB = true;
                        newVertPosition1 = GetLinePlaneIntersectionCoordinate(CutMeshPlane.transform.up, CutMeshPlane.transform.position, transform.TransformPoint(m_vertices[triList[i]]), transform.TransformPoint(m_vertices[triList[i + 1]]));

                        //get the percent between the two points for lerp
                        distanceOne = Vector3.Distance(transform.TransformPoint(m_vertices[triList[i]]), newVertPosition1);
                        distanceTwo = Vector3.Distance(transform.TransformPoint(m_vertices[triList[i]]), transform.TransformPoint(m_vertices[triList[i + 1]]));
                        distancePercent = distanceOne / distanceTwo;

                        //generate new normal and uv
                        newVertNormal1 = Vector3.Lerp(m_normals[triList[i]], m_normals[triList[i + 1]], distancePercent);
                        newVertUV1 = Vector2.Lerp(m_uvs[triList[i]], m_uvs[triList[i + 1]], distancePercent);
//convert back to local space from world space
                    newVertPosition1 = transform.InverseTransformPoint(newVertPosition1);
                    newVertPosition2 = transform.InverseTransformPoint(newVertPosition2);
                    newVertPosition3 = transform.InverseTransformPoint(newVertPosition3);
                   
                    //create new tris
                    if (!AB)
                    {
                        //add new verts to vertex list
                        vertList.Add(newVertPosition2);
                        vertList.Add(newVertPosition3);

                        normalList.Add(newVertNormal2);
                        normalList.Add(newVertNormal3);

                        uvList.Add(newVertUV2);
                        uvList.Add(newVertUV3);

                        //add new tris
                        triList.Add(triList[i]);
                        triList.Add(triList[i + 1]);
                        triList.Add(vertList.Count-1);

                        triList.Add(triList[i]);
                        triList.Add(vertList.Count - 1);
                        triList.Add(vertList.Count-2);
                    }
//convert m_triangles back into an array
        m_triangles = triList.ToArray();
        m_vertices = vertList.ToArray();
        m_normals = normalList.ToArray();
        m_uvs = uvList.ToArray();

        //update mesh
        Destroy(this.gameObject.GetComponent<MeshCollider>());

        m_mesh.vertices = m_vertices;
        m_mesh.triangles = m_triangles;
        m_mesh.normals = m_normals;
        m_mesh.uv = m_uvs;

        this.gameObject.AddComponent<MeshCollider>();

There are a few of these with different configurations to handle different triangle-plane-intersection cases, but they are all more or less the same

If you execute a .RecalculateNormals() on the mesh after all the verts and tris have been added, does the black go away? Because if it does, that’s a normal problem. If it does not, the problem is elsewhere.

In other news, unless I’m doing something “interesting” with the normals, I never bother to calculate and store normals: I just call .RecalculateNormals() (after verts and uvs and tris are in place) and call it a day. :slight_smile:

would that be after

m_normals = normalList.ToArray();

or after

m_mesh.normals = m_normals;

You don’t need to set your own normals if you call .RecalculateNormals(), so just do it right before you assign the mesh to the MeshFilter instance. If you set the normals again yourself, you’ll overwrite what .RecalculateNormals() gets you.

so essentially replace the “m_mesh.normals = m_normals;” with m_mesh.RecalculateNormals()"? (and get rid of the earlier normal calculations)

Try it and see :slight_smile:

gives the same outcome (yay for my normal calculations being right at least)

Could it have something to do with not calculating vertex tangents?

It’s very hard to diagnose a problem when you post bits and pieces of the ‘relevant’ code. Please write a script that calculates the mesh from beginning to end and post it. Separate everything to do with building the mesh away from your other code into a complete, testable, debuggable system or otherwise you will suffer from debug hell.

For example, write a ‘general’ function that takes vertex, triangle and UV arrays as arguments, and creates the mesh from it. Then we can easily see everything involved in building the mesh.

This tutorial might be of help.

thanks I’ll have a look and try to clean up/modularise the code

using a different material works with the standard shader. This one is a plain material with just an albedo texture, so I think the black tris are caused by the lack of vertex tangents with a bump map material.

This also shows the uv errors, but I will try to get them fixed tomorrow

It seems likely to me that tangents are the issue. I would suggest writing a fragment shader with and without a bump map to test this issue.

Also, this might help you understand tangents.