Tile edge artifacts (OS X related?)

Hi there,

I'm working on an application using Cesium b22 and I'm noticing some pretty bad tile edge "smearing" artifacts when I zoom in close enough. This is in both Chrome and Firefox.

I initially assumed the issue was with my code but a quick search revealed a post (https://groups.google.com/forum/#!searchin/cesium-dev/jpg/cesium-dev/e29qwfUNkyk/E3q_LK-HvjwJ) that led me to try http://cesium.agi.com/Cesium/Build/Apps/CesiumViewer/, where I experienced the same issue:
https://dl.dropboxusercontent.com/u/4770694/Screen%20Shot%202013-11-04%20at%2012.10.59%20AM.png

Another strange, perhaps related issue, is that when I plot the tile extent it seems to be way off when you get close to the poles.

I'll try to test on Window ASAP. Any hints/ideas would be appreciated!

Hi,
Where are you zooming into? I haven’t seen that, but I want to make sure I’m looking in the right place. Also, how are you plotting the tile extent that doesn’t match up?

Kevin

That was Greenland, but here's one right next to Hasvik, Norway so it's easy to find:
https://dl.dropboxusercontent.com/u/4770694/Hasvik.png

I get the tile XY from the imagery provider's tiling scheme (mouse->cartesian->cartographic->positionToTileXY), then change an ExtentPrimitive's extent member like so:
tileHighlightPrimitive.extent = tilingScheme.tileXYToExtent(tilex, tile.y, maximumLevel);

This works perfectly most of the time, but starts sliding off the closer you get to the poles. Looks like an accumulating error?

Are you using the default Bing Maps imagery provider, or something else? There should be any accumulating error there. You’re definitely using the ImageryProvider’s tiling scheme, not the TerrainProvider’s tiling scheme, right?

For my application I'm using the OSM imagery provider with my own custom tiles (they're in a /Z/X/Y.jpg format so OSM was the easiest). Definitely getting the tiling scheme directly from the imagery provider. I'm not using any terrain data or provider.

The CesiumViewer artifacts are in each an every provider (that has enough resolution).

Here's a video that demonstrates the problem very clearly: https://dl.dropboxusercontent.com/u/4770694/GridImageryProvider-WebMercator.mov

I've switched to the GridImageryProvider using the WebMarcatorTilingScheme (Geographic works fine). You can see how tile artifacts and tile extent issues interact, and later in the video both disappear closer to the equator.

Update: enabling SHOW_TILE_BOUNDARIES in CentralBodyFS shows the issue clearly:


https://dl.dropboxusercontent.com/u/4770694/SHOW_TILE_BOUNDARIES.png

Any ideas on what could be the cause would be greatly appreciated.

Even if you’re not using terrain, there’s still a terrain tiling scheme because the ellipsoid itself gets tiled. I think what’s happening is that you’re grabbing the tile.x, tile.y, and tile.level coordinates of the terrain (ellipsoid) tile. The EllipsoidTerrainProvider uses the GeographicTilingScheme, so the extents of those tiles will not line up with the WebMercatorTilingScheme used by your imagery. If you can share the exact code you’re using I can probably offer some advice for fixing it.

That’s what you’re seeing when you turn on SHOW_TILE_BOUNDARIES, too. That #define causes the boundaries of terrain (not imagery) tiles to be shown.

Kevin

Right, makes sense - when I modify EllipsoidTerrainProvider to use WebMercatorTilingScheme instead of Geographic that does make SHOW_TILE_BOUNDARIES line up with the tiles, but I’m still getting the same imagery distortion issues, and as a result (I think) the highlight doesn’t line up with the imagery.

I went back to the original library source code and stripped my test code down to its basic elements (unfortunately I can’t share my imagery publicly but the TileCoordinatesImageryProvider exhibits similar issues): https://www.dropbox.com/s/76jug9y474vju84/grid-distortion.mov

require.config({

baseUrl: ‘js/Cesium-full-b22/Source’

});

require([‘Cesium’], function(Cesium) {

“use strict”;

var maximumLevel = 10;

var canvas = document.createElement(‘canvas’);

canvas.className = “fullSize”;

document.getElementById(‘cesiumContainer’).appendChild(canvas);

var ellipsoid = Cesium.Ellipsoid.WGS84;

window.scene = new Cesium.Scene(canvas);

var primitives = scene.getPrimitives();

var centralBody = new Cesium.CentralBody(ellipsoid);

var imageryProvider = new Cesium.TileCoordinatesImageryProvider({ tilingScheme: new Cesium.WebMercatorTilingScheme() });

centralBody.getImageryLayers().addImageryProvider(imageryProvider);

primitives.setCentralBody(centralBody);

var polygon = new Cesium.ExtentPrimitive({

extent : new Cesium.Extent( // will crash unless extent has an initial size

Cesium.Math.toRadians(-11.0),

Cesium.Math.toRadians(0.0),

Cesium.Math.toRadians(-9.0),

Cesium.Math.toRadians(2.0)),

material : Cesium.Material.fromType(Cesium.Material.ColorType)

});

scene.getPrimitives().add(polygon);

polygon.material.uniforms.color = new Cesium.Color(0.0, 0.0, 0.0, 0.0);

function tick() {

scene.initializeFrame();

scene.render();

Cesium.requestAnimationFrame(tick);

}

tick();

var onResize = function () {

var width = canvas.clientWidth;

var height = canvas.clientHeight;

if (canvas.width === width && canvas.height === height) {

return;

}

canvas.width = width;

canvas.height = height;

scene.getCamera().frustum.aspectRatio = width / height;

};

window.addEventListener(‘resize’, onResize, false);

onResize();

var handler = new Cesium.ScreenSpaceEventHandler(scene.getCanvas());

var curpos = { x: -1, y: -1 };

handler.setInputAction(function(click) {

var cartesian = scene.getCamera().controller.pickEllipsoid(click.endPosition, ellipsoid);

if (cartesian) {

var cartographic = ellipsoid.cartesianToCartographic(cartesian);

var tilingScheme = imageryProvider.getTilingScheme();

var tpos = tilingScheme.positionToTileXY(cartographic, maximumLevel);

if (tpos && (tpos.x != curpos.x || tpos.y != curpos.y)) {

polygon.material.uniforms.color.alpha = 0.3;

polygon.extent = tilingScheme.tileXYToExtent(tpos.x, tpos.y, maximumLevel);

}

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

});