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.67k stars 3.44k forks source link

Multiple local imagery layers support #2047

Closed ezze closed 10 years ago

ezze commented 10 years ago

We have a web service where recent images received from satellites are published as soon as they are processed. These images are organized as tile caches with restricted area of tiling scheme, and the service is based on WorldWind.

multiple-local-imagery-world-wind

I'm looking for a possibility to replace the globe by Cesium 'cause requiring Java plugin to run the globe leads to a number of support issues. Unfortunately, I was not able to use Cesium for that purpose. When few imagery layers are loaded and intersected I see black rectangles appeared/disappeared at some zoom levels.

multiple-local-imagery-1 multiple-local-imagery-2

Running the same code on server gives the following error:

[GL] Shader program link log: error: Too many fragment shader texture samplers

I've already faced this problem some time ago attempting to load global imagery layer with 10x5 tiles on level zero. In the example I use 6 TMS-like tile caches with 2x1 tiles on level zero (it's not really TMS as stated by Kevin Ring).

To be honest, I'm not familiar with how imagery layers' rendering is implemented and what the restrictions of WebGL are but keeping in mind that WorldWind is also based on OpenGL and supports large quantity of tiled imagery layers I hope that it's also possible with Cesium. Could you, guys, consider whether it's possible to render more than a couple of imagery layers at the same time? Otherwise, Cesium is very limited in area of imagery layers.

Here is the live demo and here is the code snippet:

var cesiumWidget = new Cesium.CesiumWidget(document.querySelector('.globe-container'));
var scene = cesiumWidget.scene;
var imageryLayers = scene.imageryLayers;

imageryLayers.removeAll();

var baseUrl = window.location.protocol + '//' + window.location.host;

var worldImageryProvider = new Cesium.SingleTileImageryProvider({
    url: baseUrl + '/data/bmng-07-2004-world.jpg'
});
var worldImageryLayer = new Cesium.ImageryLayer(worldImageryProvider);
imageryLayers.add(worldImageryLayer);

var tileCaches = {
    'meteorm1-25118': new Cesium.Rectangle(
        Cesium.Math.toRadians(2.2215361372),
        Cesium.Math.toRadians(18.6570665140),
        Cesium.Math.toRadians(144.9074031091),
        Cesium.Math.toRadians(90.0000000000)
    ),
    'metopb-9541': new Cesium.Rectangle(
        Cesium.Math.toRadians(13.2031071361),
        Cesium.Math.toRadians(22.5063659218),
        Cesium.Math.toRadians(80.6967412142),
        Cesium.Math.toRadians(90.0000000000)
    ),
    'noaa19-28081': new Cesium.Rectangle(
        Cesium.Math.toRadians(10.8748087590),
        Cesium.Math.toRadians(18.2535563528),
        Cesium.Math.toRadians(154.3676960534),
        Cesium.Math.toRadians(90.0000000000)
    ),
    'npp-14116': new Cesium.Rectangle(
        Cesium.Math.toRadians(-14.4320029172),
        Cesium.Math.toRadians(27.1380832790),
        Cesium.Math.toRadians(100.6368868458),
        Cesium.Math.toRadians(84.6725281604)
    ),
    'npp-14143': new Cesium.Rectangle(
        Cesium.Math.toRadians(15.2029946554),
        Cesium.Math.toRadians(32.6892267086),
        Cesium.Math.toRadians(129.8245412382),
        Cesium.Math.toRadians(90.0000000000)
    ),
    'terra-77603': new Cesium.Rectangle(
        Cesium.Math.toRadians(32.5790415981),
        Cesium.Math.toRadians(16.9849693120),
        Cesium.Math.toRadians(105.5940722861),
        Cesium.Math.toRadians(90.0000000000)
    )
};

for (var tileCacheName in tileCaches) {
    if (!tileCaches.hasOwnProperty(tileCacheName))
        continue;
    var url = baseUrl + '/data/tms/512x512/' + tileCacheName;
    var rectangle = tileCaches[tileCacheName];
    var tileMapServiceImageryProvider = new Cesium.TileMapServiceImageryProvider({
        url: url,
        rectangle: rectangle,
        tilingScheme: new Cesium.GeographicTilingScheme({
            rectangle: rectangle
        })
    });

    var imageryLayer = new Cesium.ImageryLayer(tileMapServiceImageryProvider);
    imageryLayers.add(imageryLayer);
}
kring commented 10 years ago

Which version of Cesium are you using? Starting with 1.0 (or maybe the version before that) you should be able to render an unlimited number of imagery layers, though performance will of course degrade as you add more. You'll get better performance by keeping each ImageryProvider's rectangle property as tight as possible. That "Too many fragment shader texture samplers" error is what you used to get in older versions of Cesium.

The black areas are mysterious though. What operating system and GPU is this? Are the drivers up to date? Are you certain your server isn't returning black tiles under load?

ezze commented 10 years ago

Yes, probably, I had outdated version of Cesium on the server, and yes, I wasn't using actual drivers for my video card. Operating system is Ubuntu 14.04 and video card is GeForce GT630M. After installing recent proprietary NVIDIA driver 331 from the repository the problem went away. It seems that everything works fine now.

Thank you for the help. Sorry, my bad...

kring commented 10 years ago

No problem, glad it's working for you.