1. 程式人生 > >Cesium學習筆記(六):幾何和外觀(Geometry and Appearances)

Cesium學習筆記(六):幾何和外觀(Geometry and Appearances)

我們先直接來看一個例子

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

var flag = 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 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 }) }); scene.primitives.add(new Cesium.Primitive({ geometryInstances : instance, //使用系統自帶的條紋樣式 appearance : new Cesium.EllipsoidSurfaceAppearance({ material : Cesium.Material.fromType('Stripe') }) }));

這樣的寫法自然是有優點也有缺點的

優點:

  • 效能 - 當繪製大量靜態圖元時,直接使用幾何形狀可以將它們組合成單個幾何體,以減少CPU開銷並更好地利用GPU。並且組合是在網路上完成的,可以保持UI的響應。
  • 靈活性 - 基元組合幾何和外觀。通過解耦,我們可以獨立地修改。我們可以新增與許多不同外觀相容的新幾何體,反之亦然。
  • 低階訪問 - 外觀提供了接近於渲染器的訪問,可以直接使用渲染器的所有細節(Appearances provide close-to-the-metal access to rendering without having to worry about all the details of using the Renderer directly)。外觀使其易於:
    • 編寫完整的GLSL頂點和片段著色器。
    • 使用自定義渲染狀態。

缺點:

  • 程式碼量增大,並且需要使用者對這方面有更深入的理解。
  • 組合幾何可以使用靜態資料,不一定是動態資料。
  • primitives 的抽象級別適合於對映應用程式;幾何圖形和外觀的抽象層次接近傳統的3D引擎(Primitives are at the level of abstraction appropriate for mapping apps; geometries and appearances have a level of abstraction closer to a traditional 3D engine)(感覺翻譯的不太好的地方都給上了原文)

我們可以用一個primitives畫出多個幾何圖形,這樣可以明顯能看出效能上的優勢

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')
  })
}));

這裡寫圖片描述

對於不同的圖形,我們可以單獨給它們設定屬性,這裡,我們使用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()
}));

這裡寫圖片描述

可能這樣大家還感覺不出來效能上的優勢,那我們可以這樣

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()
}));

這裡畫了2592個不同顏色的矩形,而且速度非常快,這就更明顯的看出primitives在效能上的優勢了

這裡寫圖片描述

雖然我們是通過一個primitives來建立的,但是我們可以給每一個幾何圖形一個id,這樣我們就可以單獨訪問他們了、

var instance = new Cesium.GeometryInstance({
    id : "blue rectangle",
    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({
    id : "red rectangle",
    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()
}));
//獲取螢幕事件管理器
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
//監聽螢幕輸入事件(這裡是監聽左鍵點選事件)
handler.setInputAction(function (movement) {
    var pick = scene.pick(movement.position);
    if (Cesium.defined(pick) ) {
        switch (pick.id)
        {
            case 'blue rectangle':
                console.log('Mouse clicked blue rectangle.');
                break;
            case 'red rectangle':
                console.log('Mouse clicked red rectangle.');
                break;
        }
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

然後我點選兩個矩形,控制檯就輸出了相應的log

這裡寫圖片描述

當只要改變屬性,不需要改變幾何形狀時候還可以把幾何圖形的建立給提出來

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
    })
}));

這裡寫圖片描述

在建立完之後,我們依舊可以動態的修改模型的屬性,當然,這需要給模型加上一個id

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({
    id : 'cyan',
    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({
    id : 'orange',
    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)
    }
});

var primitive = scene.primitives.add(new Cesium.Primitive({
    geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance],
    appearance : new Cesium.PerInstanceColorAppearance({
        //不透明
        translucent : false,
        closed : true
    })
}));

setInterval(function() {
    var attributes1 = primitive.getGeometryInstanceAttributes('cyan');
    attributes1.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));
    var attributes2 = primitive.getGeometryInstanceAttributes('orange');
    attributes2.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));
},1000);

這裡寫圖片描述

下面列舉下cesium中的幾何圖形和外觀,要注意的是有些外觀和幾何是不相容的

