cesium primitive方式 ————http://blog.sina.com.cn/s/blog_15e866bbe0102y0ji.html
阿新 • • 發佈:2018-11-11
Cesium學習筆記-工具篇17-PrimitivePoint自定義渲染-點
(2018-08-28 16:12:06) 轉載▼標籤: cesiumprimitive自定義渲染shadercesium自定義畫點 |
分類: cesium |
可以看到,primitive兩個重要物件:geometry和appearance。 檢視geometry:
這裡的PrimitiveType就是指定該幾何物件圖元型別是那種,一共有以下幾種:
每個型別具體含義,大家可以自己翻譯便知。本節我們學習如何繪製點,所以我們使用POINTS物件。 然後我們來看appearance:
這裡我們需要關注圖中標出的三個屬性: 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程式碼:
在attributes中指定位置和顏色,primitiveType指定為POINTS。特別注意位置和顏色傳入的資料型別。 定義appearance程式碼:
關聯頂點著色器和片源著色器,關於renderState設定,我們暫不涉及。 頂點著色器程式碼:
片源著色器程式碼:
示例執行效果(紅藍間隔點):
更新(實際是刪除後再新建):