解决cesium锯齿和页面模糊问题

cesium中有个属性viewer.resolutionScale,默认值是1.0。
JavaScript中有个属性window.devicePixelRatio,属性返回的是当前显示设备的物理像素分辨率与CSS像素分辨率的比率,即一个CSS像素和一个物理像素的大小比值

cesium中viewer.resolutionScale默认值是1.0,也就是说无论在哪个屏幕上,cesium都把当前显示器的物理像素分辨率与CSS像素分辨率的比率(window.devicePixelRatio)当成是1.0来渲染,而实际上的比率可能是1.0或者1.25或者2.0(比如mac电脑Retina屏),所以造成锯齿和模糊。

想解决这个问题,显而易见,使viewer.resolutionScale的值等于window.devicePixelRatio值就好了。

if(Cesium.FeatureDetection.supportsImageRenderingPixelated()){//判断是否支持图像渲染像素化处理
  viewer.resolutionScale = window.devicePixelRatio;
}

如果这个时候地图远处还会有一点点锯齿,model边缘也还会有一点点锯齿,不用担心,官方文档给出的有个抗锯齿的属性: viewer.scene.fxaa,最新文档应该是viewer.scene.postProcessStages.fxaa.enabled,默认是false,改成true就可以了,一点点锯齿都看不见了,哈哈哈,直接说拜拜。

//是否开启抗锯齿
viewer.scene.fxaa = true;
viewer.scene.postProcessStages.fxaa.enabled = true;

但是开启后会造成字体的模糊(不是很明显),不用担心,设置字体的时候,字号设置大一些,然后比例缩小一倍,能够有效解决字体模糊。

label = {
  text: '测试',
  font: '24px Helvetica',
  scale: 0.5,
}

这样子基本就完美了~

