Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set color for each vertex in a triangle

I want to set each three vertex of a triangle from a mesh red, blue and green.

As seen in the first part this tutorial which is for another language. This is the code they are using to set red, green and blue to each vertext in the each triangle from a mesh:

function set_wireframe_colors(m)
    local cc = {}
    for i = 1, m.size/3 do
        table.insert(cc, color(255,0,0))
        table.insert(cc, color(0,255,0))
        table.insert(cc, color(0,0,255))
    end
    m.colors = cc
end

and this is what the output looks like with a simple vertex color shader:

enter image description here


I tried to recreate the-same thing in Unity with C# but I am struggling with the first part of this tutorial.

Here is my code:

void Start()
{
    Mesh mesh = GetComponent<MeshFilter>().mesh;
    Vector3[] vertices = mesh.vertices;

    //Create new colors array where the colors will be created.
    Color32[] colors = new Color32[vertices.Length];

    for (int i = 0; i < vertices.Length; i += 3)
    {
        colors[i] = new Color32(255, 0, 0, 255);
        colors[i + 1] = new Color32(0, 255, 0, 255);
        colors[i + 2] = new Color32(0, 0, 255, 255);
    }

    //assign the array of colors to the Mesh.
    mesh.colors32 = colors;
}

but this is the output I get from Unity with a simple vertex color shader:

enter image description here


If you look closely you will see that each vertex in my cube does not have an rgb color assigned to it like the cube from my first screenshot. It looks very close though.

What's wrong with the code? Why does each vertex not have rgb color like the image from my first screenshot.

Shader:

This problem likely has nothing to do with the shader but here the simple color shader in Unity:

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    float4 color : COLOR;
};

struct v2f
{
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
    float4 color : COLOR;
};

sampler2D _MainTex;
float4 _MainTex_ST;


v2f vert(appdata v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.color = v.color;

    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
}

float4 frag(v2f i) : SV_Target
{
    return i.color;
}
like image 494
Programmer Avatar asked Aug 24 '17 06:08

Programmer


People also ask

What is vertex color used for?

Vertex color, or vcolor, is just a color with RGB and alpha channel values stored for each vertex of a mesh. Vertex color and alpha can be used for multi-texturing, transparency, or fake ambient occlusion. Vertex color is typically multiplied against the Diffuse color, colorizing or darkening the color map.


1 Answers

The mesh he is using has a 3 separate vertices for each triangle (6 vertices per quad). In a unity cube each face is a quad with 4 vertices and the 2 triangles on each face share 2 of the vertices.
enter image description here

On the left is a quad that has 4 vertices and the mesh.triangles array would be 0 1 2 1 0 3, and on the right is a quad with 6 vertices with mesh.triangles = 0 1 2 3 4 5 (vertex order matters for back-face culling. In my shader I have Cull set to off).

So as you can see in the image for this shader you can use meshes made out of 4 vertices quads as long as you are careful and make sure that each triangle has one of each color in each vertex.


As I said in the comments you can split your mesh so that you have 3 unique vertices for each triangle.

void Start () {
    Mesh mesh = GetComponent<MeshFilter>().mesh;        
    SplitMesh(mesh);
    SetColors(mesh);
}

void SplitMesh(Mesh mesh)
{
    int[] triangles = mesh.triangles; 
    Vector3[] verts = mesh.vertices;
    Vector3[] normals = mesh.normals;
    Vector2[] uvs = mesh.uv;

    Vector3[] newVerts;
    Vector3[] newNormals;
    Vector2[] newUvs;

    int n = triangles.Length;
    newVerts   = new Vector3[n];
    newNormals = new Vector3[n];
    newUvs     = new Vector2[n];

    for(int i = 0; i < n; i++)
    {
        newVerts[i] = verts[triangles[i]];
        newNormals[i] = normals[triangles[i]];
        if (uvs.Length > 0)
        {
            newUvs[i] = uvs[triangles[i]];
        }
        triangles[i] = i; 
    }        
    mesh.vertices = newVerts;
    mesh.normals = newNormals;
    mesh.uv = newUvs;        
    mesh.triangles = triangles;            
}   
void SetColors(Mesh mesh)
{
    Color[] colors = new Color[mesh.vertexCount];
    for (int i = 0; i < colors.Length; i+=3)
    {
        colors[i] = Color.red;
        colors[i + 1] = Color.green;
        colors[i + 2] = Color.blue;
    }
    mesh.colors = colors;
}

enter image description here

like image 113
Pluto Avatar answered Oct 18 '22 19:10

Pluto