cesium 底图反色及滤镜

通过设置底图参数在一定程度上可以修改底图样式,但是想要调试出比较满意的底图还是很困难,因为cesium底图参数里并没有集成反色和滤镜,所以想要调出比较好看的底图,需要修改cesium源码的图层参数,添加反色和滤镜。这对与初学者并不友好,这里通过劫持源码渲染shader的方式(这并不是一个好主意),附加上反色和滤镜,尽可能的不去修改源码,这种方式需在初始时设置好滤镜颜色,因为缓存的原因,想动态修改滤镜颜色不太容易。后续有时间再讲讲如何修改源码,这里先按下不表。这里给出对高德电子地图添加反色和滤镜的完整示例。

1 完整示例代码

FilterLayer.vue

<!--
 * @Description: 
 * @Author: maizi
 * @Date: 2023-04-03 11:34:28
 * @LastEditTime: 2024-07-19 11:54:30
 * @LastEditors: maizi
-->

<template>
  <div id="container">
  </div>
</template>

<script>
import * as MapWorks from './js/MapWorks'
export default {
  name: 'FilterLayer',
  data(){
    return {
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy(){
    //实例被销毁前调用,页面关闭、路由跳转、v-if和改变key值
    MapWorks.destroy();
  },

  methods:{
    init(){
      let container = document.getElementById("container");
      MapWorks.initMap(container)
      MapWorks.addGdLayer()
    }
  }

}
</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>

 MapWorks.js

/*
 * @Description: 
 * @Author: maizi
 * @Date: 2023-04-03 17:34:21
 * @LastEditTime: 2024-07-19 11:55:10
 * @LastEditors: maizi
 */

import GUI from 'lil-gui'; 
import AmapImageryProvider from './AmapImageryProvider'
// 初始视图定位在中国
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);

let viewer = null;
let tileLayer = null;
const gui = new GUI();
const params = {
  alpha: 1.0,
  nightAlpha: 1.0,
  dayAlpha: 1.0,
  brightness: 0.6,
  contrast: 1.8,
  hue: 1,
  saturation: 0,
  gamma:  0.3
}

const filterParams = {
  bInvertColor: true,
  bFilterColor: true,
  filterColor: '#0044aa'
}

function 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 = true
  viewer.scene.postProcessStages.fxaa.enabled = true
  if (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)

   //gui面板
   initGui()
}

function initGui() {
  gui.title('参数设置')
  gui.add(params, 'alpha', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.alpha = params.alpha
  })
  gui.add(params, 'nightAlpha', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.nightAlpha = params.nightAlpha
  })
  gui.add(params, 'dayAlpha', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.dayAlpha = params.dayAlpha
  })
  gui.add(params, 'brightness', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.brightness = params.brightness
  })
  gui.add(params, 'contrast', 0, 2).step(0.01).onChange(function (value) {
    tileLayer.contrast = params.contrast
  })
  gui.add(params, 'hue', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.hue = params.hue
  })
  gui.add(params, 'saturation', 0, 1).step(0.01).onChange(function (value) {
    tileLayer.saturation = params.saturation
  })
  gui.add(params, 'gamma', 0, 10).step(0.01).onChange(function (value) {
    tileLayer.gamma = params.gamma
  })
}

function addGdLayer() {
  const layerProvider = new AmapImageryProvider({
    type: 'vec_label_w'
  });
  tileLayer = viewer.imageryLayers.addImageryProvider(layerProvider);

  tileLayer.brightness = 0.6
  tileLayer.contrast = 1.8
  tileLayer.gamma = 0.3
  tileLayer.hue = 1
  tileLayer.saturation = 0
  filterLayer(filterParams)
}

function filterLayer(options) {
  const {bInvertColor, bFilterColor, filterColor }  = options
  const color =  new Cesium.Color.fromCssColorString(filterColor);
  const filterRGB = [
    Math.round(color.red * 255),
    Math.round(color.green * 255),
    Math.round(color.blue * 255)
  ]
  let fragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources
  for (let i = 0; i < fragShader.length; i++) {
    const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
    let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
    if (bInvertColor) {
      strT += `
        color.r = 1.0 - color.r;
        color.g = 1.0 - color.g;
        color.b = 1.0 - color.b;
      `
    }
    if (bFilterColor) {
      strT += `
        color.r = color.r * ${filterRGB[0]}.0/255.0;
        color.g = color.g * ${filterRGB[1]}.0/255.0;
        color.b = color.b * ${filterRGB[2]}.0/255.0;
      `
    }
    fragShader[i] = fragShader[i].replace(strS, strT)
  }
}

function removeAll() {
  viewer.imageryLayers.removeAll();
}

function destroy() {
  viewer.entities.removeAll();
  viewer.imageryLayers.removeAll();
  viewer.destroy();
}

function setView(coords,hpr) {
  viewer.scene.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(coords[0], coords[1], coords[2]),
    orientation: {
      heading: Cesium.Math.toRadians(hpr.heading),
      pitch: Cesium.Math.toRadians(hpr.pitch),
      roll: Cesium.Math.toRadians(hpr.roll),
    }
  });
}


export {
  initMap,
  addGdLayer,
  setView,
  removeAll,
  destroy
}

AmapImageryProvider.js 的完整代码在cesium加载高德地图并纠偏一篇中已给出。

2 运行结果

  • 26
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值