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/