How to create animated heatmaps?

Hi @robmilton, here’s a sandcastle examplle that works in WebGL2.

And here’s a modified sandcastle that will work in CesiumJS 1.107 when createWorldTerrain and Model.fromGltf are removed for their async alternatives.

It required a few changes:

  • Renamed texture2D to texture
  • Renamed texture (the uniform) to noiseTexture (since the word texture is now reserved)
  • Use PixelFormat.RED instead of PixelFormat.LUMINANCE
1 Like

@sean_lilley thanks for the quick response and the examples! That did the trick. The “texture” reserved word was an issue we weren’t sure how to resolve (not realizing we could name that key in the material object being created).

What is the reason for the switch to PixelFormat.RED? Is that what the .r after the “texture” function is referencing?

Thanks again for the help!

Glad it works for you @Rob

The reason for switching to PixelFormat.RED is because LUMINANCE is an invalid format for floating point textures in WebGL 2. It shows up as this error in the console in Chrome:

[.WebGL-0x13c04839500] GL_INVALID_OPERATION: Invalid internal format 0x1909.

I didn’t actually have to change the .r part. It works the same for either format. The main difference between LUMINANCE and RED is that LUMINANCE returns the same value for .r, .g, and .b whereas RED return a value for .r and 0 for the other channels.

Hi @Rob , I appreciate you asking this question, I am also trying to display heatmaps in a performant manner. Were you able to take the example from @sean_lilley and produce an example with the ability to accept an array of points?

It looks like there are many who would benefit from an example / updated library on this issue

Hey all! I’m trying to implement an “animated” heatmap as well. I am using a modified version of this code:

I had to make a number of changes to integrate the code into our app, but basically this is working for me now.

The problem is, our heatmaps change over time as the scene progresses, and we are getting a “flicker” every time the heatmap data changes.

The “setData” function calls “updateLayer”, which removes the previous cesium entity and adds a new one.

This is causing the flicker. If I comment out the call to “updateLayer”, the heatmaps just accumulate.

I have tried using a single entity and updating the “image” value, but this still causes a flicker.

I see in the Cesium docs that there is something called a “Fade” Material. I thought maybe I could use this to get the images to fade in and out when the data is updated, and that this might eliminate the flicker. But I haven’t managed to figure out how to do this.

Does this seem like a good idea? Any suggestions would be hugely appreciated!

Many thanks!!

1 Like

hey , everyone.
I am using also a primitive , and i am using a custom material and rendering a computed image inside of it (base64 string format). it works , but because I am in 2.5D mode, I cannot use modelMatrix to change the positions of the primitive based on the compute FOV. hence, I am removing and adding in every camera move end. unfortunately , it means i may experience flickers. maybe someone used a CustomShader to do it and can share some code ?

can you tell what are the major modification you have done to make it work with the new version of cesium ?

Thank you,

I recently work out a heatmap component in my frontend development by using CesiumHeatmap/HeatmapImageryProvider.js
See: x.com
In my use case I need manually modify the _getContainer method, so that it can correctly append under cesium viewer container. But it may depend on use case:

HeatmapImageryProvider.prototype._getContainer = function(width, height, id) {
    const c = document.createElement("div");
    if (id) { c.setAttribute("id", id); }
    c.setAttribute("style", `width: ${width}px; height: ${height}px; margin: 0px; display: none; left: 0; top: 0; position: absolute; z-index: -1`);
    const cesiumContainer = document.querySelector("#cesiumContainer > div > div.cesium-viewer-cesiumWidgetContainer > div");
    cesiumContainer.appendChild(c);
    return c;
};

I also find the heatmap.js had inappropriate _organiseData method which use nested structure of data, and cannot fit into _drawAlpha method. I changed it to

  _organiseData(dataPoint, forceRender) {
    //skip..
    this._data.push({ x, y, value, radius });
    if (value > this._max) {
      if (!forceRender) {
        this._max = value;
      }
    }

Then heatmap.js can work with HeatmapImageryProvider.js on CesiumJS. But for current CesiumJS version, I need to convert heatmap.js to ESM module.