幾何圖形 描述
BoxGeometry 盒子
BoxOutlineGeometry 只有外部線條的的盒子
CircleGeometry 圓圈或擠壓圓
CircleOutlineGeometry 同上(只有線條的圓,後面我就省略了)
CorridorGeometry 垂直於表面的折線,寬度以米為單位,可選擇擠壓高度
CorridorOutlineGeometry
CylinderGeometry 圓柱體,圓錐體或截錐體
CylinderOutlineGeometry
EllipseGeometry 橢圓或擠出橢圓
EllipseOutlineGeometry
EllipsoidGeometry 橢圓形
EllipsoidOutlineGeometry
RectangleGeometry 矩形或擠壓矩形
RectangleOutlineGeometry
PolygonGeometry 具有可選孔或擠出多邊形的多邊形
PolygonOutlineGeometry
PolylineGeometry 一組寬度為畫素的線段
SimplePolylineGeometry
PolylineVolumeGeometry 沿著折線擠壓的2D形狀
PolylineVolumeOutlineGeometry
SphereGeometry 一個球體
SphereOutlineGeometry
WallGeometry 垂直於地球的牆壁
WallOutlineGeometry
外觀 描述
MaterialAppearance 外觀與所有幾何型別一起使用,並支援材料描述陰影。
EllipsoidSurfaceAppearance 幾何像幾何平行於地球表面的“Material Appearance”一樣,就像一個多邊形,並且使用這個假設來通過程式上計算許多頂點屬性來節省記憶體。
PerInstanceColorAppearance 使用每個例項的顏色來遮蔽每個例項。
PolylineMaterialAppearance 支援材料遮蔽Polyline。
PolylineColorAppearance 使用每頂點或每段著色來遮蔽折線。

參考資料:官方文件

相關推薦

Cesium學習筆記幾何外觀(Geometry and Appearances)

