【cesium】修改底圖顏色為藍色科技範兒

疯子110發表於2024-11-26

cesium中,預設的底圖顏色往往難以滿足個性化需求,而【藍色科技】風格常常備受青睞,本文從實操角度介紹實現方法。

簡單來說,我們所用的方法叫做【反色濾鏡】,總的分為2個步驟,反色,過濾。具體做法如下:

首先要獲取目標影像圖層,這裡不能直接對div進行操作,因為會將地圖上的所有元素都反色過濾了。

js
程式碼解讀
複製程式碼
 // 獲取地圖影像圖層
  let baseLayer = viewer.imageryLayers.get(0);

其次,定義2個變數,用來控制是否反色,以及過濾的具體值

js
程式碼解讀
複製程式碼
  //設定2個變數,用來判斷是否進行顏色的翻轉和過濾
  baseLayer.invertColor = true;
  baseLayer.filterRGB = [0, 50, 100]; //[255,255,255] = > [0,50,100]

接著要獲取著色器,方便後續直接操作著色器,寫入修改後的glsl。

js
程式碼解讀
複製程式碼
//   更改底圖著色器的程式碼
  const baseFragmentShader =
    viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources;

透過列印baseFragmentShader,可以看到裡面有3個

接下來是最關鍵的步驟,反色+過濾。

js
程式碼解讀
複製程式碼
// 迴圈修改著色器
  for (let i = 0; i < baseFragmentShader.length; i++) {
    // console.log(baseFragmentShader[i]);
    const strS = "color = czm_saturation(color, textureSaturation);\n#endif\n";
    let strT = "color = czm_saturation(color, textureSaturation);\n#endif\n";
    if (baseLayer.invertColor) {
      strT += `
        color.r = 1.0 - color.r;
        color.g = 1.0 - color.g;
        color.b = 1.0 - color.b;
      `;
    }
    if (baseLayer.filterRGB) {
      strT += `
        color.r = color.r*${baseLayer.filterRGB[0]}.0/255.0;
        color.g = color.g*${baseLayer.filterRGB[1]}.0/255.0;
        color.b = color.b*${baseLayer.filterRGB[2]}.0/255.0;
      `;
    }

    baseFragmentShader[i] = baseFragmentShader[i].replace(strS, strT);
  }

因為R、G、B都是從0-1,反色就是用1減去原來的值

js
程式碼解讀
複製程式碼
color.r = 1.0 - color.r;
color.g = 1.0 - color.g;
color.b = 1.0 - color.b;

過濾則是要套用公式,對R、G、B進行操作

js
程式碼解讀
複製程式碼
color.r = color.r*${baseLayer.filterRGB[0]}.0/255.0;
color.g = color.g*${baseLayer.filterRGB[1]}.0/255.0;
color.b = color.b*${baseLayer.filterRGB[2]}.0/255.0;

strS中的內容是glsl,原本就存在於baseFragmentShader中,而修改後的顏色值,直接用replace進行替換,將strT頂進去,發揮作用。

filterRGB的值可以根據需要進行調整,我試了2個值,都不錯 [60, 145, 172] 和[0, 50, 100]

完整程式碼如下,可以封裝成一個方法被呼叫。

js
程式碼解讀
複製程式碼
export default function modifyMap(viewer) {
  // 獲取地圖影像圖層
  let baseLayer = viewer.imageryLayers.get(0);
  //設定2個變數,用來判斷是否進行顏色的翻轉和過濾
  baseLayer.invertColor = true;

  baseLayer.filterRGB = [0, 50, 100]; //[255,255,255] = > [0,50,100]
  //   更改底圖著色器的程式碼
  const baseFragmentShader =
    viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources;
  // console.log(baseFragmentShader);

  // 迴圈修改著色器
  for (let i = 0; i < baseFragmentShader.length; i++) {
    // console.log(baseFragmentShader[i]);
    const strS = "color = czm_saturation(color, textureSaturation);\n#endif\n";
    let strT = "color = czm_saturation(color, textureSaturation);\n#endif\n";
    if (baseLayer.invertColor) {
      strT += `
        color.r = 1.0 - color.r;
        color.g = 1.0 - color.g;
        color.b = 1.0 - color.b;
      `;
    }
    if (baseLayer.filterRGB) {
      strT += `
        color.r = color.r*${baseLayer.filterRGB[0]}.0/255.0;
        color.g = color.g*${baseLayer.filterRGB[1]}.0/255.0;
        color.b = color.b*${baseLayer.filterRGB[2]}.0/255.0;
      `;
    }

    baseFragmentShader[i] = baseFragmentShader[i].replace(strS, strT);
  }
}
標籤:
前端

作者:小前端端
連結:https://juejin.cn/post/7276695947705630754
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

相關文章