在cesium通过自定义着色器实现半透明具有光带效果的电子围栏

338 阅读1分钟

首先我们分析一下,如何让一个实现动态电子围栏先观察一下图中的效果

Snipaste_2023-12-06_18-26-38.png

效果分析:

1.从透明度看,整体层半透明且上往下透明度逐渐增加的,也就是根据uv坐标的v轴进行渐变

2.里面有两条白色条纹,上下周期运动,运动方式我们联想到了波,两个条纹,其实uv坐标到v轴上的某个值,然后通过smoothstep将其差值

分析完毕开始代码实现

const getWallMaterial1 = (color?: Cesium.Color): Cesium.Material => {
  return new Cesium.Material({
    fabric: {
      uniforms: {
        color: Cesium.defaultValue(color, new Cesium.Color(0.5, 0.5, 0.4, 1)),
      },
      source: `
        uniform vec4 color;
        czm_material czm_getMaterial(czm_materialInput materialInput){
        czm_material material = czm_getDefaultMaterial(materialInput);
        float time = sin(czm_frameNumber/100.0);
        vec2 st = materialInput.st;
        vec2 uv = st;
        st = vec2(st.s, st.t - time); // 添加动画
        float y4 = distance(st.t,0.2); // 第一条白色条纹
        y4 = smoothstep(0.05,0.1,y4); // 通过差值现实第一条白色条纹
        float y6 = distance(st.t,0.5); // 第二
        y6 = smoothstep(0.05,0.1,y6); // 同理
        float y = 1.0- min(y6,y4); // 将其值限制在合理范围
        vec3 col = vec3(0.5,0.6,0.7); // 给定基础颜色
        col += color.rgb * y; // 基础颜色加上条纹颜色
        
        material.diffuse = col; // 最后着色
        material.alpha = uv.t + 0.4; // 实现渐变效果
        return material;
        }                                       
      `,
    },
  });
};

总结:首先让uv坐标朝着v轴运动,在时间的作用下;然后就是通过距离方程计算出白色条纹的像素,然后给该像素着色;最后在加上基础颜色;最最后根据v轴渐变,给alpha赋值