cesium中,預設的底圖顏色往往難以滿足個性化需求,而【藍色科技】風格常常備受青睞,本文從實操角度介紹實現方法。
簡單來說,我們所用的方法叫做【反色濾鏡】,總的分為2個步驟,反色,過濾。具體做法如下:
首先要獲取目標影像圖層,這裡不能直接對div進行操作,因為會將地圖上的所有元素都反色過濾了。
程式碼解讀
複製程式碼
// 獲取地圖影像圖層
let baseLayer = viewer.imageryLayers.get(0);
其次,定義2個變數,用來控制是否反色,以及過濾的具體值
程式碼解讀
複製程式碼
//設定2個變數,用來判斷是否進行顏色的翻轉和過濾
baseLayer.invertColor = true;
baseLayer.filterRGB = [0, 50, 100]; //[255,255,255] = > [0,50,100]
接著要獲取著色器,方便後續直接操作著色器,寫入修改後的glsl。
程式碼解讀
複製程式碼
// 更改底圖著色器的程式碼
const baseFragmentShader =
viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources;
透過列印baseFragmentShader,可以看到裡面有3個
接下來是最關鍵的步驟,反色+過濾。
程式碼解讀
複製程式碼
// 迴圈修改著色器
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減去原來的值
程式碼解讀
複製程式碼
color.r = 1.0 - color.r;
color.g = 1.0 - color.g;
color.b = 1.0 - color.b;
過濾則是要套用公式,對R、G、B進行操作
程式碼解讀
複製程式碼
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]
完整程式碼如下,可以封裝成一個方法被呼叫。
程式碼解讀
複製程式碼
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
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
連結:https://juejin.cn/post/7276695947705630754
來源:稀土掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。