import CircleRippleMaterialProperty from “./CircleRippleMaterialProperty”; // 从 public/circle.json 加载坐标数据 export async function loadRipplePoints() { const response = await fetch(“/circle.json”); // 注意路径是相对于 public 目录 return await response.json(); } // 创建多个波纹圆 export function createMultipleRippleCircles( viewer, ripplePoints, options = {} ) { const zIndex = options.zIndex || 1000; // 可选传入 zIndex ripplePoints.forEach((point) => { const position = Cesium.Cartesian3.fromDegrees( point.longitude, point.latitude ); viewer.entities.add({ name: point.name, position: position, ellipse: { semiMinorAxis: 5000.0, semiMajorAxis: 8000.0, height: 0, zIndex: zIndex, // 设置 zIndex 提升层级 material: new CircleRippleMaterialProperty({ color: Cesium.Color.fromCssColorString("#00FFFF").withAlpha(0.8), speed: 30.0, count: 2, gradient: 0.2, }), }, }); }); } 如图所示生成动态波纹圆代码,生成是生成了,但是波纹圆一旦放大就变得很模糊,看起来感觉断断续续的,有问题,你结合下面的vue文件找一些原因更改,但是注意最好不要更改vue文件,或者最小量更改: <div id="cesiumContainer"></div> <div ref="miniMapContainer" class="mini-map" @click="handleMiniMapClick"> <div class="location-indicator" :style="indicatorStyle"></div> <!-- 四个角折角 --> <div class="corner corner-top-left"></div> <div class="corner corner-top-right"></div> <div class="corner corner-bottom-left"></div> <div class="corner corner-bottom-right"></div> <!-- <div class="camera-icon">📷</div> --> <div class="focus-effect"></div> <div class="pulse"></div> </div> <Search /> <LocationBar v-if="loaded" :update-interval="100" :use-dms-format="useDmsFormat" /> </template> <style> /* @import "/temp/css/divGraphic.css"; */ </style> <script setup lang="ts"> import { computed, onUnmounted, onMounted, reactive } from "vue"; import LocationBar from "./location-bar.vue"; import Search from "./search.vue"; import initMap from "./init"; import { ref } from "vue"; import { loadRipplePoints, createMultipleRippleCircles } from './circle.js'; import { $ prototype } from "../../main.ts"; const miniMapContainer = ref<HTMLElement>(); let viewIndicator: Rectangle; // 视图指示器样式 const currentPosition = reactive({ longitude: 113.361538, latitude: 27.339318, }); // 更新指示器位置 const updateIndicatorPosition = () => { if (!$ prototype.$ map) return; const camera = $ prototype.$ map.camera; const rect = camera.computeViewRectangle(); if (!rect) return; // 计算指示器在鹰眼中的位置 const miniMapWidth = miniMapContainer.value?.clientWidth || 200; const miniMapHeight = miniMapContainer.value?.clientHeight || 150; // 更新CSS指示器(用于点击交互) const westPercent = (((rect.west * 180) / Math.PI + 180) / 360) * 100; const eastPercent = (((rect.east * 180) / Math.PI + 180) / 360) * 100; const southPercent = ((90 - (rect.south * 180) / Math.PI) / 180) * 100; const northPercent = ((90 - (rect.north * 180) / Math.PI) / 180) * 100; indicatorStyle.value = { left: `${westPercent}%`, top: `${northPercent}%`, width: `${eastPercent - westPercent}%`, height: `${southPercent - northPercent}%`, }; return rect; }; // 更新鹰眼地图 const updateOverview = () => { if (!$ prototype.$ map || !overviewViewer.value) return; // 获取主地图的当前视图范围 const rectangle = $ prototype.$ map.camera.computeViewRectangle(); if (!rectangle) return; // 更新当前中心位置 const center = Cesium.Rectangle.center(rectangle); currentPosition.longitude = Cesium.Math.toDegrees(center.longitude); currentPosition.latitude = Cesium.Math.toDegrees(center.latitude); // 计算视图矩形在鹰眼地图上的位置 const scene = overviewViewer.value.scene; const canvas = scene.canvas; const southwest = Cesium.Cartesian3.fromRadians( rectangle.west, rectangle.south ); const northeast = Cesium.Cartesian3.fromRadians( rectangle.east, rectangle.north ); const swPixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, southwest ); const nePixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, northeast ); if (!swPixel || !nePixel) return; // 更新视图矩形 viewRectangle.width = Math.abs(nePixel.x - swPixel.x); viewRectangle.height = Math.abs(nePixel.y - swPixel.y); viewRectangle.left = Math.min(swPixel.x, nePixel.x); viewRectangle.top = Math.min(swPixel.y, nePixel.y); syncView(); }; const overviewViewer = ref(null); const initMiniMap = () => { Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDhlNDdmYy03NzFhLTQ1ZTQtOWQ3NS1lZDAzNDc3YjE4NDYiLCJpZCI6MzAxNzQyLCJpYXQiOjE3NDcwNTMyMDN9.eaez8rQxVbPv2LKEU0sMDclPWyHKhh1tR27Vg-_rQSM"; if (!miniMapContainer.value) return; // 鹰眼地图初始化 overviewViewer.value = new Cesium.Viewer(miniMapContainer.value, { sceneMode: Cesium.SceneMode.SCENE2D, baseLayerPicker: false, homeButton: false, timeline: false, navigationHelpButton: false, animation: false, scene3DOnly: true, selectionIndicator: false, infoBox: false, imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", }), terrainProvider: window.Cesium.createWorldTerrain(), }); var toolbar = overviewViewer.value.container.getElementsByClassName( "cesium-viewer-toolbar" )[0]; if (toolbar) { toolbar.style.display = "none"; } // 隐藏鹰眼控件 overviewViewer.value.cesiumWidget.creditContainer.style.display = "none"; // 设置鹰眼固定视角 // overviewViewer.value.camera.setView({ // destination: new Cesium.Cartesian3( // -2432812.6687511606, // 5559483.804371395, // 2832009.419525571 // ), // }); }; const syncView = () => { if (!$ prototype.$ map || !overviewViewer.value) return; const rectangle = $ prototype.$ map.camera.computeViewRectangle(); if (!rectangle) return; // 鹰眼地图飞往相同范围 overviewViewer.value.camera.flyTo({ destination: Cesium.Rectangle.fromDegrees( Cesium.Math.toDegrees(rectangle.west), Cesium.Math.toDegrees(rectangle.south), Cesium.Math.toDegrees(rectangle.east), Cesium.Math.toDegrees(rectangle.north) ), duration: 1.5, }); }; function initRectangle() { overviewViewer.value.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(113.200224, 27.004546, 50000), orientation: { heading: 3.1769448901508976, pitch: -0.2880443992926125, roll: 6.283184370499525, }, duration: 3.0, // 飞行时间(秒) }); // 创建视图指示器 viewIndicator = overviewViewer.value.entities.add({ rectangle: { // coordinates: new window.Cesium.CallbackProperty( // updateIndicatorPosition, // false // ), coordinates: new Cesium.CallbackProperty(function () { // 必须返回 Cesium.Rectangle 对象 return new Cesium.Rectangle( Cesium.Math.toRadians(113.125), // 西经 Cesium.Math.toRadians(26.9541), // 南纬 Cesium.Math.toRadians(113.2542), // 东经 Cesium.Math.toRadians(27.2545225) // 北纬 ); }, false), // false 表示不持续更新(性能优化) material: Cesium.Color.RED.withAlpha(0.3), outline: true, outlineColor: Cesium.Color.RED, outlineWidth: 2, }, }); overviewViewer.value.flyTo(viewIndicator, { duration: 2, // 飞行持续时间(秒) offset: new Cesium.HeadingPitchRange( Cesium.Math.toRadians(0), // 朝向角度(0表示正北) Cesium.Math.toRadians(-45), // 俯仰角度(-45度俯视) 1000000 // 距离目标的距离(米) ), }); console.log(overviewViewer.value.entities); } const viewRectangle = reactive({ width: 0, height: 0, left: 0, top: 0, }); // 指示器样式计算 const indicatorStyle = computed(() => { if (!overviewViewer.value) return {}; // 将经纬度转换为屏幕坐标 const position = Cesium.Cartesian3.fromDegrees( currentPosition.longitude, currentPosition.latitude ); const scene = overviewViewer.value.scene; const canvas = scene.canvas; const pixel = Cesium.SceneTransforms.wgs84ToWindowCoordinates( scene, position ); if (!pixel) return { display: "none" }; return { left: `${pixel.x}px`, top: `${pixel.y}px`, display: "block", }; }); // 视图矩形样式计算 const rectangleStyle = computed(() => { return { width: `${viewRectangle.width}px`, height: `${viewRectangle.height}px`, left: `${viewRectangle.left}px`, top: `${viewRectangle.top}px`, display: viewRectangle.width > 0 ? "block" : "none", }; }); const loaded = ref(false); const useDmsFormat = ref(false); function addDemoGraphics() { const chinaBoundary = $ prototype.$ map.dataSources.add( Cesium.GeoJsonDataSource.load("/shp_zz.geojson", { stroke: Cesium.Color.WHITE, fill: false, clampToGround: true, describe: null, // 禁用默认样式描述 }) ); // 添加标签 chinaBoundary.then((dataSource) => { const entities = dataSource.entities.values; for (let entity of entities) { if (entity.polyline) { entity.polyline.fill = false; // entity.polyline.material.color = Cesium.Color.BLACK; // 彻底移除材质 } } }); } function flyToDes() { const center = Cesium.Cartesian3.fromDegrees(-98.0, 40.0); // map.camera.lookAt(center, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)); // 第一视角飞行 84.330408,38.24518 $ prototype.$ map.camera.flyTo({ destination: new Cesium.Cartesian3( -2432812.6687511606, 5559483.804371395, 2832009.419525571 ), orientation: { heading: 6.283185307179421, pitch: -1.0472145569408116, roll: 6.2831853071795205, }, complete: function () { // map.camera.lookAt( // Cesium.Cartesian3.fromDegrees(113.300224, 27.004546, 500), // new Cesium.HeadingPitchRange( // 3.1769448901508976, // -0.2880443992926125, // 500 // ) // ); // map.camera.flyTo({ // destination: Cesium.Cartesian3.fromDegrees(113.300224, 27.004546, 500), // orientation: { // heading: 3.1769448901508976, // pitch: -0.2880443992926125, // roll: 6.283184370499525, // }, // duration: 3.0, // 飞行时间(秒) // }); }, }); } // 监听主地图相机变化 const setupCameraListener = () => { $ prototype.$ map.camera.changed.addEventListener(updateOverview); // viewIndicator.rectangle.coordinates = updateIndicatorPosition(); }; const handleMiniMapClick = (event: MouseEvent) => { if (!miniMapContainer.value) return; const rect = miniMapContainer.value.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // 计算点击位置的经纬度 const lon = (x / rect.width) * 360 - 180; const lat = 90 - (y / rect.height) * 180; // 主地图飞向点击位置 $ prototype.$ map.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(lon, lat, 1000000), }); }; function addImage() { var rightImageProvider = new Cesium.UrlTemplateImageryProvider({ name: "影像图", type: "xyz", layer: "vec_d", url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png", minimumLevel: 1, maximumLevel: 17, crs: "EPSG:3857", }); $ prototype.$ map.imageryLayers.addImageryProvider(rightImageProvider); rightImageProvider.splitDirection = Cesium.SplitDirection.right; } onMounted(() => { // console.clear() initMap(); addImage(); loaded.value = true; addDemoGraphics(); flyToDes(); initMiniMap(); setupCameraListener(); setTimeout(function () { initRectangle(); }, 2000); // 新增部分:加载并创建波纹圆(不影响其他逻辑) (async () => { try { const ripplePoints = await loadRipplePoints(); createMultipleRippleCircles($ prototype.$ map, ripplePoints); // 注意这里没有空格 } catch (error) { console.error('加载波纹圆失败:', error); } })(); //测试加载wmts服务的geojson格式 //此处很重要,很重要如果是4326的话就需要,如果不是4326是900913就不需要下面的了 // var options = { // url: "http://localhost:8080/geoserver/zhuzhou/gwc/service/wmts", // layer: "zhuzhou:lukou_farmland", // name: "zhuzhou:lukou_farmland", // show: true, // alpha: 1.0, // serviceType: "wmts", // type: "raster", // // rectangle: layerData.rectangle, // minimumLevel: 1, // maximumLevel: 14, // tileMatrixSetID: "EPSG:4326", // style: "", // format: "application/json;type=geojson", // }; // options.tileMatrixLabels = [...Array(20).keys()].map((level) => // ("EPSG:4326:" + level).toString() // ); // if (options.tileMatrixSetID == "EPSG:4326") { // options.tilingScheme = new Cesium.GeographicTilingScheme({ // numberOfLevelZeroTilesX: 2, // numberOfLevelZeroTilesY: 1, // }); // } // const provider = new Cesium.WebMapTileServiceImageryProvider(options); // // $ prototype.$ map.imageryLayers.remove( // // $ prototype.$ map.imageryLayers._layers[0] // // ); // $ prototype.$ map!.imageryLayers.addImageryProvider(provider); }); onUnmounted(() => { if ($ prototype.$ map) { $ prototype.$ map.destroy(); $ prototype.$ map = null; } console.log("组件销毁"); }); // onload事件将在地图渲染后触发 const emit = defineEmits(["onload", "onclick"]); const initMars3d = async (option: any) => { emit("onclick", true); emit("onload", $ prototype.$ map); }; </script> <style lang="less"> /**cesium 工具按钮栏*/ .cesium-viewer-toolbar { top: auto !important; bottom: 35px !important; left: 12px !important; right: auto !important; } .cesium-toolbar-button img { height: 100%; } .cesium-viewer-toolbar > .cesium-toolbar-button, .cesium-navigationHelpButton-wrapper, .cesium-viewer-geocoderContainer { margin-bottom: 5px; float: left; clear: both; text-align: center; } .cesium-button { background-color: rgba(23, 49, 71, 0.8); color: #e6e6e6; fill: #e6e6e6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); line-height: 32px; } .cesium-button:hover { background: #3ea6ff; } /**cesium 底图切换面板*/ .cesium-baseLayerPicker-dropDown { bottom: 0; left: 40px; max-height: 700px; margin-bottom: 5px; background-color: rgba(23, 49, 71, 0.8); } /**cesium 帮助面板*/ .cesium-navigation-help { top: auto; bottom: 0; left: 40px; transform-origin: left bottom; background: none; background-color: rgba(23, 49, 71, 0.8); .cesium-navigation-help-instructions { background: none; } .cesium-navigation-button { background: none; } .cesium-navigation-button-selected, .cesium-navigation-button-unselected:hover { background: rgba(0, 138, 255, 0.2); } } /**cesium 二维三维切换*/ .cesium-sceneModePicker-wrapper { width: auto; } .cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon { float: right; margin: 0 3px; } /**cesium POI查询输入框*/ .cesium-viewer-geocoderContainer .search-results { left: 0; right: 40px; width: auto; z-index: 9999; } .cesium-geocoder-searchButton { background-color: rgba(23, 49, 71, 0.8); } .cesium-viewer-geocoderContainer .cesium-geocoder-input { background-color: rgba(63, 72, 84, 0.7); } .cesium-viewer-geocoderContainer .cesium-geocoder-input:focus { background-color: rgba(63, 72, 84, 0.9); } .cesium-viewer-geocoderContainer .search-results { background-color: rgba(23, 49, 71, 0.8); } /**cesium info信息框*/ .cesium-infoBox { top: 50px; background-color: rgba(23, 49, 71, 0.8); } .cesium-infoBox-title { background-color: rgba(23, 49, 71, 0.8); } /**cesium 任务栏的FPS信息*/ .cesium-performanceDisplay-defaultContainer { top: auto; bottom: 35px; right: 50px; } .cesium-performanceDisplay-ms, .cesium-performanceDisplay-fps { color: #fff; } /**cesium tileset调试信息面板*/ .cesium-viewer-cesiumInspectorContainer { top: 10px; left: 10px; right: auto; } .cesium-cesiumInspector { background-color: rgba(23, 49, 71, 0.8); } /**覆盖mars3d内部控件的颜色等样式*/ .mars3d-compass .mars3d-compass-outer { fill: rgba(23, 49, 71, 0.8); } .mars3d-contextmenu-ul, .mars3d-sub-menu { background-color: rgba(23, 49, 71, 0.8); > li > a:hover, > li > a:focus, > li > .active { background-color: #3ea6ff; } > .active > a, > .active > a:hover, > .active > a:focus { background-color: #3ea6ff; } } /* Popup样式*/ .mars3d-popup-color { color: #ffffff; } .mars3d-popup-background { background: rgba(23, 49, 71, 0.8); } .mars3d-popup-content { margin: 15px; } .mars3d-template-content label { padding-right: 6px; } .mars3d-template-titile { border-bottom: 1px solid #3ea6ff; } .mars3d-template-titile a { font-size: 16px; } .mars3d-tooltip { background: rgba(23, 49, 71, 0.8); border: 1px solid rgba(23, 49, 71, 0.8); } .mars3d-popup-btn-custom { padding: 3px 10px; border: 1px solid #209ffd; background: #209ffd1c; } .mars-dialog .mars-dialog__content { height: 100%; width: 100%; overflow: auto; padding: 5px; } .image { border: solid 2px #fff; } .content { height: 90%; padding-top: 10px; overflow-x: auto; overflow-y: auto; } .content-text { padding: 0 10px; text-indent: 30px; font-size: 17px; } .details-video { width: 100%; height: 760px; background-color: #000; } :where(.css-lt97qq9).ant-space { display: inline-flex; } :where(.css-lt97qq9).ant-space-align-center { align-items: center; } :where(.css-lt97qq9).ant-image .ant-image-mask { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; background: rgba(0, 0, 0, 0.5); cursor: pointer; opacity: 0; transition: opacity 0.3s; } :where(.css-lt97qq9).ant-image .ant-image-mask .ant-image-mask-info { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; padding: 0 4px; } :where(.css-1t97qq9)[class^="ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class^="ant-image"], :where(.css-1t97qq9)[class^="ant-image"] [class*=" ant-image"], :where(.css-1t97qq9)[class*=" ant-image"] [class*=" ant-image"] { box-sizing: border-box; } :where(.css-lt97qq9).ant-image .ant-image-img { width: 100%; height: auto; vertical-align: middle; } </style> <style scoped> .mini-map-container { position: relative; width: 100%; height: 100%; } .main-viewer { width: 100%; height: 100%; } .mini-map { position: absolute; right: 3vw; bottom: 6vh; width: 12vw; height: 17vh; border: 2px solid #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); z-index: 999; cursor: pointer; overflow: hidden; } .location-indicator { position: absolute; width: 14px; height: 14px; background: #ff3e3e; border: 2px solid white; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 15px rgba(255, 62, 62, 1); z-index: 100; } .view-rectangle { position: absolute; border: 2px solid #00f2fe; z-index: 99; pointer-events: none; box-shadow: 0 0 20px rgba(0, 242, 254, 0.7); } /* 相机聚焦样式 - 四个角折角 */ .corner { position: absolute; width: 25px; height: 25px; z-index: 100; pointer-events: none; } .corner::before, .corner::after { content: ""; position: absolute; background: #00f2fe; box-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .corner-top-left { top: -2px; left: -2px; } .corner-top-left::before { top: 0; left: 0; width: 15px; height: 3px; } .corner-top-left::after { top: 0; left: 0; width: 3px; height: 15px; } .corner-top-right { top: -2px; right: -2px; } .corner-top-right::before { top: 0; right: 0; width: 15px; height: 3px; } .corner-top-right::after { top: 0; right: 0; width: 3px; height: 15px; } .corner-bottom-left { bottom: -2px; left: -2px; } .corner-bottom-left::before { bottom: 0; left: 0; width: 15px; height: 3px; } .corner-bottom-left::after { bottom: 0; left: 0; width: 3px; height: 15px; } .corner-bottom-right { bottom: -2px; right: -2px; } .corner-bottom-right::before { bottom: 0; right: 0; width: 15px; height: 3px; } .corner-bottom-right::after { bottom: 0; right: 0; width: 3px; height: 15px; } .camera-icon { position: absolute; top: 10px; right: 10px; color: #00f2fe; font-size: 24px; z-index: 100; text-shadow: 0 0 10px rgba(0, 242, 254, 0.8); } .focus-effect { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 98; border: 2px solid rgba(0, 242, 254, 0.2); border-radius: 5px; box-shadow: inset 0 0 30px rgba(0, 242, 254, 0.1); } .pulse { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 10px; height: 10px; border-radius: 50%; background: rgba(0, 242, 254, 0.7); box-shadow: 0 0 0 0 rgba(0, 242, 254, 0.7); animation: pulse 2s infinite; } ::v-deep.cesium-viewer-toolbar { display: none; } </style> 还有同时结合 // CircleRippleMaterialProperty.js // import * as Cesium from 'cesium'; class CircleRippleMaterialProperty { constructor(options = {}) { this._definitionChanged = new Cesium.Event(); this._color = Cesium.defaultValue(options.color, Cesium.Color.BLUE); this._speed = Cesium.defaultValue(options.speed, 5.0); this._count = Cesium.defaultValue(options.count, 4); this._gradient = Cesium.defaultValue(options.gradient, 0.2); } get isConstant() { return false; } get definitionChanged() { return this._definitionChanged; } get color() { return this._color; } set color(value) { this._color = value; } get speed() { return this._speed; } set speed(value) { this._speed = value; } get count() { return this._count; } set count(value) { this._count = value; } get gradient() { return this._gradient; } set gradient(value) { this._gradient = value; } getType() { return 'CircleRipple'; } getValue(time, result) { if (!result) result = {}; result.color = this._color; result.speed = this._speed; result.count = this._count; result.gradient = this._gradient; return result; } equals(other) { return this === other || (other instanceof CircleRippleMaterialProperty && Cesium.Color.equals(this._color, other._color) && this._speed === other._speed && this._count === other._count && this._gradient === other._gradient); } } // 注册材质类型 Cesium.Material.CircleRippleType = 'CircleRipple'; Cesium.Material.CircleRippleSource = ` uniform vec4 color; uniform float speed; uniform float count; uniform float gradient; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); vec2 st = materialInput.st; float time = czm_frameNumber * speed / 1000.0; float d = distance(st, vec2(0.5, 0.5)); // 多圈波纹效果 float alpha = 0.0; for(float i = 0.0; i < count; i++) { float ripple = sin(d * 20.0 - time * 2.0 - i * 0.5); float fade = smoothstep(0.0, 0.3, d) * (1.0 - smoothstep(0.3, 0.5, d)); alpha += abs(ripple) * fade * pow(1.0 - d, gradient * 10.0); } material.alpha = alpha * color.a; material.diffuse = mix(color.rgb, vec3(1.0), d * 0.5); return material; }`; Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleRippleType, { fabric: { type: Cesium.Material.CircleRippleType, uniforms: { color: new Cesium.Color(0.0, 0.8, 1.0, 0.7), speed: 5.0, count: 4.0, gradient: 0.2 }, source: Cesium.Material.CircleRippleSource }, translucent: function() { return true; } }); export default CircleRippleMaterialProperty; 加上这个circleRippleMaterialProperty.js怎么修改
最新发布
07-06
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值