本文代码摘自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
)
只能贴相关代码,无法贴出全部代码,利益相关,感谢前博主的技术分享