Cesium 实战 - OD 线,动态连接线(卫星通信)

Cesium 实战 - OD 线,动态连接线

最近有个卫星相关的项目,希望有一个卫星通信的效果,在思考之后,觉得其实就是一个线段 entity 对象,给他一个动态效果应该可以实现。

经尝试之后,在之前的流动线效果基础上进行修改,达到了通信效果。

实际上是通过自定义材质类,通过着色器代码实现

本文包含OD 线动态效果代码、完整代码以及在线示例三部分。


OD 线动态效果代码


/**
 * @description:卫星通信材质
 * @date: 2023年6月17日10:43:18
 */
function SatelliteMaterialProperty(options) {
    
    
    // 默认参数设置
    this._definitionChanged = new Cesium.Event();
    this.color = options.color;
}

Object.defineProperties(SatelliteMaterialProperty.prototype, {
    
    
    isConstant: {
    
    
        get: function() {
    
    
            return false;
        }
    },
    definitionChanged: {
    
    
        get: function() {
    
    
            return this._definitionChanged;
        }
    },
    color: Cesium.createPropertyDescriptor('color')
});

SatelliteMaterialProperty.prototype.getType = function(time) {
    
    
    return 'SatelliteMaterial';
};

SatelliteMaterialProperty.prototype.getValue = function(time, result) {
    
    
    if (!Cesium.defined(result)) {
    
    
        result = {
    
    };
    }
    result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
    viewer.scene.requestRender();
    return result;
};

SatelliteMaterialProperty.prototype.equals = function(other) {
    
    
    return this === other ||
        (other instanceof SatelliteMaterialProperty &&
            Cesium.Property.equals(this._color, other._color));
};

Cesium.Material.SatelliteType = 'SatelliteMaterial';

Cesium.Material.SatelliteSource = `
    uniform vec4 color;
    uniform float speed;
    uniform float percent;
    uniform float gradient;
    uniform float count;
    
    czm_material czm_getMaterial(czm_materialInput materialInput){
      czm_material material = czm_getDefaultMaterial(materialInput);
      vec2 st = materialInput.st;
      float t =fract(czm_frameNumber * speed / 1000.0);
      float v = 1.0-(1.0-smoothstep(gradient,0.0,fract(st.x*count-t)))*0.95;
      material.diffuse = color.rgb/10.0 + vec3(v)*9.0;
      material.alpha = color.a;
      return material;
    }
    `;
    
Cesium.Material._materialCache.addMaterial(Cesium.Material.SatelliteType, {
    
    
    fabric: {
    
    
        type: Cesium.Material.SatelliteType,
        uniforms: {
    
    
            color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),
            speed: 30.0,
            gradient: 0.2,
            count: 15,
        },
        source: Cesium.Material.SatelliteSource
    },
    translucent: function(material) {
    
    
        return true;
    }
});

以下是模拟卫星通信效果:
在这里插入图片描述


完整代码


<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Use correct character set. -->
    <meta charset="utf-8"/>
    <!-- Tell IE to use the latest, best version. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
    <meta
            name="viewport"
            content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <title>Cesium model video</title>
    <link rel="stylesheet" href="./popup.css" type="text/css">
    <script src="http://openlayers.vip/examples/csdn/Cesium.js"></script>
    <script src="./cesium_init.js"></script>
    <script src="http://www.openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script>
    <script src="./CesiumPopup.js"></script>
    <style>
        @import url(./Widgets/widgets.css);

        html,
        body,
        #cesiumContainer {
      
      
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>

    <script>
        var _hmt = _hmt || [];
        (function () {
      
      
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>
<body>
<div id="cesiumContainer"></div>
<script>


    // 创建三维球
    const viewer = init();

	viewer.entities.add({
      
      
	  position: Cesium.Cartesian3.fromDegrees(
	   111.286419,31.864436,2000000.0
	  ),
	  model: {
      
      
	    uri: "https://www.openlayers.vip/examples/resources/weixing.gltf",
	    scale: 60.0,
	  },
	});
	
	
	viewer.entities.add({
      
      
	  position: Cesium.Cartesian3.fromDegrees(
	   118.286419,31.864436,2000000.0
	  ),
	  model: {
      
      
	    uri: "https://www.openlayers.vip/examples/resources/weixing.gltf",
	    scale: 70.0,
	    color: new Cesium.Color(0.0, 1.0, 1.0, 0.7),
	  },
	});
	
	
	/**
	 * @description:卫星通信材质
	 * @date: 2023年6月17日10:43:18
	 */
	function SatelliteMaterialProperty(options) {
      
      
	    // 默认参数设置
	    this._definitionChanged = new Cesium.Event();
	    this.color = options.color;
	}
	
	Object.defineProperties(SatelliteMaterialProperty.prototype, {
      
      
	    isConstant: {
      
      
	        get: function() {
      
      
	            return false;
	        }
	    },
	    definitionChanged: {
      
      
	        get: function() {
      
      
	            return this._definitionChanged;
	        }
	    },
	    color: Cesium.createPropertyDescriptor('color')
	});
	SatelliteMaterialProperty.prototype.getType = function(time) {
      
      
	    return 'SatelliteMaterial';
	};
	SatelliteMaterialProperty.prototype.getValue = function(time, result) {
      
      
	    if (!Cesium.defined(result)) {
      
      
	        result = {
      
      };
	    }
	    result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
	    viewer.scene.requestRender();
	    return result;
	};
	SatelliteMaterialProperty.prototype.equals = function(other) {
      
      
	    return this === other ||
	        (other instanceof SatelliteMaterialProperty &&
	            Cesium.Property.equals(this._color, other._color));
	};
	Cesium.Material.SatelliteType = 'SatelliteMaterial';
	Cesium.Material.SatelliteSource = `
	    uniform vec4 color;
	    uniform float speed;
	    uniform float percent;
	    uniform float gradient;
	    uniform float count;
	    
	    czm_material czm_getMaterial(czm_materialInput materialInput){
	      czm_material material = czm_getDefaultMaterial(materialInput);
	      vec2 st = materialInput.st;
	      float t =fract(czm_frameNumber * speed / 1000.0);
	      float v = 1.0-(1.0-smoothstep(gradient,0.0,fract(st.x*count-t)))*0.95;
	      material.diffuse = color.rgb/10.0 + vec3(v)*9.0;
	      material.alpha = color.a;
	      return material;
	    }
	    `;
	Cesium.Material._materialCache.addMaterial(Cesium.Material.SatelliteType, {
      
      
	    fabric: {
      
      
	        type: Cesium.Material.SatelliteType,
	        uniforms: {
      
      
	            color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),
	            speed: 30.0,
	            gradient: 0.2,
	            count: 15,
	        },
	        source: Cesium.Material.SatelliteSource
	    },
	    translucent: function(material) {
      
      
	        return true;
	    }
	});
	
	
	viewer.entities.add({
      
      
	  name: "Blue dashed line",
	  polyline: {
      
      
	    positions: Cesium.Cartesian3.fromDegreesArrayHeights([
	      111.286419,31.864436,2000000.0,
	      118.286419,31.864436,2000000.0
	    ]),
	    width: 6,
	    material: new SatelliteMaterialProperty({
      
      
	                color: new Cesium.Color(1.0, 0.0, 0.0, 0.1)
	    }),
	  },
	});
	
	viewer.zoomTo(viewer.entities);


</script>
</body>
</html>

示例建立了两个卫星,模拟通信效果。

在这里插入图片描述


在线示例

OD 线模拟卫星通信

猜你喜欢

转载自blog.csdn.net/linzi19900517/article/details/131175946