【cesium】打造科技感建筑泛光效果

一些智慧城市项目经常需要加载建筑白膜数据(3dtiles),并制作炫酷的炫光效果,在cesium中可以使用自定义着色器修改白膜建筑的外观。

1.首先,加载3Dtiles格式的建筑白膜数据,这里我们使用一个免费的数据链接:

data.mars3d.cn/3dtiles/jzw…

这是mars3D提供的一个链接,发送请求就会返回3Dtiles建筑数据,我们用cesium提供的方法加载一下:

var viewer = new Cesium.Viewer("cesiumContainer", {
        geocoder: false, //是否显示地名查找工具
        homeButton: false, //是否显示首页位置工具
        sceneModePicker: false, //是否显示视角模式切换工具
        baseLayerPicker: false, //是否显示默认图层选择工具
        navigationHelpButton: false, //是否显示导航帮助工具
        animation: false, //是否显示动画工具
        timeline: false, //是否显示时间轴工具
        fullscreenButton: false, //是否显示全屏按钮工具
});
//启用实验性功能
Cesium.ExperimentalFeatures.enableModelExperimental = true;


//加载建筑数据,赋给变量tilesets
let tilesets = viewer.scene.primitives.add(
        new Cesium.Cesium3DTileset({
                url: "http://data.mars3d.cn/3dtiles/jzw-hefei/tileset.json", 
        })
);

修改一下建筑的颜色:

tilesets.readyPromise.then(function (tileset) {
        tileset.style = new Cesium.Cesium3DTileStyle({
                color: {
                        conditions: [["true", "color('rgb(51, 153, 255)',1)"]],
                },
        });
        viewer.flyTo(tileset);
});

需要使用cesium1.87+提供的customShaderAPI,来自定义shader


var customShader = new Cesium.CustomShader({
//不考虑光照模型
lightingModel: Cesium.LightingModel.UNLIT,
//修改片元着色器
fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
            float _baseHeight = 0.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
            float _heightRange = 60.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 / 360.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);
    }
    `,
});
//将定义好的着色器作用域建筑tilesets
tilesets.customShader = customShader;

 这个时候再看效果,明显就不一样了:

当然,这个影像底色不好看,也需要改一改,

//修改地图底色
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);
  }
}

最终效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值