Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cesium DataSourceCollection layer ordering

I have multiple GeoJsonDataSource objects that I want to put on a Cesium globe. The problem is that if they overlap, I get some z-fighting issues and I can't adjust their order.

Is there a way of specifying the order of DataSource objects in a DataSourceCollection?

For example, I'd like to have the green polygon on top of the red polygon using the following code:

var viewer = new Cesium.Viewer('cesiumContainer');

var red = Cesium.GeoJsonDataSource.load('map1.geojson', {
  fill: new Cesium.Color(1, 0, 0, 1.0)
});

var green = Cesium.GeoJsonDataSource.load('map2.geojson', {
  fill: new Cesium.Color(0, 1, 0, 1.0)
});

viewer.dataSources.add(red);
viewer.dataSources.add(green);

However, the result looks like this:

Cesium screenshot showing z-fighting

I've noticed that if I adjust the alpha argument to less than 1.0, I can fix the z-fighting, but the order still does not get addressed.

like image 608
austin Avatar asked Mar 21 '16 13:03

austin


3 Answers

Update 12/2019:

Cesium has added a zIndex property to PolygonGraphics in the time since this was originally asked. It's only valid for "ground primitives", for example polygons that lie directly on terrain and do not have height or extrudedHeight properties assigned to them. For those, use my original answer below. But for ground primitives, you can now just assign a zIndex like this:

var viewer = new Cesium.Viewer('cesiumContainer');

var redPolygon = viewer.entities.add({
    name : 'Red polygon',
    polygon : {
        hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
                                                        -115.0, 32.0,
                                                        -102.0, 31.0,
                                                        -102.0, 38.0]),
        material : new Cesium.Color(1, 0, 0),
        zindex : 1
    }
});

var greenPolygon = viewer.entities.add({
    name : 'Green polygon',
    polygon : {
        hierarchy : Cesium.Cartesian3.fromDegreesArray([-118.0, 42.0,
                                                        -100.0, 42.0,
                                                        -104.0, 32.0]),
        material : new Cesium.Color(0, 1, 0),
        zIndex : 2
    }
});

viewer.zoomTo(viewer.entities);

Original answer:

At the bottom of your question, you mentioned the quick-fix for z-fighting is to simply to turn off the Z buffer for these polygons, by setting some transparency. Transparency happens in an 8-bit Alpha channel, so my favorite value to use is 254.0 / 255.0, or 0.996.

But there's another option you'll probably want to turn off, and that's orderIndependentTranslucency. This is a property of Scene that can be initialized from an options parameter in Viewer's constructor. When left on, the default for systems that support it, one can always "see" translucent objects behind other translucent objects, regardless of the opacity, and of course the render order doesn't affect the result. But in this case, you want the render order to affect the result, if you want one polygon to obscure the other one.

Here's an example. Click "Run Code Snippet" at the bottom, or paste just the JavaScript section into Sandcastle.

var viewer = new Cesium.Viewer('cesiumContainer', {
    navigationInstructionsInitiallyVisible: false, animation: false, timeline: false,

    // The next line is the important option for this demo.
    // Test how this looks with both "true" and "false" here.
    orderIndependentTranslucency: false
});

var redPolygon = viewer.entities.add({
    name : 'Red polygon',
    polygon : {
        hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
                                                        -115.0, 32.0,
                                                        -102.0, 31.0,
                                                        -102.0, 38.0]),
        // The alpha of 0.996 turns off the Z buffer.
        material : new Cesium.Color(1, 0, 0, 0.996)
    }
});

var greenPolygon = viewer.entities.add({
    name : 'Green polygon',
    polygon : {
        hierarchy : Cesium.Cartesian3.fromDegreesArray([-118.0, 42.0,
                                                        -100.0, 42.0,
                                                        -104.0, 32.0]),
        // The alpha of 0.996 turns off the Z buffer.
        material : new Cesium.Color(0, 1, 0, 0.996)
    }
});

viewer.zoomTo(viewer.entities);
html, body, #cesiumContainer {
  width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
  font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.19/Build/Cesium/Widgets/widgets.css" 
      rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.19/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>
like image 92
emackey Avatar answered Nov 04 '22 04:11

emackey


Answer is simple, You can add z-index in your code.

var viewer = new Cesium.Viewer('cesiumContainer');

var red = Cesium.GeoJsonDataSource.load('map1.geojson', {
  fill: new Cesium.Color(1, 0, 0, 1.0),
  zIndex: 1
});

var green = Cesium.GeoJsonDataSource.load('map2.geojson', {
  fill: new Cesium.Color(0, 1, 0, 1.0),
  zIndex: 2
});

viewer.dataSources.add(red);
viewer.dataSources.add(green);
like image 38
Tekson Avatar answered Nov 04 '22 04:11

Tekson


It might be useful for a bit different case: enter image description here polygons have heights and some of them might be transparent or not , also polygon layers lie on top of each other. For resolving z-fighting in this case the good approach is removing bottom part of polygons with option flag {closeBottom: false}. I have adapted code for this case from above comment:

var viewer = new Cesium.Viewer('cesiumContainer', {
navigationInstructionsInitiallyVisible: false, animation: false, timeline: false,

// The next line is the important option for this demo.
// Test how this looks with both "true" and "false" here.
orderIndependentTranslucency: false
});

var redPolygon = viewer.entities.add({
name : 'Red polygon',
polygon : {
    hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
                                                    -115.0, 32.0,
                                                    -102.0, 31.0,
                                                    -102.0, 38.0]),
    // The alpha of 0.996 turns off the Z buffer.
    material : new Cesium.Color(1, 0, 0, 1),
    closeBottom: false,
    height: 1000,
    extrudedHeight: 50100
}
});

var greenPolygon = viewer.entities.add({
name : 'Green polygon',
polygon : {
    hierarchy : Cesium.Cartesian3.fromDegreesArray([-118.0, 42.0,
                                                    -100.0, 42.0,
                                                    -104.0, 32.0]),
    // The alpha of 0.996 turns off the Z buffer.
    material : new Cesium.Color(0, 1, 0, 0.29),
    height: 50100,
    extrudedHeight: 95000,
    closeBottom: false
}
    });

viewer.zoomTo(viewer.entities);
like image 1
Oleg Bondarenko Avatar answered Nov 04 '22 06:11

Oleg Bondarenko