cesium
cesium copied to clipboard
Image Material doesn't update when canvas content or image src changes
Reported on the forum: https://groups.google.com/forum/?hl=en#!topic/cesium-dev/7Bda_BkaJMU
The canvas used for the image material is updating, but the rectangle itself does not. It's because we only read from the canvas once and then it's skipped for subsequent updates https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/Material.js#L762
Is there any way to detect if a canvas has changed?
<style>
@import url(../templates/bucket.css);
#canvas {
position: absolute;
left: 0;
top: 50px;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>
<canvas id="canvas" width="800" height="200"></canvas>
var viewer = new Cesium.Viewer('cesiumContainer');
var i = 0;
function drawCanvas() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = 'italic 40pt Calibri';
context.fillStyle = "white";
context.fillText(i++, 20, 100);
return canvas;
}
viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(-92.0, 30.0, -76.0, 40.0),
material: new Cesium.ImageMaterialProperty({
image: new Cesium.CallbackProperty(drawCanvas, false),
transparent: true
})
}
});
viewer.zoomTo(viewer.entities);
image example:
var viewer = new Cesium.Viewer('cesiumContainer');
var image = new Image(100, 200);
image.src = '../images/Cesium_Logo_Color.jpg';
var material = Cesium.Material.fromType('Image', {
image: image
});
viewer.scene.primitives.add(new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.RectangleGeometry({
rectangle : Cesium.Rectangle.fromDegrees(-120.0, 30.0, -110.0, 40.0),
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
})
}),
appearance : new Cesium.EllipsoidSurfaceAppearance({
material : material
})
}));
Sandcastle.addToolbarButton('Change image', function() {
image.onload = function(){
material.uniforms.image = image;
};
image.src = '../images/Cesium_Logo_overlay.png';
});
This is by design. We can consider adding something like a dynamic
flag to update the WebGL texture from the canvas each frame; in the meantime, the app should explicitly update it.
Might something like this be able to support updating tiles as well?
For instance, I'd like to visualize wind in Cesium. My data is tiled PNGs with raw UV vector values encoded into the Red and Green bands. (https://mapbox.github.io/webgl-wind/demo/)
I can get the particles dropped but updating the canvas to move them isn't possible with the current Imagery/ImageryLayer implementation.
Reported again here: https://groups.google.com/d/msg/cesium-dev/D4Nre2wu3II/KuCki2YsAAAJ
Anyone had solved it?
@zapzqc looks like a workaround is to use two canvasas to swap between, more on that here: https://groups.google.com/d/msg/cesium-dev/7Bda_BkaJMU/mfAM7WraBAAJ
This is by design. We can consider adding something like a
dynamic
flag to update the WebGL texture from the canvas each frame; in the meantime, the app should explicitly update it.
@pjcozzi I'll be glad to know how to update the WebGL texture explicit