前言
人生一迹,谨以此记录地图相关系列知识
问题背景:解决Cesium中气象环境模拟模型!
在许多应用场景中,气象环境模拟是极其关键的一部分。Cesium提供了强大的三维地球渲染和可视化工具,但在气象环境模拟方面却相对较弱。如何在Cesium中构建一个真实可靠的气象环境模型,以满足更复杂的场景需求,是当前的挑战。这种模型需要考虑到各种各样的气候和环境因素,比如热量传递、湿度变化、风向风速、云层移动等。因此,我们需要深入研究如何在Cesium中开发一个强大、准确且动态的气象环境模拟模型,以便为更广泛的应用场景提供强大的支持。
一、雨着色器代码(GLSL)
雨着色器代码是用于模拟下雨效果的图形渲染代码,通常使用OpenGL Shading Language (GLSL)来实现。GLSL是一种高级着色语言,专门用于编写可在GPU上并行执行的小程序,称为"着色器"。
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
float hash(float x){
return fract(sin(x*133.3)*13.13);
}
void main(void){
float time = czm_frameNumber / 60.0;
vec2 resolution = czm_viewport.zw;
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
vec3 c=vec3(.6,.7,.8);
float a= -.4;
float si=sin(a),co=cos(a);
uv*=mat2(co,-si,si,co);
uv*=length(uv+vec2(0,4.9))*.3+1.;
float v=1.-sin(hash(floor(uv.x*100.))*2.);
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
c*=v*b;
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5);
}
二、Cesium加载着色器代码
在Cesium中,PostProcessStage类用于执行后处理操作,这些操作在场景已经被渲染到帧缓冲区之后进行,如镜头效果、边缘检测等。一般来说,后处理可以用来改变最终呈现图像的整体外观。
其中,我们常见的着色器通常应用于单个模型或者特定的几何体上,而后处理着色器则是直接作用于整个场景的渲染结果上。因此,后处理着色器通常用于实现全局的视觉效果,比如雾、深度感、暗角、对比度增强等。
let rain = new Cesium.PostProcessStage({
fragmentShader: rainFS
});
<!-- 加载雨着色器代码 -->
viewer.scene.postProcessStages.add(rain);
<!-- 卸载雨着色器代码 -->
viewer.scene.postProcessStages.remove(rain);
三、全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cesium 气象状态 下雨天</title>
<!-- <link rel="stylesheet" href="./CesiumUnminified/Widgets/widgets.css">
<script type="text/javascript" src="./CesiumUnminified/Cesium.js"></script> -->
<link rel="stylesheet" href="./Cesium/Widgets/widgets.css">
<script type="text/javascript" src="./Cesium/Cesium.js"></script>
</head>
<body>
<div id="cesiumContainer"></div>
<script type="text/javascript">
let viewer = new Cesium.Viewer('cesiumContainer');
// 更换底图
let imageryLayers = viewer.imageryLayers;
let map = new Cesium.UrlTemplateImageryProvider({
url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}", //高德地图
minimumLevel: 3,
maximumLevel: 16,
});
imageryLayers.addImageryProvider(map); //添加地图贴图
// 场景定位
viewer.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(121.195,21.813,738947.02),
orientation :{
heading : Cesium.Math.toRadians(355.1),
pitch : Cesium.Math.toRadians(-75.3),
roll :0.0
}
});
// 雨天---着色器
let rainFS = `
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
float hash(float x){
return fract(sin(x*133.3)*13.13);
}
void main(void){
float time = czm_frameNumber / 60.0;
vec2 resolution = czm_viewport.zw;
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
vec3 c=vec3(.6,.7,.8);
float a= -.4;
float si=sin(a),co=cos(a);
uv*=mat2(co,-si,si,co);
uv*=length(uv+vec2(0,4.9))*.3+1.;
float v=1.-sin(hash(floor(uv.x*100.))*2.);
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
c*=v*b;
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5);
}
`
let rain = new Cesium.PostProcessStage({
fragmentShader: rainFS
});
viewer.scene.postProcessStages.add(rain);
</script>
</body>
</html>