Multiple Colors in Mesh Programmatically?

I can programmatically assign my mesh any one color with code like this:

renderer.material.color = Color(1.0, 0.5, 1.0)  # Light purple

But I’d like to programmatically assign my mesh multiple colors (per-face/triangles preferred, but per-vertex acceptable).

I saw that Mesh has an attribute called colors, so I tried using it like this (this is nearly identical to the example in the scripting documentation here: Unity - Scripting API: Mesh.colors):

mesh = GetComponent(MeshFilter).mesh
colors = array(Color, mesh.vertices.Length)
for i in range(mesh.vertices.Length):
    colors _= Color.Lerp(Color.red, Color.green, mesh.vertices*.z)*_

mesh.colors = colors
But my mesh came out a solid white instead of being red, green, or a mix. What am I doing wrong?

Most normal shaders don’t use the vertex color at all. Only a few specialized shaders like all the particle shaders. Just try different shaders and you will see the vertex colors.

You can easily write your own shader that suits your needs. See this page for more details on how to use vertex colors. It’s the 4th example.

After reading up on Shaders for a few hours and seeing a few different examples, I figured out how to modify the diffuse shader to use vertex colors instead of texture colors. Here it is:

Shader "MyShader" {
SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 200

CGPROGRAM
#pragma surface surf Lambert

struct Input {
    fixed4 color : COLOR;
};

void surf (Input IN, inout SurfaceOutput o) {
    o.Albedo = IN.color;
}
ENDCG
}

Fallback "VertexLit"
}

I’m not quite sure what the Tags and LOD do, but the important parts are:

#pragma surface surf Lambert

Says that I’m going to define a surface shader called surf which I want to have use the Lambert lighting system (that’s how my mesh ends up with shadows and stuff rather than looking flat).

Since it’s a surface shader, Unity automagically figures out how to pipe data around for me. I just let it know that I need a COLOR as Input to surf - it ends up grabbing the color of the vertex, which is correct. At that point, all I have to do is write the simple one line function surf which just takes the vertex color and applies it to the SurfaceOutput.

If someone else had told me all this hours ago, it would have been pretty helpful for me, I think, so hopefully now that I’ve written this here, it’ll help others in the future.