Search code examples
c#unity-game-engineshader

Unity3d: How to calculate the surface area of different colors in a colored mesh


I have created a mesh in run-time with a special shared. The shared has the following property:
1. When it is colored for the first time the color is blue
2. When it is colored for the second time the color is yellow
3. When it is colored for the third time the color is red
4. When it is colored for the fourth or more the color becomes green

Here's an example of the colored region:

enter image description here

In the above image the green region has many layer of mashes. I cannot calculate the area by summing up the triangles in mesh because there are many overlaps.

EDIT! I am updating question with more information
The mesh is generated using the following code (it's not the whole code by it is enough to give a general idea of how the mesh is generated)

for (int i = start; i<colorUntil; i++)
{
    parent.position = currentPosition;
    Vector3 relativePos = points[i + 1] - points[i];
    if (relativePos.magnitude > 0.5)
    {
        parent.rotation = Quaternion.LookRotation(relativePos);
    }

    currentPosition = points[i];
    Vector3 offset = parent.right * width / 2f;
    vertices.Add(currentPosition - offset);
    vertices.Add(currentPosition + offset);

    uvs.Add(new Vector2(0, 1));
    uvs.Add(new Vector2(1, 1));

    if (vertices.Count< 4)
    {
        return;
    }

    int c = vertices.Count;
    triangles.Add(c - 1);
    triangles.Add(c - 2);
    triangles.Add(c - 3);
    triangles.Add(c - 3);
    triangles.Add(c - 2);
    triangles.Add(c - 4);

    Vector3[] v = new Vector3[c];
    Vector2[] uv = new Vector2[c];
    int[] t = new int[triangles.Count];
    vertices.CopyTo(v, 0);
    uvs.CopyTo(uv, 0);
    triangles.CopyTo(t, 0);

    mesh.vertices = v;
    mesh.triangles = t;
    mesh.uv = uv;
}

Now I have to calculate the area of each color. Given the mesh above is it possible to calculate area of each color? Any suggestion would be welcome.

EDIT 2!
Apparently, there's no way to calculate the colored area using mash information (at least according to my research). How I am looking for a creative way to achieve what I want. I would welcome and appreciate any suggestions.


Solution

  • A simple script to take screenshot then count the green pixels.

    Put the script on the render camera, set m_TakeScreenshot to true, it'll work in the current frame.

    public class ScreenshotCamera : MonoBehaviour
    {
        public bool m_TakeScreenshot;
        public Texture2D m_OutputTexture;
    
        void OnPostRender()
        {
            if (m_TakeScreenshot)
            {
                m_TakeScreenshot = false;
    
                //Take screenshot
                if (m_OutputTexture == null)
                    m_OutputTexture = new Texture2D(Screen.width, Screen.height);
                m_OutputTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
                m_OutputTexture.Apply();
    
                //Get all pixels, count green pixels
                var pixels = m_OutputTexture.GetPixels(0, 0, m_OutputTexture.width, m_OutputTexture.height);
                int greenPixels = 0, otherPixels = 0;
                foreach (var color in pixels)
                {
                    //green
                    if (color.g > 0.8f && color.r < 0.1f && color.b < 0.1f)
                        greenPixels++;
                    //not black
                    else if (color.r > 0.1f || color.g > 0.1f || color.b > 0.1f)
                        otherPixels++;
                }
            }
        }
    }