我們先直接來看一個例子 var viewer = new Cesium.Viewer('cesiumContainer'); var flag = viewer.entities.add({ rectangle : { coord

Python學習筆記列表字典

以Mark Lutz著的《Python學習手冊》為教程,每天花1個小時左右時間學習,爭取兩週完成。 --- 寫在前面的話 2013-7-18 19:00 學習筆記 1,Python中的列表是任意物件的有序集合,而且是可變的。在標準的Python直譯器內部,列表是C陣列,不

Unity3D之Mecanim動畫系統學習筆記使用腳本控制動畫

ont nim 復制代碼 info rip esc enter machine images 控制人物動畫播放 這裏我重新弄了一個簡單的場景和新的Animator Controller來作為示例。 下面先看看Animator Controller的配置: 人物在站

.net core 2.0學習筆記Remoting核心類庫RealProxy遷移

ride dispatch 包含 void reflect 既然 splay creat (六) 在學習.net core的過程中,我們已經明確被告知,Remoting將不會被支持。官方的解釋是,.net framework 類型包含了太多的Runtime的內容,是

java學習筆記變量類型

animal 單獨使用 div 位置 fin strong pub 局部變量 變量聲明 java一共三種變量: 局部變量(本地變量):方法調用時創建,方法結束時銷毀 實例變量(全局變量):類創建時創建,類銷毀時銷毀 類變量(靜態變量):程序啟動是創建,程序銷毀時銷毀

javaweb學習筆記HTML

目錄 1.HTML相關概念 2.主要標籤 2.1頭資訊 2.2文字標籤 2.3字元實體 2.4媒體標籤 2.5連結標籤 2.6影象標籤   2.7表格標籤 2.8框架標籤 2.9表單標籤 1.HTML相關概念 軟體的結構:

學習筆記使用隨機森林演算法檢測FTP暴力破解

1.資料蒐集:         載入ADFA-LD中正常資料         定義遍歷目錄下檔案         從攻擊資料中篩選出和FTP暴力破解有關的資料 &n

機器學習筆記KNN分類器

1 KNN演算法 1.1 KNN演算法簡介 KNN(K-Nearest Neighbor)工作原理:存在一個樣本資料集合,也稱為訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類對應的關係。輸入沒有標籤的資料後,將新資料中的每個特徵與樣本集中資料對應的特

Scala學習筆記本地函式、頭等函式、佔位符部分應用函式

本地函式 可以在方法內定義方法,這種方法叫本地函式,本地函式可以直接訪問父函式的引數 def parent(x: Int, y: Int): Unit ={ def child(y:Int) = y + 1 val z = child(y) println(s"x: $x, z

圖解演算法學習筆記廣度優先搜尋

本章內容;        學習使用新的資料結構圖來建立網路模型;        學習廣度優先搜尋;        學習有向圖和無向圖;        學習拓撲排序,這種排序演算法指出了節點之間的依賴關係。 1)圖簡介 假設你住在舊金山,要從雙子峰前往金門大橋。你想乘

機器學習筆記貝葉斯分類器

機器學習所研究的主要內容,是關於在計算機上從資料中產生“模型”的演算法,這個產生的模型大體上可以分為“判別式模型”和“生成式模型”兩大類。 其中判別式模型是給定x,通過直接對條件概率分佈P(y|x)進行建模來預測y。這種方法尋找不同類別的最優分類面,反映的是異類資料之間的差異。之前幾篇文章中介紹

各種音視訊編解碼學習詳解之 編解碼學習筆記H.26x系列

    最近在研究音視訊編解碼這一塊兒,看到@bitbit大神寫的【各種音視訊編解碼學習詳解】這篇文章,非常感謝,佩服的五體投地。奈何大神這邊文章太長,在這裡我把它分解成很多小的篇幅,方便閱讀。大神部落格傳送門:https://www.cnblogs.com/skyofbitbi

Cesium學習筆記新增實體物件

1. 首先,你需要選擇一款程式碼編輯器,可以選擇eclipse,webstorm,visual studio code這種比較大型的帶有程式碼提示的,你也可以選擇sublime,nodepad++,atom這種沒有提示的,但是不能使用word這種自帶格式的,這樣

SpringBoot學習筆記SpringBoot實現Shiro登入控制許可權控制

登入模組:在登入時必須呼叫 授權模組:不是一登入就調動,而是當角色許可權控制時才會呼叫 登入控制 環境搭建在上一篇。 資料庫表 表名:role 欄位:id rolename 表名:user 欄位:id username sex roleid 在程式碼中簡歷資料庫表對應的實

Cesium學習筆記Demo學習(差值器)

這個Demo是官方Demo中的Interpolation(差值器),不過我更喜歡叫它轉圈的飛機o( ̄ε ̄*) 這個Demo看上去就是一個飛機在繞著一個圈在飛,你可以通過切換差值器看效果 話說這個Demo困擾了我好久,我一直以為這個飛機飛行是自己畫出來

Cesium學習筆記環境配置首次執行

Cesium是國外一個基於JavaScript編寫的使用WebGL的地圖引擎。Cesium支援3D,2D,2.5D形式的地圖展示,可以自行繪製圖形,高亮區域,並提供良好的觸控支援,且支援絕大多數的瀏覽器和mobile。 這是官網上給出的例子,如果你可以成功執行

OpenCVPython學習筆記One幾何變換之對影象的旋轉

 最近學習中會用到OpenCV,感覺OpenCV簡單且功能強大,Python語言也簡單易用,於是就學了Python版OpenCV。裡面講的比較簡單,就先從簡單的入手吧。 因為已經學習一段時間了,所以文章並不是按照OpenCV的順序來寫的,我會慢慢補齊以前學過的一些例子。 都是些簡單

Cesium學習筆記Demo學習自由控制飛行的飛機[轉]

https://blog.csdn.net/umgsoil/article/details/74923013# 這是官方的教程Demo,名字叫Use HeadingPitchRoll,顧名思義,就是教你用HeadingPitchRoll這個方法的,下面我們就來看一看這個Demo首先先說一下,這個Demo是沙

Python3《機器學習實戰》學習筆記Logistic迴歸基礎篇之梯度上升演算法

一 前言 本文從Logistic迴歸的原理開始講起,補充了書上省略的數學推導。本文可能會略顯枯燥,理論居多,Sklearn實戰內容會放在下一篇文章。自己慢慢推導完公式,還是蠻開心的一件事。 二 Logistic迴歸與梯度上升演算法 Logistic迴歸是眾

Cesium學習筆記Demo學習自由控制飛行的飛機

這是官方的教程Demo,名字叫Use HeadingPitchRoll,顧名思義,就是教你用HeadingPitchRoll這個方法的,下面我們就來看一看這個Demo 首先先說一下,這個Demo是沙盒裡面的,所以如果你想在本地執行的話需要改一下html