Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Material doesn't update when canvas content or image src changes #5080

Open
hpinkos opened this issue Mar 7, 2017 · 6 comments
Open

Comments

@hpinkos
Copy link
Contributor

hpinkos commented Mar 7, 2017

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';
});
@pjcozzi
Copy link
Contributor

pjcozzi commented Mar 7, 2017

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.

@NaderCHASER
Copy link
Contributor

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.

@hpinkos hpinkos changed the title Image Material doesn't update when canvas content changes Image Material doesn't update when canvas content or image src changes Jun 26, 2018
@OmarShehata
Copy link
Contributor

@zapzqc
Copy link

zapzqc commented Nov 2, 2018

Anyone had solved it?

@OmarShehata
Copy link
Contributor

@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

@GuyAgiv
Copy link

GuyAgiv commented Dec 27, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants