honey们,一起来学习cesium天气效果吧^^
本篇文章实现的是简单的HTML页面在线显示,用其他框架的改一下就可以啦
1、CDN引入
<script src='https://cdn.bootcdn.net/ajax/libs/cesium/1.98.1/Cesium.js'></script>
<link href='https://cdn.bootcdn.net/ajax/libs/cesium/1.98.1/Widgets/widgets.css' rel='stylesheet'>
2、页面显示
设置切换按钮和显示区域
<body>
<div class="button">
<button onclick="rainning()">下雨</button>
<button onclick="snowwing()">下雪</button>
<button onclick="clean()">晴天</button>
</div>
<div id='container'></div>
</body>
3、容器设置
有需要的控件,可以自行改动为“true”
const viewer = new Cesium.Viewer('container', {
// terrainExaggeration: 1.0,
fullscreenButton: false,
baseLayerPicker: false,
selectionIndicator: false,
sceneModePicker: false,
navigationHelpButton: false,
homeButton: false,
animation: false, // 时间控制器
geocoder: false,
timeline: false, //时间线
infoBox: false,
scene3DOnly: false,
vrButton: false,
shouldAnimate: true,
navigationInstructionsInitiallyVisible: false,
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t{s}.tianditu.gov.cn/img_w/wmts?tk=4befa5ab78e9656c766335d1a007f570',
layer: 'img',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
maximumLevel: 18,
}),
});
viewer._cesiumWidget._creditContainer.style.display = 'none';
//启用光照
viewer.scene.globe.enableLighting = true
4、特效着色器设置
/***********************下雨*************************/
const FS_Rain="uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float hash(float x){\n\
return fract(sin(x*133.3)*13.13);\n\
}\n\
\n\
void main(void){\n\
\n\
float time = czm_frameNumber / 60.0;\n\
vec2 resolution = czm_viewport.zw;\n\
\n\
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
vec3 c=vec3(.6,.7,.8);\n\
\n\
float a=-.4;\n\
float si=sin(a),co=cos(a);\n\
uv*=mat2(co,-si,si,co);\n\
uv*=length(uv+vec2(0,4.9))*.3+1.;\n\
\n\
float v=1.-sin(hash(floor(uv.x*100.))*2.);\n\
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;\n\
c*=v*b; \n\
\n\
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5); \n\
}\n\
";
/*************************下雪*********************/
const FS_Snow="uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float snow(vec2 uv,float scale)\n\
{\n\
float time = czm_frameNumber / 60.0;\n\
float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;\n\
uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;\n\
uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;\n\
p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);\n\
k=smoothstep(0.,k,sin(f.x+f.y)*0.01);\n\
return k*w;\n\
}\n\
\n\
void main(void){\n\
vec2 resolution = czm_viewport.zw;\n\
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
vec3 finalColor=vec3(0);\n\
float c = 0.0;\n\
c+=snow(uv,30.)*.0;\n\
c+=snow(uv,20.)*.0;\n\
c+=snow(uv,15.)*.0;\n\
c+=snow(uv,10.);\n\
c+=snow(uv,8.);\n\
c+=snow(uv,6.);\n\
c+=snow(uv,5.);\n\
finalColor=(vec3(c)); \n\
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.5); \n\
\n\
}\n\
";
5、控制按钮
// 清除特效
let lastStage=null;
let removeStage = () => {
lastStage && viewer.scene.postProcessStages.remove(lastStage), lastStage = null
}
//下雨
function rainning(){
removeStage()
var rain = new Cesium.PostProcessStage({
name: 'hi_rain',
fragmentShader: FS_Rain
});
viewer.scene.postProcessStages.add(rain);
lastStage=rain
}
//下雪
function snowwing(){
removeStage()
var snow = new Cesium.PostProcessStage({
name: 'hi_snow',
fragmentShader: FS_Snow
});
viewer.scene.postProcessStages.add(snow);
lastStage=snow
}
//晴天
function clean(){
removeStage()
lastStage=null
}
完整代码
<!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'>
<script src='https://cdn.bootcdn.net/ajax/libs/cesium/1.98.1/Cesium.js'></script>
<link href='https://cdn.bootcdn.net/ajax/libs/cesium/1.98.1/Widgets/widgets.css' rel='stylesheet'>
<title>Document</title>
<style>
html,
body,
#container {
margin: 0;
padding: 0;
height: 100%;
}
.button{
background:rgb(5,5,5);
}
</style>
</head>
<body>
<div class="button">
<button onclick="rainning()">下雨</button>
<button onclick="snowwing()">下雪</button>
<button onclick="clean()">晴天</button>
</div>
<div id='container'></div>
</body>
<script>
const viewer = new Cesium.Viewer('container', {
// terrainExaggeration: 1.0,
fullscreenButton: false,
baseLayerPicker: false,
selectionIndicator: false,
sceneModePicker: false,
navigationHelpButton: false,
homeButton: false,
animation: false, // 时间控制器
geocoder: false,
timeline: false, //时间线
infoBox: false,
scene3DOnly: false,
vrButton: false,
shouldAnimate: true,
navigationInstructionsInitiallyVisible: false,
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t{s}.tianditu.gov.cn/img_w/wmts?tk=4befa5ab78e9656c766335d1a007f570',
layer: 'img',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
maximumLevel: 18,
}),
});
viewer._cesiumWidget._creditContainer.style.display = 'none';
//启用光照
viewer.scene.globe.enableLighting = true
/***********************下雨*************************/
const FS_Rain="uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float hash(float x){\n\
return fract(sin(x*133.3)*13.13);\n\
}\n\
\n\
void main(void){\n\
\n\
float time = czm_frameNumber / 60.0;\n\
vec2 resolution = czm_viewport.zw;\n\
\n\
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
vec3 c=vec3(.6,.7,.8);\n\
\n\
float a=-.4;\n\
float si=sin(a),co=cos(a);\n\
uv*=mat2(co,-si,si,co);\n\
uv*=length(uv+vec2(0,4.9))*.3+1.;\n\
\n\
float v=1.-sin(hash(floor(uv.x*100.))*2.);\n\
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;\n\
c*=v*b; \n\
\n\
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5); \n\
}\n\
";
/*************************下雪*********************/
const FS_Snow="uniform sampler2D colorTexture;\n\
varying vec2 v_textureCoordinates;\n\
\n\
float snow(vec2 uv,float scale)\n\
{\n\
float time = czm_frameNumber / 60.0;\n\
float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;\n\
uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;\n\
uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;\n\
p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);\n\
k=smoothstep(0.,k,sin(f.x+f.y)*0.01);\n\
return k*w;\n\
}\n\
\n\
void main(void){\n\
vec2 resolution = czm_viewport.zw;\n\
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
vec3 finalColor=vec3(0);\n\
float c = 0.0;\n\
c+=snow(uv,30.)*.0;\n\
c+=snow(uv,20.)*.0;\n\
c+=snow(uv,15.)*.0;\n\
c+=snow(uv,10.);\n\
c+=snow(uv,8.);\n\
c+=snow(uv,6.);\n\
c+=snow(uv,5.);\n\
finalColor=(vec3(c)); \n\
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.5); \n\
\n\
}\n\
";
// 清除特效
let lastStage=null;
let removeStage = () => {
lastStage && viewer.scene.postProcessStages.remove(lastStage), lastStage = null
}
//下雨
function rainning(){
removeStage()
var rain = new Cesium.PostProcessStage({
name: 'hi_rain',
fragmentShader: FS_Rain
});
viewer.scene.postProcessStages.add(rain);
lastStage=rain
}
//下雪
function snowwing(){
removeStage()
var snow = new Cesium.PostProcessStage({
name: 'hi_snow',
fragmentShader: FS_Snow
});
viewer.scene.postProcessStages.add(snow);
lastStage=snow
}
//晴天
function clean(){
removeStage()
lastStage=null
}
</script>
</html>
实现效果
着色器设置引用https://blog.csdn.net/qq_40863573/article/details/125327716?spm=1001.2014.3001.5506