- Home /
random colors for each triangle face
I'm trying to pull off an effect similar to this: http://www.creativeapplications.net/wp-content/uploads/2013/02/gif-colourstep-grow2.gif
my current strategy is to set the vertex color of each vertex of the triangle to the same color. Then randomizing that number for each triangle vertex group. I've already gotten pretty far with this
void Start ()
{
_meshFilter = GetComponentInChildren<MeshFilter>();
setColorVertecies();
}
private void setColorVertecies()
{
Mesh mesh = _meshFilter.mesh;
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
Color[] colors = new Color[vertices.Length];
Color triColor = getRandomColor();
//Debug.Log("numTri" + triangles.Length); //36, 42, 240
//Debug.Log("numVer" + vertices.Length); //24, 26, 55
for (int i = 0; i < triangles.Length; i++)
{
int vertIndex = triangles[i];
if (i % 3 == 0)
triColor = getRandomColor();
colors[vertIndex] = triColor;
}
mesh.colors = colors;
}
private Color getRandomColor()
{
float red = Random.Range(0, 1.0f);
float green = Random.Range(0, 1.0f);
float blue = Random.Range(0, 1.0f);
return new Color(red, green, blue);
}
The problem is that some of the vertices are shared between triangles and the colors are getting interpolated. I figured out after some research that each vertex needs to be unique... aka not shared but I can't figure out how to force my model to split vertices http://answers.unity3d.com/questions/248297/vertex-color-by-face.html
I thought I was on the right track by setting the mesh import smooth angle to 0 but that didn't seem to help at all: http://answers.unity3d.com/questions/125738/shade-object-flat.html
Here's a screen shot of the problem:
Is there a way to force unity to split vertices so each face can have its own solid color? Or am I on the wrong track and this effect would be easier to pull off using a shader or something?
update
Thanks @Eric5h5 and @robertbu that did the trick. I'd still like to figure out a export or import setting that could do this for me instead of doing it inside unity. This works great on simple models but I got some really complex geometry that the script is freezing on. Oh well I suppose that's a problem for my 3D software and not necessarily Unity related.
There is always the brute force approach. It would be straight forward as either a runtime script or an editor script inside of Unity to rewrite the mesh so that all the vertices are unique.
@robertbu hmmm I suppose so... seems like a bit of work and I'm having a hard time thinking about how I would rewrite the mesh. I could keep a running list of vertex indices and check for duplicate ones but once I find one how would I inject a new unique vertex into the mesh's vertex list?
Trying to modify the list would get ugly. Build new versions of both list. Here is a quick try. Attach this script to a game object that has mesh.
public class UniqueVerts : $$anonymous$$onoBehaviour {
void Start () {
$$anonymous$$eshFilter mf = GetComponent<$$anonymous$$eshFilter>();
if (mf == null) return;
$$anonymous$$esh mesh = mf.mesh;
int[] triangles = mesh.triangles;
Vector3[] vertices = mesh.vertices;
int[] trianglesNew = new int[triangles.Length];
Vector3[] verticesNew = new Vector3[triangles.Length];
for (int i = 0; i < trianglesNew.Length; i++) {
Vector3 v3Pos = vertices[triangles[i]];
trianglesNew[i] = i;
verticesNew[i] = v3Pos;
}
Color colorT = Color.red;
Color[] colors = new Color[trianglesNew.Length];
for (int i = 0; i < colors.Length; i++) {
colorT = new Color(Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), Random.Range (0.0f, 1.0f), 1.0f);
colors[i] = colorT;
}
mesh.vertices = verticesNew;
mesh.triangles = trianglesNew;
mesh.colors = colors;
mesh.RecalculateBounds();
mesh.RecalculateNormals ();
}
}
Answer by Eric5h5 · Feb 04, 2013 at 11:51 PM
Assuming you have the appropriate arrays that you got from the mesh called meshTriangles, meshVertices, etc., then this code will create unique vertices:
var newVertices = new Vector3[meshTriangles.Length];
var newUV = new Vector2[meshTriangles.Length];
var newNormals = new Vector3[meshTriangles.Length];
var newTriangles = new int[meshTriangles.Length];
// Rebuild mesh so that every triangle has unique vertices
for (var i = 0; i < meshTriangles.Length; i++) {
newVertices[i] = myVertices[meshTriangles[i]];
newUV[i] = meshUV[meshTriangles[i]];
newNormals[i] = meshNormals[meshTriangles[i]];
newTriangles[i] = i;
}
Then assign the newTriangles, newVertices, etc. arrays back to the mesh.
As of Unity 5.6 there is a new "Weld Vertices" import setting for the 3D $$anonymous$$odel. This won't make each triangle unique like the above code, but it will prevent Unity from merging duplicate vertices if you need them.
https://docs.unity3d.com/560/Documentation/$$anonymous$$anual/FBXImporter-$$anonymous$$odel.html
Your answer
Follow this Question
Related Questions
triangles colors render on top of each other 1 Answer
Strange issue with generated mesh 2 Answers
Connecting flatshaded vertices 0 Answers
Understanding verts and triangles in Unity 1 Answer
Triangles on my mesh don't show 1 Answer