Cesium DataSourceCollection层排序
Cesium DataSourceCollection layer ordering
我有多个 GeoJsonDataSource
对象要放在铯球上。问题是如果它们重叠,我会遇到一些 z-fighting 问题,我无法调整它们的顺序。
有没有办法指定 DataSource
个对象在 DataSourceCollection
中的顺序?
例如,我想使用以下代码将绿色多边形置于红色多边形之上:
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);
然而,结果是这样的:
我注意到如果我将 alpha 参数调整到小于 1.0
,我可以修复 z-fighting,但顺序仍然没有得到解决。
2019 年 12 月更新:
Cesium 在最初提出这个问题后在 PolygonGraphics
中添加了 zIndex
属性。它仅对 "ground primitives" 有效,例如直接位于地形上且未分配 height
或 extrudedHeight
属性的多边形。对于那些,请使用下面我的原始答案。但是对于地面图元,您现在可以像这样分配 zIndex
:
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);
原回答:
在你的问题的底部,你提到了 z-fighting 的快速修复是通过设置一些透明度来简单地关闭这些多边形的 Z 缓冲区。透明度发生在 8 位 Alpha 通道中,所以我最喜欢使用的值是 254.0 / 255.0
或 0.996
.
但是您可能想要关闭另一个选项,那就是 orderIndependentTranslucency
。这是 Scene
的 属性,可以从 Viewer 的构造函数中的选项参数初始化。如果启用,支持它的系统的默认设置,一个人总是可以 "see" 在其他半透明对象后面的半透明对象,无论不透明度如何,当然渲染顺序不会影响结果。但在这种情况下,如果您希望一个多边形遮挡另一个多边形,您希望渲染顺序影响结果。
举个例子。单击底部的 "Run Code Snippet",或仅将 JavaScript 部分粘贴到 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>
它可能对一些不同的情况有用:
多边形具有高度,其中一些可能是透明的或不透明的,多边形层也位于彼此之上。
在这种情况下,为了解决 z-fighting,好的方法是使用选项标志 {closeBottom: false} 移除多边形的底部。
我从上面的评论中为这个案例改编了代码:
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);
答案很简单,您可以在代码中添加z-index
。
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);
我有多个 GeoJsonDataSource
对象要放在铯球上。问题是如果它们重叠,我会遇到一些 z-fighting 问题,我无法调整它们的顺序。
有没有办法指定 DataSource
个对象在 DataSourceCollection
中的顺序?
例如,我想使用以下代码将绿色多边形置于红色多边形之上:
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);
然而,结果是这样的:
我注意到如果我将 alpha 参数调整到小于 1.0
,我可以修复 z-fighting,但顺序仍然没有得到解决。
2019 年 12 月更新:
Cesium 在最初提出这个问题后在 PolygonGraphics
中添加了 zIndex
属性。它仅对 "ground primitives" 有效,例如直接位于地形上且未分配 height
或 extrudedHeight
属性的多边形。对于那些,请使用下面我的原始答案。但是对于地面图元,您现在可以像这样分配 zIndex
:
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);
原回答:
在你的问题的底部,你提到了 z-fighting 的快速修复是通过设置一些透明度来简单地关闭这些多边形的 Z 缓冲区。透明度发生在 8 位 Alpha 通道中,所以我最喜欢使用的值是 254.0 / 255.0
或 0.996
.
但是您可能想要关闭另一个选项,那就是 orderIndependentTranslucency
。这是 Scene
的 属性,可以从 Viewer 的构造函数中的选项参数初始化。如果启用,支持它的系统的默认设置,一个人总是可以 "see" 在其他半透明对象后面的半透明对象,无论不透明度如何,当然渲染顺序不会影响结果。但在这种情况下,如果您希望一个多边形遮挡另一个多边形,您希望渲染顺序影响结果。
举个例子。单击底部的 "Run Code Snippet",或仅将 JavaScript 部分粘贴到 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>
它可能对一些不同的情况有用:
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);
答案很简单,您可以在代码中添加z-index
。
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);