cesium实现报警波纹

本文代码摘自https://blog.csdn.net/weixin_44058725/article/details/104017509

本人愚钝,刚接触自己实现不了,做了部分注释

 AddCircleScanPostStage(viewer, cartographicCenter, maxRadius, scanColor, duration) {
        var ScanSegmentShader =
            "uniform sampler2D colorTexture;\n" +
            "uniform sampler2D depthTexture;\n" +
            "varying vec2 v_textureCoordinates;\n" +
            "uniform vec4 u_scanCenterEC;\n" +
            "uniform vec3 u_scanPlaneNormalEC;\n" +
            "uniform float u_radius;\n" +
            "uniform vec4 u_scanColor;\n" +
            "vec4 toEye(in vec2 uv, in float depth)\n" +
            " {\n" +
            " vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n" +
            " vec4 posInCamera =czm_inverseProjection * vec4(xy, depth, 1.0);\n" +
            " posInCamera =posInCamera / posInCamera.w;\n" +
            " return posInCamera;\n" +
            " }\n" +
            "vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)\n" +
            "{\n" +
            "vec3 v01 = point -planeOrigin;\n" +
            "float d = dot(planeNormal, v01) ;\n" +
            "return (point - planeNormal * d);\n" +
            "}\n" +
            "float getDepth(in vec4 depth)\n" +
            "{\n" +
            "float z_window = czm_unpackDepth(depth);\n" +
            "z_window = czm_reverseLogDepth(z_window);\n" +
            "float n_range = czm_depthRange.near;\n" +
            "float f_range = czm_depthRange.far;\n" +
            "return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n" +
            "}\n" +
            "void main()\n" +
            "{\n" +
            "gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n" +
            "float depth = getDepth( texture2D(depthTexture, v_textureCoordinates));\n" +
            "vec4 viewPos = toEye(v_textureCoordinates, depth);\n" +
            "vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n" +
            "float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n" +
            "if(dis < u_radius)\n" +
            "{\n" +
            "float f = 1.0 -abs(u_radius - dis) / u_radius;\n" +
            "f = pow(f, 4.0);\n" +
            "gl_FragColor = mix(gl_FragColor, u_scanColor, f);\n" +
            "}\n" +
            "}\n";
        //根据坐标制图,通过笛卡尔积?没怎么看懂文档
        var _Cartesian3Center = Cesium.Cartographic.toCartesian(cartographicCenter);
        //转换到更高维度,4维了,不理解含义
        var _Cartesian4Center = new Cesium.Cartesian4(_Cartesian3Center.x, _Cartesian3Center.y, _Cartesian3Center.z, 1);
        //将图转换到WGS_84协议的经纬网中,额,将高度增加500
        var _CartographicCenter1 = new Cesium.Cartographic(cartographicCenter.longitude, cartographicCenter.latitude, cartographicCenter.height + 500);
        //转换为图,同上不懂*_*
        var _Cartesian3Center1 = Cesium.Cartographic.toCartesian(_CartographicCenter1);
        //转化到4维
        var _Cartesian4Center1 = new Cesium.Cartesian4(_Cartesian3Center1.x, _Cartesian3Center1.y, _Cartesian3Center1.z, 1);
        //获取毫秒数
        var _time = (new Date()).getTime();
        var _scratchCartesian4Center = new Cesium.Cartesian4();
        var _scratchCartesian4Center1 = new Cesium.Cartesian4();
        var _scratchCartesian3Normal = new Cesium.Cartesian3();
        //cesium后期处理
        var ScanPostStage = new Cesium.PostProcessStage({
          //执行做色器
            fragmentShader: ScanSegmentShader,
            //着色器制式,可以是常量或函数,着色器每一帧都将调用
            uniforms: {
                u_scanCenterEC: function () {
                    return Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                },
                u_scanPlaneNormalEC: function () {
                    var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                    var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                    _scratchCartesian3Normal.x = temp1.x - temp.x;
                    _scratchCartesian3Normal.y = temp1.y - temp.y;
                    _scratchCartesian3Normal.z = temp1.z - temp.z;
                    Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
                    return _scratchCartesian3Normal;
 
                },
                u_radius: function () {
                  //当前时间模周期余数除以周期控制圆圈周期变换大小
                    return maxRadius * (((new Date()).getTime() - _time) % duration) / duration;
                },
                u_scanColor: scanColor
            }
        });
        viewer.scene.postProcessStages.add(ScanPostStage);
        return (ScanPostStage);
    }

调用

addCircleScan(viewer,data){ //调用闪烁
        //防止移动、放大缩小会视觉偏移depthTestAgainstTerrain // 设置该属性为true之后,标绘将位于地形的顶部;如果设为false(默认值),那么标绘将位于平面上。缺陷:开启该属性有可能在切换图层时会引发标绘消失的bug。
        viewer.scene.globe.depthTestAgainstTerrain = true; 
        //根据经纬度和高度刻画位置
        var CartographicCenter = new Cesium.Cartographic(Cesium.Math.toRadians(data.lon), Cesium.Math.toRadians(data.lat), 0); //中心位子
        return  this.AddCircleScanPostStage(viewer, CartographicCenter,data.r,data.scanColor,data.interval);
    }

数据调用

 var pontdata={
            lon:"116.609119",//经度
            lat:"40.080861",//纬度
            r:"100000",//扫描半径
            scanColor:new Cesium.Color(1.0,0.0,0.0),//颜色注意必须是var scanColor = new Cesium.Color(1.0, 0.0, 0.0, 1);rgba形式的‘red’和‘#fff’都不行
            interval:"1000",//时间
        };
        this.addCircleScan(viewer,pontdata);
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(
            116.609119,
            40.080861,
            6493.719
          )

只能贴相关代码,无法贴出全部代码,利益相关,感谢前博主的技术分享

你可能感兴趣的:(cesium,cesium,报警波纹)