1. 程式人生 > >cesium primitive方式 ————http://blog.sina.com.cn/s/blog_15e866bbe0102y0ji.html

cesium primitive方式 ————http://blog.sina.com.cn/s/blog_15e866bbe0102y0ji.html

Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點

  (2018-08-28 16:12:06) 轉載
標籤: 

cesium

 

primitive

 

自定義渲染

 

shader

 

cesium自定義畫點

分類: cesium
今天我們來學習下cesium最重要一個物件--primitive,在之前基礎系列中,我們已經接觸過primitive,但是接觸的都是primitive為我們封裝好的介面,我們今天來學習下primitive更深層次的api。我們有時候繪製物件時,需要自己靈活控制渲染物件的頂點和顏色(紋理),雖然cesium已經給我們提供了很多現成的基礎圖元,但還是不夠靈活,今天我們就從三維基礎繪製原理來學習下在cesium中,如何繪製基本圖元:點、線、三角面片以及紋理貼圖。如果你熟悉三維渲染底層,那麼對點、線、三角面片、紋理這些概念一定非常瞭解,應為它們是組成三維渲染物件的基礎。任何三維物件幾何屬性都是由複雜的點、線、三角面片這三種基本型別組成,然後加上紋理貼圖就有了逼真的外觀。那麼今天我們就先來了解下如何用primitive介面繪製自定義點。在這裡我要感謝我的好朋友
MikesWei
,在我學習cesium過程中給予無私地幫助。 首先我們看primitive的官方api: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
可以看到,primitive兩個重要物件:geometry和appearance。 檢視geometry: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
這裡的PrimitiveType就是指定該幾何物件圖元型別是那種,一共有以下幾種: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
每個型別具體含義,大家可以自己翻譯便知。本節我們學習如何繪製點,所以我們使用POINTS物件。 然後我們來看appearance: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
這裡我們需要關注圖中標出的三個屬性: material:設定材質 vertexShaderSource:設定頂點著色器程式碼 fragmentShaderSource:設定片源著色器程式碼。 頂點著色器和片源著色器都是使用GLSL語言編寫,接觸webgl的童鞋對此一定非常瞭解,我對此還沒入門,無法說出個所以然來。 知道繪製primitive的要點後,下面就是具體實現,直接上程式碼: var PrimitivePoints=(     function () {         var vertexShader;         var fragmentShader;         var geometry;         var appearance;         var viewer;         function _(options) {             viewer = options.viewer;             vertexShader = getVS();             fragmentShader = getFS();             if (options.Cartesians && options.Cartesians.length >= 2) {                 var postionsTemp = [];                 var colorsTemp = [];                 var indicesTesm = [];                 if (options.Colors && options.Colors.length === options.Cartesians.length * 4) {                     for (var i = 0; i < options.Cartesians.length; i++) {                         postionsTemp.push(options.Cartesians[i].x);                         postionsTemp.push(options.Cartesians[i].y);                         postionsTemp.push(options.Cartesians[i].z);                     }                     colorsTemp = options.Colors;                 } else {                     for (var i = 0; i < options.Cartesians.length; i++) {                         postionsTemp.push(options.Cartesians[i].x);                         postionsTemp.push(options.Cartesians[i].y);                         postionsTemp.push(options.Cartesians[i].z);                         //                         colorsTemp.push(0.0);                         colorsTemp.push(0.0);                         colorsTemp.push(1.0);                         colorsTemp.push(1.0);                     }                 }                 for (var i = 0; i < options.Cartesians.length; i++) {                     indicesTesm.push(i);                 }                 this.positionArr = new Float64Array(postionsTemp);                 this.colorArr = new Float32Array(colorsTemp);                 this.indiceArr = new Uint16Array(indicesTesm);               } else {                 var p1 = Cesium.Cartesian3.fromDegrees(0, 0, -10);                 var p2 = Cesium.Cartesian3.fromDegrees(0, 0.001, -10);                 this.positionArr = new Float64Array([                     p1.x, p1.y, p1.z,                     p2.x, p2.y, p2.z                 ]);                 this.colorArr = new Float32Array([                          0.0, 0.0, 1.0, 1.0,                          0.0, 0.0, 1.0, 1.0                 ]);                 this.indiceArr = new Uint16Array([0, 1]);             }                         geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);             appearance = CreateAppearence(fragmentShader, vertexShader);               this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({                 geometryInstances: new Cesium.GeometryInstance({                     geometry: geometry                 }),                 appearance: appearance,                 asynchronous: false             }));         }           function CreateGeometry(positions, colors, indices) {             return new Cesium.Geometry({                 attributes: {                     position: new Cesium.GeometryAttribute({                         componentDatatype: Cesium.ComponentDatatype.DOUBLE,                         componentsPerAttribute: 3,                         values: positions                     }),                     color: new Cesium.GeometryAttribute({                         componentDatatype: Cesium.ComponentDatatype.FLOAT,                         componentsPerAttribute: 4,                         values: colors                     })                 },                 indices: indices,                 primitiveType: Cesium.PrimitiveType.POINTS,                 boundingSphere: Cesium.BoundingSphere.fromVertices(positions)             });         }           function CreateAppearence(fs, vs) {             return new Cesium.Appearance({                         renderState: {                     blending: Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,                      depthTest: { enabled: true },                      depthMask: true                 },                 fragmentShaderSource: fs,                 vertexShaderSource: vs             });         }           function getVS() {             return "attribute vec3 position3DHigh;\             attribute vec3 position3DLow;\             attribute vec4 color;\             varying vec4 v_color;\             attribute float batchId;\             void main()\             {\                 vec4 p = czm_computePosition();\                 v_color =color;\                 p = czm_modelViewProjectionRelativeToEye * p;\                 gl_Position = p;\                 gl_PointSize=8.0;\             }\             ";         }         function getFS() {             return "varying vec4 v_color;\             void main()\             {\                  float d = distance(gl_PointCoord, vec2(0.5,0.5));\                  if(d < 0.5){\                     gl_FragColor = v_color;\                  }else{\                     discard;\                  }\             }\             ";         }                 _.prototype.remove = function () {             if (this.primitive != null) {                 viewer.scene.primitives.remove(this.primitive);                 this.primitive = null;             }         }         _.prototype.updateCartesianPosition = function (cartesians) {             if (this.primitive != null) {                 viewer.scene.primitives.remove(this.primitive);                 if (cartesians && cartesians.length < 2) { return; }                              var postionsTemp = [];                 var colorsTemp = [];                 var indicesTesm = [];                 for (var i = 0; i < cartesians.length; i++) {                     postionsTemp.push(cartesians[i].x);                     postionsTemp.push(cartesians[i].y);                     postionsTemp.push(cartesians[i].z);                                           colorsTemp.push(0.0);                     colorsTemp.push(0.0);                     colorsTemp.push(1.0);                     colorsTemp.push(1.0);                 }                 for (var i = 0; i < cartesians.length; i++) {                     indicesTesm.push(i);                 }                 this.positionArr = new Float64Array(postionsTemp);                 this.colorArr = new Float32Array(colorsTemp);                 this.indiceArr = new Uint16Array(indicesTesm);                   geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);                 appearance = CreateAppearence(fragmentShader, vertexShader);                   this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({                     geometryInstances: new Cesium.GeometryInstance({                         geometry: geometry                     }),                     appearance: appearance,                     asynchronous: false                 }));             } else { return;}         }         _.prototype.updateCartesianPositionColor = function (cartesians, colors) {             if (colors.length === cartesians.length * 4) { } else { return; }             if (this.primitive != null) {                 viewer.scene.primitives.remove(this.primitive);                 if (cartesians && cartesians.length < 2) { return; }                                  var postionsTemp = [];                 var indicesTesm = [];                                  for (var i = 0; i < cartesians.length; i++) {                     postionsTemp.push(cartesians[i].x);                     postionsTemp.push(cartesians[i].y);                     postionsTemp.push(cartesians[i].z);                 }                 for (var i = 0; i < cartesians.length; i++) {                     indicesTesm.push(i);                 }                 this.positionArr = new Float64Array(postionsTemp);                 this.colorArr = new Float32Array(colors);                 this.indiceArr = new Uint16Array(indicesTesm);                   geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);                 appearance = CreateAppearence(fragmentShader, vertexShader);                                  this.primitive = viewer.scene.primitives.add(new Cesium.Primitive({                     geometryInstances: new Cesium.GeometryInstance({                         geometry: geometry                     }),                     appearance: appearance,                     asynchronous: false                 }));             } else { return; }         }         return _;     })(); 程式碼中我們定義了PrimitivePoints自定義渲染點類,可以繪製任意多個點,並且改變點的位置和顏色。 其中定義geometry程式碼:
Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點

在attributes中指定位置和顏色,primitiveType指定為POINTS。特別注意位置和顏色傳入的資料型別。 定義appearance程式碼: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
關聯頂點著色器和片源著色器,關於renderState設定,我們暫不涉及。 頂點著色器程式碼: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
片源著色器程式碼: Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
示例執行效果(紅藍間隔點): Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
更新(實際是刪除後再新建): Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點