how to preload material image for polygons in czml

hello team!

In my application scenario, I need to load a batch of time-based images to create a piece of animation. To achieve this, I create and attach an image material to a polygon, which forms a packet in my czml. The following code works great for me, except one thing: there is always a white flash on the polygon when its material image is loaded for the first time. When the first animation run ends and all images are loaded, it goes smoothly without any flash in next runs.

////////////////////// code start //////////////////////////

var mike21OutputCzml = ;

var imgUrl = “/images/MIKE21-outputs/OK2_withoutBuildings_500m2Elements ####.png”;

var startTimeString = “2014-02-01-11-00”;

var st = moment(startTimeString, “YYYY-MM-DD-HH-mm”);

var loopHours = 20;

for (var i = 0; i < loopHours; i++){

var template = ‘{“id”: “ITEM-ID”,“availability”: “ITEM-AVAILABILITY”,“polygon”: {“material”:{“image”:{“image”:{“image”:“ITEM-IMAGE”}}}},“vertexPositions”: {“cartographicDegrees”: [144.8814041758, -37.7535683243, 0, 144.9064154011, -37.7535683243, 0, 144.9064154011, -37.7778272223, 0, 144.8814041758, -37.7778272223, 0]}}’;

availabilityFrom = st.format(“YYYYMMDDTHHmmss”);

curTimeString = st.add(“hours”,i==0?0:1).format(“YYYY-MM-DD-HH-mm”);

availabilityTo = st.format(“YYYYMMDDTHHmmss”);

curImgUrl = imgUrl;

curImgUrl = curImgUrl.replace("####", curTimeString);

availabilityStr = availabilityFrom+"/"+availabilityTo;

var newCZMLData = template.replace(“ITEM-ID”, rec.get(“simcode”)+"_"+i);

newCZMLData = newCZMLData.replace(“ITEM-AVAILABILITY”,availabilityStr);

newCZMLData = newCZMLData.replace(“ITEM-IMAGE”,curImgUrl);

console.log("===url: "+curImgUrl);

mike21OutputCzml.push(JSON.parse(newCZMLData));

}

var czmlDataSource = new Cesium.CzmlDataSource();

czmlDataSource.load(mike21OutputCzml, “mike21”);

//finally put it into the scene

mainViewer.dataSources.add(czmlDataSource);

mainViewer.clock.multiplier = 30*100.0;

////////////////////// code end //////////////////////////

Really wanna get rid of the annoying flash. Is there any way I can preload these images to be used in czml? I have tried the following means but the flash still exists and it seems that the images just cannot be cached in these ways.

(1) call Cesium.loadImage before the above czml code

Cesium.when.all([

Cesium.loadImage(’/images/MIKE21-outputs/OK2_withoutBuildings_500m2Elements 2014-02-01-11-00.png’),

Cesium.loadImage(’/images/MIKE21-outputs/OK2_withoutBuildings_500m2Elements 2014-02-01-12-00.png’),

Cesium.loadImage(’/images/MIKE21-outputs/OK2_withoutBuildings_500m2Elements 2014-02-01-13-00.png’)

],function(images) {

console.log("==== all images loaded");

});

(2) first create polygon primitives (with image material) and add them to the scene, then run the above czml code.

Tons of thanks in advance! Any hints or tips are greatly appreciated :sunglasses:

Benny

I've got a similar problem when updating the image of a polygon of an entity... i.e. the following has white flashes between images.

   this.entity.polygon.material.image = this.images[this.clock % 13];

I managed to avoid this by instead of passing a URL to the image I pass the texture, I'm having to load the image, create a canvas, draw the image to the canvas, then convert to a texture using private API to get the context....

for (i = 0; i < 13; i++) {
  (function() {
    var localI = i;
    var img = new Image();
    img.src = sprintf("images/metoffice/rainfall/%03d.png", i);
    img.onload = function() {
      var canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      var context = canvas.getContext("2d");
      context.drawImage(img, 0, 0);
      textures[localI] = viewer.scene._context.createTexture2D({
        source : canvas,
        pixelFormat : Cesium.PixelFormat.RGBA
      });
    };
  })();
}

Now I just update the texture like this, amazingly this works, it still flickers between updates, but is transparent rather than white background...

   this.entity.polygon.material.image = this.textures[this.clock % 13];

In my project we were having the same issue of the white flashing when using entities with a rectangle having a material with a canvas image. Our solution was to switch to a primitive and update the material image as follows:

yourRenderedRectangleprimitive.material.uniforms.image = canvas.image.

Alberto

What's type is the canvas.image property you refer to? Do you just mean?

yourRenderedRectangleprimitive.material.uniforms.image = canvas

Adam.

I am facing the same problem when streaming czml data. Any workaround?

This worked!! Thanks!