最终效果图如下:
实现方法:
步骤一:使用cesiumlib生产白模,格式为3dtiles
注意事项:采用其他方式可能导致白模贴地,从而导致不能实现该效果,例如把步骤二的服务地址改为Cesium Sandcastle 里的3dtiles服务,就不能实现效果图里的效果。原因是cesiumlib生成的白模服务本质上是错误的,是都在一个平面上。所以为保证精确度,场景需要小一些。
设置拉伸高度。
提交处理:
步骤二:设置样式(style)、customShader
导入3dtiles服务:
const tileset = await Cesium.Cesium3DTileset.fromUrl(
"第一步生成的3dtiles数据发布的服务地址"
);
viewer.scene.primitives.add(tileset);
设置样式:
const style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
["${Floor} < 10.0", "color('#00356A')"], // 深蓝色
["(${Floor} >= 10.0) && (${Floor} < 20.0)", "color('#0099FF')"], // 亮蓝色
["(${Floor} >= 20.0) && (${Floor} < 30.0)", "color('#0066CC')"], // 电蓝色
["(${Floor} >= 30.0) && (${Floor} < 60.0)", "color('#00FFFF')"], // 荧光蓝
["${Floor} >= 60.0", "color('#0033CC')"], // 深蓝色
],
},
});
tileset.style = style;
设置shader:
// 增加自定义shader
let customShader = new Cesium.CustomShader({
//PBR(基于物理的渲染)或 UNLIT,具体取决于所需的结果。
lightingModel: Cesium.LightingModel.UNLIT,
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
float _baseHeight = 0.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
float _heightRange = 30.0; // 高亮的范围(_baseHeight ~ _baseHeight + _heightRange) 默认是 0-60米
float _glowRange = 300.0; // 光环的移动范围(高度)
float vtxf_height = fsInput.attributes.positionMC.z-_baseHeight;
float vtxf_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
float vtxf_a12 = vtxf_height / _heightRange + sin(vtxf_a11) * 0.1;
material.diffuse*= vec3(vtxf_a12, vtxf_a12, vtxf_a12);
float vtxf_a13 = fract(czm_frameNumber / 120.0);
float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
float vtxf_diff = step(0.005, abs(vtxf_h - vtxf_a13));
material.diffuse += material.diffuse * (1.0 - vtxf_diff);
}
`,
});
tileset.customShader = customShader;
}