Apply colormap to a mesh

In a plane geometry, i have two value at some percentage area of Mesh and another value at remaining percentage area of Mesh (continuous area).

I want to apply the heat map based on static value at two area of each of the two meshes.

How can i do that?

Thank you

It is not quite clear what you ask for.

If you want to add a gradient to the water tank (e.g. top is red, bottom is blue, percentage determines where red becomes blue), you have several options:

  • Draw the gradient with Canvas2D and apply it as a TextureCanvas to the water tank mesh. To change the hot/cold proportion, redraw the Canvas2D gradient.
  • Have one long gradient image (e.g. as JPEG file) and apply it as a texture to the water tank. To change the proportion of hot/cold slide the texture up or down (with texture’s offset property).
  • You can go without textures, by using vertex colors with fixed red/blue colors. The GPU will make the gradient. You only have to move the inner vertices depending on the hot/cold proportion.

These three approaches are illustrated below (if I were you, I’d pick the second approach):

1 Like

Modified fragment shader is also an option:

1 Like

@prisoner849 wow !! awesome !! Is it possible if you can share the snippet?

Hi, @PavelBoytchev Thank you so much for such a well-articulated answer and not only answering the question but also teaching the ideas.

In my case I am trying to simulate the heat transfer so, for instance, it might be yellow and blue as two color values representing hot and cold water temperature in the water tank/Mesh ( hot water is top and cold water is at the bottom) and after some time the hot and cold water temperature will be different than previous instance because hot and cold water at top and bottom both will be hotter than the previous value because of solar.

So I think I need more than 2 color heat maps and I am not able to understand how can i do that.

like this:

image

1 Like

Both @prisoner849’s option with the shader and my three options can be made to work with multiple colors. For multiple colors (and the possibility for you to pick colors and their positions in the tank), the CanvasTexture is my favorite option.

As it is too late now in my time zone, I will have a look tomorrow for a small example with canvas texture (if nobody else has answered your question by then).

But at a time, I only have two colors to be painted which might be at 0.2 and 0.3 positions in the color map. After some time not my 0.3 position color for hot becomes cold temperature and the next hot temperature is 0.4 so It needs to be painted color at 0.3 and 0.4 likewise after that 0.4 and 0.5.

But within the time when there are two certain colors in the tank, the level of color should change. I don’t know how can I achieve both things.

I am just making sure I was able to articulate the problem statement.

Here you are: https://codepen.io/prisoner849/full/OJwqxBy

1 Like

Hi, @prisoner849 Golden stuff !! Thank you so much !!

What will be the code in the fragment shader if I have 4 or 5 colors?

If i want to change the color index of 1 and 2 as 2 and 3 when use move the slider up and eventually 3 and 4 when moved further

Creativity is up to you :slight_smile:
For simplicity, with multiple colours, I would go the way of CanvasTexture with gradients.

but like you have done with


 diffuseColor.rgb = mix(colorCold, colorHot, colorRatio);

I only need two colors at a time, but I need different colorCold and hot at other times.

I think this is more efficient than the gradient texture. Am I thinking wrong?

I modified the codepen.

There are still two colours.
You can access and change them via
m.userData.colors.value[0 /*or 1*/].set(_valid_value_);

2 Likes

in the smooth step function, you have three parameters passed into it

float colorRatio = smoothstep(heatRatio - 0.5, heatRatio + 0.5, vUv.y);

vUV is not defined anywhere in the code, is it correct?

Thank you @prisoner849 for an awesome solution I managed to get it as per my problem.

Thank you so much.

I also have to color the collector which is another small mesh on the left of the Water Tank.

I did this

  let tank = new THREE.Mesh(tankGeometry, tankMaterial);
  tank.rotation.x = Math.PI * 0.5;
  const collectorGeometry = new THREE.PlaneGeometry(20, 50);
  const collectorMaterial = tankMaterial.clone();
  let collector = new THREE.Mesh(collectorGeometry, collectorMaterial);
  collector.rotation.x = Math.PI * 0.5;
  scene.add(tank);
  scene.add(collector);

where tankMaterial is the material created using the onBeforeCompile.

This is not copying the material code but rather it is white like this

image