当前位置: 首页 > news >正文

cesium 发光线

发光线也是一种比较常见的可视化效果,cesium 内置的材质已经提供了PolylineGlowMaterialProperty类,实现了发光效果。这种材质在线的中间部分始终会有白色线条,如果想实现纯色的发光线,就需要对这种材质进行改造。本篇通过自定义MaterialProperty提供两种发光线材质。

1. 自定义GlowLineMaterialProperty类

1.1. 自定义 GlowLineMaterialProperty 类
/** @Description: * @Author: maizi* @Date: 2024-08-16 15:06:46* @LastEditTime: 2024-08-27 17:10:15* @LastEditors: maizi*/function GlowLineMaterialProperty(options) {options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);this._definitionChanged = new Cesium.Event();this._color = undefined;this._power = undefined;this.color = options.color || Cesium.Color.fromBytes(0, 255, 255, 255);this.power = options.power || 0.25;
}Object.defineProperties(GlowLineMaterialProperty.prototype, {isConstant: {get: function () {return (Cesium.Property.isConstant(this._color) && Cesium.Property.isConstant(this._power));},},definitionChanged: {get: function () {return this._definitionChanged;},},color: Cesium.createPropertyDescriptor("color"),power: Cesium.createPropertyDescriptor("power")
});GlowLineMaterialProperty.prototype.getType = function (time) {return "GlowLine";
};GlowLineMaterialProperty.prototype.getValue = function (time, result) {if (!Cesium.defined(result)) {result = {};}result.color = Cesium.Property.getValueOrClonedDefault(this._color, time);result.power = Cesium.Property.getValueOrClonedDefault(this._power, time);return result;
};GlowLineMaterialProperty.prototype.equals = function (other) {const res = this === other || (other instanceof GlowLineMaterialProperty &&Cesium.Property.equals(this._color, other._color) &&Cesium.Property.equals(this._power, other._power))return res;
};
export default GlowLineMaterialProperty;
1.2. 材质shader
uniform vec4 color;
uniform float power;czm_material czm_getMaterial(czm_materialInput materialInput)
{ czm_material material = czm_getDefaultMaterial(materialInput);vec2 st = materialInput.st;float glow = power / abs(st.t - 0.5) - (power / 0.5);material.alpha = clamp(0.0, 1.0, glow);material.diffuse = color.rgb;return material;
}
1.3. 添加到缓存
/** @Description: * @Author: maizi* @Date: 2024-08-16 16:21:55* @LastEditTime: 2024-08-26 18:00:42* @LastEditors: maizi*/
import GlowLinetMaterial from '../shader/GlowLinetMaterial.glsl'Cesium.Material.GlowLine = 'GlowLine'
Cesium.Material._materialCache.addMaterial(Cesium.Material.GlowLine,{fabric: {type: Cesium.Material.GlowLine,uniforms: {color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),power: 0.25},source: GlowLinetMaterial,},translucent: function (material) {return true},}
)

2. 自定义ImageGlowLineMaterialProperty类

2.1. 自定义ImageGlowLineMaterialProperty类
/** @Description: * @Author: maizi* @Date: 2024-08-16 15:06:46* @LastEditTime: 2024-08-27 17:17:09* @LastEditors: maizi*/function ImageGlowLineMaterialProperty(options) {options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);this._definitionChanged = new Cesium.Event();this._color = undefined;this._image = undefined;this.color = options.color || Cesium.Color.fromBytes(0, 255, 255, 255);this.image = options.image;
}Object.defineProperties(ImageGlowLineMaterialProperty.prototype, {isConstant: {get: function () {return (Cesium.Property.isConstant(this._color) && Cesium.Property.isConstant(this._image));},},definitionChanged: {get: function () {return this._definitionChanged;},},color: Cesium.createPropertyDescriptor("color"),image: Cesium.createPropertyDescriptor("image")
});ImageGlowLineMaterialProperty.prototype.getType = function (time) {return "ImageGlowLine";
};ImageGlowLineMaterialProperty.prototype.getValue = function (time, result) {if (!Cesium.defined(result)) {result = {};}result.color = Cesium.Property.getValueOrClonedDefault(this._color, time);result.image = Cesium.Property.getValueOrClonedDefault(this._image, time);return result;
};ImageGlowLineMaterialProperty.prototype.equals = function (other) {const res = this === other || (other instanceof ImageGlowLineMaterialProperty &&Cesium.Property.equals(this._color, other._color) &&Cesium.Property.equals(this._image, other._image))return res;
};
export default ImageGlowLineMaterialProperty;
2.2. 材质shader
uniform sampler2D image;
uniform vec4 color;czm_material czm_getMaterial(czm_materialInput materialInput){czm_material material = czm_getDefaultMaterial(materialInput);vec2 st = materialInput.st;vec4 colorImage = texture(image,st);vec3 fragColor = color.rgb;material.alpha = colorImage.a * color.a * 3.;// 设置中间发光图片的颜色占比if(st.t < 0.55 && st.t > 0.45) {material.diffuse = colorImage.rgb;} else {material.diffuse = fragColor.rgb;}return material;
}
2.3. 添加到缓存
/** @Description: * @Author: maizi* @Date: 2024-08-16 16:21:55* @LastEditTime: 2024-08-26 18:00:42* @LastEditors: maizi*/
import ImageGlowLinetMaterial from '../shader/ImageGlowLinetMaterial.glsl'Cesium.Material.ImageGlowLine = 'ImageGlowLine'
Cesium.Material._materialCache.addMaterial(Cesium.Material.ImageGlowLine,{fabric: {type: Cesium.Material.ImageGlowLine,uniforms: {color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),image: Cesium.Material.DefaultImageId,},source: ImageGlowLinetMaterial,},translucent: function (material) {return true},}
)

