How to translate vertices values to RBG based on a colormap

Hello,
I’m creating custom meshes from a brain reconstruction:
https://playground.babylonjs.com/#EQ46H3#8
I want to plot an activity. As input, I have a value per vertice and a colormap (hot for example).
Is there an easy way to translate the values to RGB values based on the colormap?

Welcome aboard!

What is the value you have per vertex exactly? Is your colormap a 1d map? So you would simply need to lookup colormap[activity * texture_width] (if activity is between 0 and 1) to get the RGB values for the vertex?

I think providing thoses values as well as the colormap will ease understanding what has to be done.

1 Like

Thanks Evgeni!
I would like to support any type of brain activation that can be plotted on the cortical surfaces, meaning there is a value per vertice. I can normalize the activity to be between 0 and 1.
You can find an example for such an activity here. These values are not normalized though.
For the colormap, I’m looking for something equivalent to the python matplotlib colormaps, like hot, or even better, YlOrRd.
Thanks!

Here’s a way to do it:

https://playground.babylonjs.com/#EQ46H3#10

It is normalizing the data (I have taken the first file you provided and put the data in the activities array) and sets them as a new activity attribute.

I’m also creating a texture for the colormap (I have taken the plasma scale in the page you linked).

Then I’m using some custom shader code to lookup in the texture the color to use for the vertex.

There’s an easier way which would be to set the color attribute with the right values in the js code. Basically, in the js code you would read the colormap texture for each activity value and create an array with those colors, that you would set like rightVertexData.colors = rightColors. With my solution, however, you can easily change the colormap by simply binding another texture to the colormap uniform.

1 Like

Thanks so much! That looks fantastic!
How did you define the plasma scale? Did you create this png image? And how can I find other maps?
Also, I want to create a texture for only the values about a threshold (let’s say 0.2). Is there an easy way to do something like that? Maybe I can use alpha=1 where the values are below the threshold?

I just copied the part of the image I was interrested in (the plasma) from your link (Choosing Colormaps in Matplotlib — Matplotlib 3.1.0 documentation) and saved it as a .png, which I converted to base 64 (Base64 Image Encoder - Online Tool).

Update the shader code and set a fixed vColor when the activity is below the threshold:

https://playground.babylonjs.com/#EQ46H3#11

1 Like

Thanks so much!
btw, do you have any idea why your playground seems to work on my end only on Firefox (Windows 10)?
On Chrome and Edge the right part is blank.

What I see on my end on both Chrome and Firefox:

You don’t see the same thing?

Nope, it’s completely blank. It does work after I set manually the min and max though. Maybe it’s a memory error?
That’s the error I’m getting in the console:
Uncaught (in promise) RangeError: Maximum call stack size exceeded
at createScene (:22:22)

It must be the Math.min/max(...activities) syntax which uses a lot of memory. You should replace it by a standard loop that computes the min/max of the values (I did it this way only because I was lazy!).

1 Like