shader之cesium應用
shader用作編寫cesium自定義材質的着色器。
效果:

代碼:
<template> <div class="earthSence"> <!-- 地圖 --> <div id="earthContainer"></div> </div> </template> <script> import { mapUrl } from '@/config' export default { name: 'flyline', data() { return { _earth: {}, _viewer: {} } }, mounted() { XE.ready().then(() => { this.initMap() }) }, methods: { // 初始化earthSDK地圖 initMap() { //創建viewer實例 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2N2UwZWU2Zi1jN2UzLTQ3YTAtOTZmNC05MzNkM2IxZDViMzgiLCJpZCI6MjY1MzgsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODc5MDQ0NTF9.lLpxvsIwB9Se5GeINW-jp5nm406S7KVWMdvH8swDHQ4' this.viewer = new Cesium.Viewer('earthContainer', { geocoder: false, // 隱藏搜索 homeButton: false, // 隱藏主頁 sceneModePicker: false, // 隱藏二三維轉換 baseLayerPicker: false, // 隱藏圖層選擇控件 navigationHelpButton: false, // 隱藏幫助按鈕 animation: false, // 隱藏時鍾 timeline: false, // 隱藏時間軸 fullscreenButton: false, // 隱藏全屏 vrButton: false, // 隱藏雙屏模式 infoBox: false, // 隱藏點擊 entity 信息框 selectionIndicator: false, // 隱藏點擊 entity 綠框 shouldAnimate: true, // 設置底圖 imageryProvider: new Cesium.UrlTemplateImageryProvider({ url:mapUrl, style: 'default', format: 'image/png' }) }) // 定位到全國 // 中國坐標 let chinaPosition = Cesium.Cartesian3.fromDegrees( 113.41726298378288, 10.290411251106182, 700000.0 ) this.viewer.camera.flyTo({ destination: chinaPosition, orientation : { heading : Cesium.Math.toRadians(0.0), pitch : Cesium.Math.toRadians(-25.0), roll : 0.0 }, duration: 1, // 飛行時間 offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(-20.0)) // 偏移量 }) this.addCube() }, // 創建柱狀體並賦予shader着色器材質 addCube() { var viewer = this.viewer // 創建長方體對象 const extrudedPolygon = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArray([ 112.41726298378288, 23.290411251106182, 113.67072522399741, 23.560312361463682, 114.09370956893551, 22.590768298743153, 112.83803246418894, 22.285610818885644, ]) ), extrudedHeight: 100000, }) const instance = new Cesium.GeometryInstance({ geometry: extrudedPolygon, id: 'box with height', }) const extrudedPolygon2 = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArray([ 114, 22, 115, 22, 115, 23, 114, 23, ]) ), extrudedHeight: 100000, }) const instance2 = new Cesium.GeometryInstance({ geometry: extrudedPolygon2, id: 'box with height', }) // 創建材質,在MaterialAppearance中若不添加基礎材質,模型將會透明 var material = new Cesium.Material.fromType("Color"); material.uniforms.color = Cesium.Color.WHITE; // 自定義材質 const aper = new Cesium.MaterialAppearance({ material: material, translucent: true, closed: true, vertexShaderSource: ` attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec2 st; attribute float batchId; varying vec3 vNormal; void main() { //將attributes的normal通過varying賦值給了向量vNormal vNormal = normal; //projectionMatrix是投影變換矩陣 modelViewMatrix是相機坐標系的變換矩陣 vec4 p = czm_computePosition(); gl_Position = czm_modelViewProjectionRelativeToEye * p; } `, fragmentShaderSource: ` //片元着色器同樣需要定義varying vec3 vNormal; varying vec3 vNormal; void main() { //vNormal是一個已經歸一化的三維向量 float pr = (vNormal.x + 1.0) / 2.0; //pr紅色通道值范圍為0~1 float pg = (vNormal.y + 1.0) / 2.0; //pg綠色通道值范圍為0~1 float pb = (vNormal.z + 1.0) / 2.0; //pb藍色通道值范圍為0~1 gl_FragColor=vec4(pr, pg, pb, 1.0); //最后設置頂點顏色,點與點之間會自動插值 } `, }) // 加載模型 var p = viewer.scene.primitives.add( new Cesium.Primitive({ geometryInstances: [instance, instance2], appearance: aper, releaseGeometryInstances: false, compressVertices: false, }) ) }, } } </script> <style scoped lang="scss"> .earthSence { width: 100%; height: 100%; background: grey; overflow: hidden; position: relative; #earthContainer { width: 100%; height: 100%; overflow: hidden; position: absolute; } } </style>
合作:@浩
鑽研不易,轉載請注明出處。。。。。。
