Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/javascript
本教程将向您介绍提供使用Primitive API的几何图形和外观系统。这是一个高级主题,用于扩展具备自定义网格、形状、体积和外观的CesiumJS,而不是面向通用的Cesium用户。若是您有兴趣学习如何在地球上绘制各类形状和体积,请查看建立实体教程。 CesiumJS可使用实体(如多边形和椭圆体)建立不一样的几何类型。例如,将如下代码复制并粘贴到Hello World Sandcastle示例中,以在球体上建立具备点模式的矩形:html
var viewer = new Cesium.Viewer('cesiumContainer'); viewer.entities.add({ rectangle : { coordinates : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), material : new Cesium.StripeMaterialProperty({ evenColor: Cesium.Color.WHITE, oddColor: Cesium.Color.BLUE, repeat: 5 }) } });
在本教程中,咱们将深刻到遮光罩下,查看构成它们的几何图形和外观类型。几何图形定义了Primitive结构,即构成基本体的三角形、线或点。外观定义了Primitive的着色,包括其完整的GLSL顶点和面片着色,以及渲染状态。java
使用几何图形和外观的好处是:git
固然也会有一些缺点:github
让咱们使用几何图形和外观重写初始代码示例:canvas
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; // original code //viewer.entities.add({ // rectangle : { // coordinates : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), // material : new Cesium.StripeMaterialProperty({ // evenColor: Cesium.Color.WHITE, // oddColor: Cesium.Color.BLUE, // repeat: 5 // }) // } //}); var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT }) }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : instance, appearance : new Cesium.EllipsoidSurfaceAppearance({ material : Cesium.Material.fromType('Stripe') }) }));
咱们使用Primitive(Primitive)代替矩形实体,它结合了几何图形和外观。如今,咱们将不区分Geometry和GemometryInstance。实例不只是几何图形的实例,更是其的容器。app
为了建立矩形的几何图形,即覆盖矩形区域的三角形和适合球体曲率的三角形,咱们建立了一个RectangleGeometry。dom
由于它在表面上,因此咱们可使用EllipsoidSurfaceAppearance。这经过假设几何图形在曲面上或在椭球体上方的恒定高度来节省内存。ide
CesiumJS提供下列几何图形:性能
当咱们使用一个Primitive绘制多个静态几何图形时,咱们看到了性能优点。例如,在一个Primitive中绘制两个矩形。
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT }) }); var anotherInstance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0), vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT }) }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : [instance, anotherInstance], appearance : new Cesium.EllipsoidSurfaceAppearance({ material : Cesium.Material.fromType('Stripe') }) }));
咱们用不一样的矩形建立了另外一个实例,而后将这两个实例提供给Primitive。这将以相同的外观绘制两个实例。
有些外观容许每一个实例提供惟一的属性。例如,咱们可使用PerinstanceColorAppearance对每一个实例使用不一样的颜色进行着色。
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 0.8) } }); var anotherInstance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0), vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8) } }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : [instance, anotherInstance], appearance : new Cesium.PerInstanceColorAppearance() }));
每一个实例都有一个颜色属性。Primitive是用PerinstanceColorAppearance构造的,它使用每一个实例的颜色属性来肯定着色。
组合几何图形可使CesiumJS有效地绘制许多几何图形。下面的示例绘制2592个颜色独特的矩形。
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var instances = []; for (var lon = -180.0; lon < 180.0; lon += 5.0) { for (var lat = -85.0; lat < 85.0; lat += 5.0) { instances.push(new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(lon, lat, lon + 5.0, lat + 5.0), vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 0.5})) } })); } } scene.primitives.add(new Cesium.Primitive({ geometryInstances : instances, appearance : new Cesium.PerInstanceColorAppearance() }));
实例合并后能够独立访问。为实例分配一个ID,并使用它来肯定是否使用Scene.Pick拾取该实例。
下面的示例建立一个带id的实例,并在单击该实例时将消息写入控制台。
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var instance = new Cesium.GeometryInstance({ geometry : new Cesium.RectangleGeometry({ rectangle : Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0), vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), id : 'my rectangle', attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED) } }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : instance, appearance : new Cesium.PerInstanceColorAppearance() })); var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); handler.setInputAction(function (movement) { var pick = scene.pick(movement.position); if (Cesium.defined(pick) && (pick.id === 'my rectangle')) { console.log('Mouse clicked rectangle.'); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
使用id避免了在内存中,在Primitive构造以后,对整个实例的引用,包括几何图形。
实例可用于在场景的不一样部分定位、缩放和旋转相同的几何体。这是可能的,由于多个实例能够引用相同的Geometry,而且每一个实例能够具备不一样的modelMatrix。这容许咱们只计算一次几何图形,并屡次重复使用它。
如下示例建立一个EllipsoidGeometry和两个实例。每一个实例引用相同的椭球几何体,但使用不一样的modelMatrix放置它,致使一个椭球位于另外一个椭球之上。
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var ellipsoidGeometry = new Cesium.EllipsoidGeometry({ vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, radii : new Cesium.Cartesian3(300000.0, 200000.0, 150000.0) }); var cyanEllipsoidInstance = new Cesium.GeometryInstance({ geometry : ellipsoidGeometry, modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 150000.0), new Cesium.Matrix4() ), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CYAN) } }); var orangeEllipsoidInstance = new Cesium.GeometryInstance({ geometry : ellipsoidGeometry, modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)), new Cesium.Cartesian3(0.0, 0.0, 450000.0), new Cesium.Matrix4() ), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE) } }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance], appearance : new Cesium.PerInstanceColorAppearance({ translucent : false, closed : true }) }));
将几何图形添加到Primitive后,更新几何图形的每一个实例属性以更改可视化效果。每一个实例的属性包括:
下列展现了如何改变几何实例的颜色:
var viewer = new Cesium.Viewer('cesiumContainer'); var scene = viewer.scene; var circleInstance = new Cesium.GeometryInstance({ geometry : new Cesium.CircleGeometry({ center : Cesium.Cartesian3.fromDegrees(-95.0, 43.0), radius : 250000.0, vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) }, id: 'circle' }); var primitive = new Cesium.Primitive({ geometryInstances : circleInstance, appearance : new Cesium.PerInstanceColorAppearance({ translucent : false, closed : true }) }); scene.primitives.add(primitive); setInterval(function() { var attributes = primitive.getGeometryInstanceAttributes('circle'); attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0})); },2000);
几何图形实例的属性能够被primitive使用primitive.getGeometryInstanceAttributes检索。attirbutes的属性能够直接被改变。
几何定义结构。primitive的另外一个关键属性,appearance,定义了primitive的纹理,即单个像素的颜色。primitive能够有多个几何实例,但只能有一个外观。根据外观的类型,外观将具备定义着色的主体的material。
CesiumJS具备下列外观:
外观定义了绘制Primitive时在GPU上执行的完整GLSL顶点和面片着色器。外观还定义了完整的渲染状态,它控制绘制primitvie时GPU的状态。咱们能够直接定义渲染状态,也可使用更高级的属性,如“闭合(closed)”和“半透明(translucent)”,外观将转换为渲染状态。例如:
// Perhaps for an opaque box that the viewer will not enter. // - Backface culled and depth tested. No blending. var appearance = new Cesium.PerInstanceColorAppearance({ translucent : false, closed : true }); // This appearance is the same as above var anotherAppearance = new Cesium.PerInstanceColorAppearance({ renderState : { depthTest : { enabled : true }, cull : { enabled : true, face : Cesium.CullFace.BACK } } });
建立外观后,不能更改其renderState属性,但能够更改其material。咱们还能够更改primitive的appearnace属性。
大多数外观还具备flat和faceForward属性,这些属性间接控制GLSL着色器。
并不是全部外观都适用于全部几何图形。例如,EllipsoidSurfaceAppearance外观不适用于WallGeometry几何图形,由于墙不在球体的表面上。
要使外观与几何图形兼容,它们必须具备匹配的顶点格式,这意味着几何图形必须具备外观所期待的输入数据。建立几何图形时能够提供vertexFormat。
几何图形的vertexFormat肯定它是否能够与其余几何图形组合。两个几何图形没必要是相同的类型,但它们须要匹配的顶点格式。
为方便起见,外观要么具备vertexFormat属性,要么具备可做为几何体选项传入的VERTEX_FORMAT静态常量。
var geometry = new Ceisum.RectangleGeometry({ vertexFormat : Ceisum.EllipsoidSurfaceAppearance.VERTEX_FORMAT // ... }); var geometry2 = new Ceisum.RectangleGeometry({ vertexFormat : Ceisum.PerInstanceColorAppearance.VERTEX_FORMAT // ... }); var appearance = new Ceisum.MaterialAppearance(/* ... */); var geometry3 = new Ceisum.RectangleGeometry({ vertexFormat : appearance.vertexFormat // ... });
参考文档:
更多材料请访问:Fabric 更多将来计划,请访问:Geometry and Appearances Roadmap
Cesium中文网交流QQ群:807482793 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/