3. 完整示例代码

GlowLine.js

/** @Description:* @Author: maizi* @Date: 2022-05-27 11:36:22* @LastEditTime: 2024-08-27 18:27:19* @LastEditors: maizi*/
const merge = require('deepmerge')
import { GlowLineMaterialProperty, ImageGlowLineMaterialProperty } from '../../materialProperty/index.js'
const defaultStyle = {power: 0.25,color: "#ffff00",lineWidth: 8,type: 0
}class GlowLine {constructor(viewer, coords, options = {}) {this.viewer = viewerthis.coords = coords;this.options = options;this.props = this.options.props;this.style = merge(defaultStyle, this.options.style || {});this.entity = null;this.material = nullthis.points = []this.init();}init() {this.createMaterial();this.entity = new Cesium.Entity({id: Math.random().toString(36).substring(2),type: "glow_line",polyline: {positions: this.getPositons(),width: this.style.lineWidth,material: this.material,//clampToGround: true}});}addPoints() {this.coords.forEach((coord) => {const point = new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(coord[0],coord[1],coord[2]),point: {color: Cesium.Color.DARKBLUE.withAlpha(.4),pixelSize: 6,outlineColor: Cesium.Color.YELLOW.withAlpha(.8),outlineWidth: 4}     }); this.viewer.entities.add(point)this.points.push(point)})}removePoints() {this.points.forEach((point) => {this.viewer.entities.remove(point)})this.points = []}getPositons() {const positions = []this.coords.forEach((coord) => {positions.push(Cesium.Cartesian3.fromDegrees(coord[0], coord[1], coord[2]));})return positions}createMaterial() {switch(this.style.type){case 0:this.material = new GlowLineMaterialProperty({color: new Cesium.Color.fromCssColorString(this.style.color),power:this.style.power});breakcase 1:this.material = new ImageGlowLineMaterialProperty({color: new Cesium.Color.fromCssColorString(this.style.color),image: require("@/assets/img/glow_line.png"),});break}}updateStyle(style) {this.style = merge(defaultStyle, style);this.entity.polyline.width = this.style.lineWidththis.material.color = new Cesium.Color.fromCssColorString(this.style.color)if(this.style.type === 0) {this.material.power = this.style.power}}setSelect(enabled) {if (enabled) {this.addPoints()} else {this.removePoints()}}
}export {GlowLine
}

MapWorks.js

import GUI from 'lil-gui'; 
// 初始视图定位在中国
import { GlowLine } from './GlowLine'Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);let viewer = null;
let graphicLayer = null
let graphicList = []
let selectGraphic = null
let eventHandler = null
let gui = nullfunction initMap(container) {viewer = new Cesium.Viewer(container, {animation: false,baseLayerPicker: false,fullscreenButton: false,geocoder: false,homeButton: false,infoBox: false,sceneModePicker: false,selectionIndicator: false,timeline: false,navigationHelpButton: false, scene3DOnly: true,orderIndependentTranslucency: false,contextOptions: {webgl: {alpha: true}}})viewer._cesiumWidget._creditContainer.style.display = 'none'viewer.scene.fxaa = trueviewer.scene.postProcessStages.fxaa.enabled = trueif (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {// 判断是否支持图像渲染像素化处理viewer.resolutionScale = window.devicePixelRatio}// 移除默认影像removeAll()// 地形深度测试viewer.scene.globe.depthTestAgainstTerrain = true// 背景色viewer.scene.globe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 0)// 太阳光照viewer.scene.globe.enableLighting = true;// 初始化图层initLayer()// 初始化鼠标事件initClickEvent()//调试window.viewer = viewer
}function initGui() {let params = {...selectGraphic.style}gui = new GUI()let layerFolder = gui.title('样式设置')if (params.type === 0) {layerFolder.add(params, 'power', 0, 1).step(0.01).onChange(function (value) {selectGraphic.updateStyle(params)})}layerFolder.add(params, 'lineWidth', 1, 30).step(1).onChange(function (value) {selectGraphic.updateStyle(params)})layerFolder.addColor(params, 'color').onChange(function (value) {selectGraphic.updateStyle(params)})
}function initLayer() {const layerProvider = new Cesium.ArcGisMapServerImageryProvider({url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'});viewer.imageryLayers.addImageryProvider(layerProvider);graphicLayer = new Cesium.CustomDataSource('graphicLayer')viewer.dataSources.add(graphicLayer)
}function loadGrowLine(lines) {lines.forEach(line => {const glowLine = new GlowLine(viewer, line.points, {style: line.style})graphicList.push(glowLine)graphicLayer.entities.add(glowLine.entity)});viewer.flyTo(graphicLayer)
}function initClickEvent() {eventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);initLeftClickEvent()initMouseMoveEvent()
}function initLeftClickEvent() {eventHandler.setInputAction((e) => {if (selectGraphic) {selectGraphic.setSelect(false)selectGraphic = null}if (gui) {gui.destroy()}let pickedObj = viewer.scene.pick(e.position);if (pickedObj && pickedObj.id) {if (pickedObj.id.type === 'glow_line') {selectGraphic = getGraphicById(pickedObj.id.id)if (selectGraphic) {selectGraphic.setSelect(true)initGui()}}}},Cesium.ScreenSpaceEventType.LEFT_CLICK)
}function initMouseMoveEvent() {eventHandler.setInputAction((e) => {const pickedObj = viewer.scene.pick(e.endPosition);if (pickedObj && pickedObj.id) {if (pickedObj.id.type === 'glow_line') {// 改变鼠标状态viewer._element.style.cursor = "";document.body.style.cursor = "pointer";} else {viewer._element.style.cursor = "";document.body.style.cursor = "default";}} else {viewer._element.style.cursor = "";document.body.style.cursor = "default";}},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}function getGraphicById(id) {let line = nullfor (let i = 0; i < graphicList.length; i++) {if (graphicList[i].entity.id === id) {line = graphicList[i]break} }return line
}function removeAll() {viewer.imageryLayers.removeAll();
}function destroy() {viewer.entities.removeAll();viewer.imageryLayers.removeAll();viewer.destroy();
}export {initMap,loadGrowLine,destroy
}

GlowLine.vue

<!--* @Description: * @Author: maizi* @Date: 2023-04-07 17:03:50* @LastEditTime: 2024-08-27 17:02:06* @LastEditors: maizi
--><template><div id="container"></div>
</template><script>
import * as MapWorks from './js/MapWorks'
export default {name: 'GlowLine',mounted() {this.init();},methods:{init(){let container = document.getElementById("container");MapWorks.initMap(container)let lines = [{points: [[104.068822,30.654807,10],[104.088822,30.654807,10],],style: {type: 0},},{points: [[104.068822,30.655807,10],[104.088822,30.655807,10],],style: {type: 1},},];MapWorks.loadGrowLine(lines)}},beforeDestroy(){//实例被销毁前调用,页面关闭、路由跳转、v-if和改变key值MapWorks.destroy();}
}
</script><style lang="scss" scoped>
#container{width: 100%;height: 100%;background: rgba(7, 12, 19, 1);overflow: hidden;background-size: 40px 40px, 40px 40px;background-image: linear-gradient(hsla(0, 0%, 100%, 0.05) 1px, transparent 0), linear-gradient(90deg, hsla(0, 0%, 100%, 0.05) 1px, transparent 0);
}</style>

4. 运行结果


http://www.mrgr.cn/news/15199.html

相关文章:

  • (三)了解MySQL 【用户创建和权限/索引】
  • 天玑9200 V2双芯联动旗舰手机Vivo X90拆解
  • 你好GPT-4o,程序员如何通过GPT-4o提升自己的编码能力
  • wpf prism 《3》 弹窗 IOC
  • 安全帽佩戴监测摄像机
  • 2024最新版DataGrip安装教程-全网最新版教程
  • java 读取json文件并写入Excel
  • Windows Edge兼容性问题修复
  • day15JS-es6的基础语法
  • git分支
  • DocuSign集成方案 | 结合 DocuSign 与 Oracle,加快业务完成速度!
  • python基础操作
  • 25考研计算机组成原理复习·4.3程序的机器级代码表示
  • 【设计模式】创建型模式——抽象工厂模式
  • 游戏引擎详解——图片
  • 【机器学习】智驭未来:机器学习如何重塑现代城市管理新生态
  • 一 lua学习笔记:概述
  • 聚观早报 | 苹果推出AI消除功能;比亚迪2024上半年营收
  • C与C++的三种区分方式
  • 每日练习6