天天看點

Cesium Primitive API 實踐:繪制一個三角形

與直接調用官方 API 不同,本例直接使用 Geometry 和 Appearance 類進行構造圖形,靈活度較大。 部落格園 @四季留歌

目錄

1 目的與結果

2 實作原理坐标系統選擇

3 踩坑點

3.1 GeometryAttribute 的構造

3.1.1 position 的構造 - 數值類型

3.1.2 頂點着色器中 attribute 變量的名稱

3.1.3 頂點着色器必須有 batchId attribute

3.2 僅 3D 模式

3.3 Appearance 的 renderState

3.4 Geometry 的 boundingSphere

3.5 Primitive 的異步計算

有如下一個經緯高數組,表示三角形的三個點,逆時針順序:

其在GIS軟體中繪制的形狀如下:

Cesium Primitive API 實踐:繪制一個三角形

最終在 Cesium 的繪制效果如下:

Cesium Primitive API 實踐:繪制一個三角形

使用 Primitive 建立靜态圖形,不依賴官方封裝好的 XXGeometry(最友善的應該是 PolygonGeometry)和 XXAppearance,隻用最基礎的 Geometry 類和 Appearance 類。

Primitive API 建立圖形對象的結構如下:

如果使用 ENU 坐标,則需要計算轉換矩陣,官方已提供了例子。

此處全為經緯高坐标,需要借助 Cesium 數學API 進行世界坐标轉換。

Primitive API 直到傳遞給 WebGL 之前,想要在地球上繪制正确,必須是世界坐标。

使用 <code>Cesium.ComponentDatatype.DOUBLE</code>,values 必須傳遞 <code>Float64Array</code>,否則頂點着色器中比對不到 <code>attribute vec3 position3DHigh</code> 和 <code>attribute vec3 position3DLow</code>。

若改為 <code>Cesium.ComponentDatatype.FLOAT</code>,values 傳遞 <code>Float32Array</code>,會導緻異常。

暫不清楚傳遞 <code>Float32Array</code> 時,頂點着色器的坐标 attribute 應該改成什麼(或許根本不應傳遞 Float32Array)

參考 <code>GeometryAttributes</code> 的文檔,允許的 attribute 有如下幾個:

坐标 position,需為 Float64 的數值,且每個點必須是 xyz 三個次元的

紋理坐标 st,需為 Float32 的數值,且必須是 xy 兩個次元的

頂點顔色 color,需為 Uint8 的數值,且必須是 xyzw 四個次元的

頂點法線 normal,需為 Float32 的數值,且必須是 xyz 三個次元的

(不知道是什麼,應該是切線之類的)bitangent,需為 Float32 的數值,且必須是 xyz 三個次元的

頂點切線向量 tangent,需為 Float32 的數值,且必須是 xyz 三個次元的

在 Primitive.prototype.update 方法運作時,有一個 <code>if (createSP)</code> 分支會調用 <code>createShaderProgram</code> 函數,其内會調用函數 <code>validateShaderMatching</code> 來檢測着色器與 js 對象中 GeometryAttribute 的比對情況。

頂點着色器中的 attribute 變量名,理應與 <code>attributes</code> 中的 key 一樣,除了 position 被分解成了 <code>position3DHigh</code> 和 <code>position3DLow</code>(原因大家應該都知道,就是精度不夠,需要分别編碼)。

否則會報錯。

Cesium Primitive API 實踐:繪制一個三角形

若 new Viewer 時不指定 <code>scene3DOnly</code>,Primitive 的着色器要處理二三維的全部情況,這裡隻關心三維的情況,故要指定僅使用三維模式。

若不指定僅三維模式,且不計算範圍球(見3.4),必報錯。

一個對象,這個 renderState 對象的屬性會在渲染時覆寫預設的 renderState。

depthMask:是否将深度值寫入緩沖區

blending:透明度混合

depthTest:

enabled 深層檢測

具體更多細節見 Renderer/RenderState.js

這裡必須指明的是,即使什麼 renderState 都不給,也要在 new Appearance 時給 renderState 一個空對象:

否則會報錯:

Cesium Primitive API 實踐:繪制一個三角形

若不指定,圖形就不會出現。

coords_world 是世界坐标數組,[x1, y1, z1, x2, y2, z2, ...]

若不計算包圍球且不指定僅三維模式(見3.2),程式将報錯:

Cesium Primitive API 實踐:繪制一個三角形

new Primitive 時,有一個 <code>asynchronous</code> 選項用于指定異步計算生成圖形,要自己寫 <code>WebWorker</code>,在這裡因為沒有寫 <code>WebWorker</code>,是以将其指定為 false 進行同步計算。

若不寫 WebWorker 也不指定其為 false,将報錯:

Cesium Primitive API 實踐:繪制一個三角形

繼續閱讀