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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。