how to preload material image for polygons in czml

1,109 views
Skip to first unread message

Benny Chen

unread,
Apr 4, 2014, 8:14:37 AM4/4/14
to cesiu...@googlegroups.com
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 8-)

Benny



squirre...@gmail.com

unread,
Aug 13, 2015, 5:36:15 AM8/13/15
to cesium-dev
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];

Alberto Acevedo

unread,
Aug 13, 2015, 5:03:29 PM8/13/15
to cesium-dev
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

squirre...@gmail.com

unread,
Sep 8, 2015, 4:30:01 AM9/8/15
to cesium-dev
On Thursday, 13 August 2015 22:03:29 UTC+1, Alberto Acevedo wrote:
> 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.
>

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

yourRenderedRectangleprimitive.material.uniforms.image = canvas

Adam.

Laercio Barbosa

unread,
Oct 14, 2015, 4:58:58 PM10/14/15
to cesium-dev
I am facing the same problem when streaming czml data. Any workaround?
Message has been deleted

willw...@gmail.com

unread,
Mar 22, 2017, 11:09:42 AM3/22/17
to cesium-dev
This worked!! Thanks!
Reply all
Reply to author
Forward
0 new messages