shader之cesium应用
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>
合作:@浩
钻研不易,转载请注明出处。。。。。。