CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.77k stars 3.46k forks source link

Animation support in Cesium3DTileStyle #5343

Open SunBlack opened 7 years ago

SunBlack commented 7 years ago

Currently you can implement animations in Cesium3DTileStyle only by modifying style in each frame, which causes a recompilation of shader. To prevent this we need a uniform containing the current time.

I see two possible implementation strategies we could use:

Option 1: Implementing ${TIME} should be easy - but there are some difficult questions: Which is the start time of ${TIME}? Is 0 start of UNIX time or is 0 time of first frame of this shader? If you want be sure animation starts by 0 you need time of first frame. But if you store time of first frame and you have multiple styles it is hard to synchronize animations. So we could in my opinion we don't should provide this option, if we implement option 2.

Option 2: With adding support of user defined uniforms implementation of animations needs some more lines to user, but you can implement all variables like you want and you have a little better performance (e.g. you can process ${TIME} % 100 once on CPU side instead on GPU side for each vertex). And of course you can use this uniforms for other variables, too ;-).

What do you think about it? It could be we need this in near future, so maybe (if I have time and it has enough priority for us) I will implement it.

lilleyse commented 7 years ago

Option 1 already exists actually: https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/Styling#tiles3d_tileset_time. It starts when the tileset is loaded, so different tiles should be synchronized.

Option 2: that could be an interesting idea. Would the "uniform" be written with the regular style syntax? If so, this could build on top of multiple expressions along with your comment. If the expression doesn't reference any per-point properties it can be sent as a uniform instead of evaluated on the gpu like it is now. Possibly no spec-work required, just under-the-hood optimizations.

SunBlack commented 7 years ago

Ah good to know that there exists already a timing function. Nevertheless I don't believe it is possible to synchronize animation between different tilesets or objects with it.

Option 2: No, it has not really do to with multiple expressions. Multiple expressions are just glsl optimizations to reduce redundant calculations. With uniforms you could instead introduce dynamic values from JS side.

E.g.:

style['color'] = {
        uniform : [
                "myUniformColor": 'vec4'
        ],
    'conditions': [
        ['length(${POSITION_ABSOLUTE}) < 100000', 'vec4(0.0)'],
        ['length(${POSITION_ABSOLUTE}) > 100100', '0.1 * ${myUniformColor}'],
        ['length(${POSITION_ABSOLUTE}) > 100200', '0.9 * ${myUniformColor}'],
        ['length(${POSITION_ABSOLUTE}) > 100300', '${myUniformColor}'],
        [true, 'vec4(1.0, 0.5, 0.5, 1.0)']
    ]
};
var tileStyle = new Cesium.Cesium3DTileStyle(style);
//modify it in combination with user interaction, device sensor or something like this
tileStyle.setUniformValue('myUniformColor', 'vec4(1.0, 0.5, 0.25, 0.125)')
lilleyse commented 7 years ago

Ok I see. That would be nice to have if you are interested in implementing it.

pjcozzi commented 7 years ago

For option 2, in the early days of styling when the language was very limited, we actually had the ability to change the operand in an expression at runtime without recompiling. We would like to have this again, but I don't know if it will be as simple as exposing these "uniforms" (think about this in the general sense, not just from a GLSL implementation perspective). It would be great if it is; the previous implementation basically allowed access to what the AST would be, but that is overkill.

We should take a holistic view here and think about styling in general with both JavaScript and GLSL backends, what the level of allowed modification should be, and what the various use cases are that drive this.

@SunBlack please propose and prototype something but please excuse us if we are slow to review as we are heads down finishing up #5308.

katSchmid commented 1 year ago

is that something still possible?

ggetz commented 1 year ago

@katSchmid Some initial work was done in https://github.com/CesiumGS/cesium/pull/5380, but more work would need to be done to get this feature in. Let us know if you have interest in contributing. Thanks!

katSchmid commented 1 year ago

Looking into it unfortunately might not be my decision if the code is public in the end