- Home /

# Is it possible to create a colour gradient across an entire mesh if only a few vertices have colour?

I have been struggling to create a shader for my model of ~40,000 vertices. I have 144 vertices which I have assigned a colour to. (These 144 vertices represent real life data that I have obtained from sensors, so I can not increase the number of vertices initially coloured)

I would like to create a colour gradient between these vertices, so that the entire model is coloured, similar to a heat map.

I've tried using Lerp on the vertex matrix, but because the vertex numbers are seemingly random compared to their location, I'm not getting the interpolation between appropriate locations, rather neighbouring vertex numbers.

I have tried using something similar to this, but as I have so few vertices initially coloured, I just end up with a black model with colours spots: https://forum.unity.com/threads/standard-shader-with-vertex-colors.316529/

My question: is it possible to do it in this way? If not, is there another way? I can't seem to find one.

**Answer** by Harinezumi
·
Apr 09, 2018 at 03:09 PM

Interesting, I've been working on something scarily similar...

Anyway, I just iterate through all the vertices of the model (mine is about 9000 vertices), and interpolate using the distance from each of my colored points. I use a `Gradient`

object and a `float[] heatValues`

(one value for each vertex) that stores the current "heat" value, then evaluate the gradient for each vertex, and finally assign the vertex colors.

It is faster than expected, there's no FPS drop even if I update every frame.

Does this make sense?

That definitely makes me feel less crazy attempting this! Your description makes sense, just in the process of trying to write the code to do it - thank you :)

For some reason, I can't get it to work. I end up with a fuzzy one coloured object. I've tried debugging and I think the logic is correct, but something (obviously) isn't right...

Here is the method I've written for the colour interpolation, I've tried to base it on your advice, but I'm not sure where I'm going wrong!

```
private void ColourInterpolation()
{
List<KeyValuePair<float, Vector3>> distances = new List<KeyValuePair<float, Vector3>>();
for (int i = 0; i < _vertices.Length; i++)
{
var skip = false;
foreach (var sensor in _sensorLocations)
{
var localVertex = transform.TransformPoint(_vertices[i]);
if (sensor.Value.x == Math.Round(localVertex.x, 1) &&
sensor.Value.y == Math.Round(localVertex.y, 1) &&
sensor.Value.z == Math.Round(localVertex.z, 1))
{
skip = true;
break;
}
}
if (skip)
{
skip = false;
continue;
}
KeyValuePair<int, Vector3> min1 = new KeyValuePair<int, Vector3>();
KeyValuePair<int, Vector3> min2 = new KeyValuePair<int, Vector3>();
float min1Distance = float.MaxValue;
float min2Distance = float.MaxValue;
foreach (KeyValuePair<int, Vector3> sensor in _sensorLocations)
{
float distance = Vector3.Distance(_vertices[i], sensor.Value);
if (distance < min1Distance)
{
min2Distance = min1Distance;
min1Distance = distance;
min2 = min1;
min1 = sensor;
}
else if (distance < min2Distance)
{
min2 = sensor;
min2Distance = distance;
}
}
float proportion = Math.Abs(min1Distance / (min1Distance + min2Distance)); // Gives proprtion towards min1
_colors[i] = Color32.Lerp(_colors[min1.Key], _colors[min2.Key], proportion);
}
```

Your algorithm seems good, but I think you need the *3* closest sensors to get a uniformly interpolated color in 3D, and you might need to do interpolate using barycentric coordinates, see this article.

I think you can also simplify the check if the vertex is one of the sensors like this:

```
// this works if _sensorLocations is a dictionary of vertex index to sensor vertex position
if (_sensorLocations.ContainsKey(i)) { continue; }
```

Something still isn't right with my interpolation...I'm now getting multiple colours, but I'm getting a massive mess...think an explosion in a paint factory! I've adapted the barycentric equations to incorporate 3D rather than just 2D, but the results seem to be the same.

Is there something obvious I'm doing wrong?

```
KeyValuePair<int, Vector3> min1 = new KeyValuePair<int, Vector3>();
KeyValuePair<int, Vector3> min2 = new KeyValuePair<int, Vector3>();
KeyValuePair<int, Vector3> min3 = new KeyValuePair<int, Vector3>();
float min1Distance = float.MaxValue;
float min2Distance = float.MaxValue;
float min3Distance = float.MaxValue;
foreach (KeyValuePair<int, Vector3> sensor in _sensorLocations)
{
float distance = Vector3.Distance(_vertices[i], sensor.Value);
if (distance < min1Distance)
{
min3Distance = min2Distance;
min2Distance = min1Distance;
min1Distance = distance;
min3 = min2;
min2 = min1;
min1 = sensor;
}
else if (distance < min2Distance)
{
min3 = min2;
min2 = sensor;
min3Distance = min2Distance;
min2Distance = distance;
}
else if (distance < min3Distance)
{
min3 = sensor;
min3Distance = distance;
}
}
float Xv1 = min1.Value.x;
float Xv2 = min2.Value.x;
float Xv3 = min3.Value.x;
float Yv1 = min1.Value.y;
float Yv2 = min2.Value.y;
float Yv3 = min3.Value.y;
float Zv1 = min1.Value.z;
float Zv2 = min2.Value.z;
float Zv3 = min3.Value.z;
float Px = _vertices[i].x;
float Py = _vertices[i].y;
float Pz = _vertices[i].z;
float Wv1 = ((Yv2 - Yv3) * (Px - Xv3) + (Xv3 - Xv2) * (Py - Yv3)) / ((Yv2 - Yv3) * (Xv1 - Xv3) + (Xv3 - Xv2) * (Yv1 - Yv3));
float Wv2 = ((Yv3 - Yv1) * (Px - Xv3) + (Xv1 - Xv3) * (Py - Yv3)) / ((Yv2 - Yv3) * (Xv1 - Xv3) + (Xv3 - Xv2) * (Yv1 - Yv3));
float Wv3 = (Pz - Wv1*Zv1 - Wv2*Zv2)/Zv3;
Byte r = (Byte)((_colors[min1.Key].r * Wv1 + _colors[min2.Key].r * Wv2 + _colors[min3.Key].r * Wv3) / 3);
Byte g = (Byte)((_colors[min1.Key].g * Wv1 + _colors[min2.Key].g * Wv2 + _colors[min3.Key].g * Wv3) / 3);
Byte b = (Byte)((_colors[min1.Key].b * Wv1 + _colors[min2.Key].b * Wv2 + _colors[min3.Key].b * Wv3) / 3);
_colors[i] = new Color32(r, g, b, 255);
```

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

convert gradient in to color keys 1 Answer

In search of a gradient editor tool.. 0 Answers

Vertex colour based on distance from transform center 2 Answers

Changing two different objects renderer colour 1 Answer

Light bandings 0 Answers