1 前言
为cesium添加天气的特效,添加雨天特效。
cesium探索系列目录
:传送门
2 代码封装与实现
2.1 cesium底层修改为WebGL2
Cesium 自 1.102.0 开始,为了更好支持跨平台,尤其是移动端,Cesium 默认使用 WebGL2,则之前参考的SnowEffect代码不能使用,需要进行webGL2的改造。
2.2 封装代码
对WebGL1代码的下雨效果进行WebGL2的改造,改造的代码如下:
/*
* @description:下雨效果
* @date:2023-08-02
*/
export class RainEffect {
tiltAngle: number | undefined;
rainSize: number | undefined;
rainSpeed: number | undefined;
viewer: Cesium.Viewer;
rainStage?: Cesium.PostProcessStage;
constructor(
viewer: Cesium.Viewer,
options: { tiltAngle: number; rainSize: number; rainSpeed: number }
) {
if (!viewer) throw new Error('no viewer object!');
options = options || {};
//倾斜角度,负数向右,正数向左
this.tiltAngle = Cesium.defaultValue(options.tiltAngle, -0.6);
this.rainSize = Cesium.defaultValue(options.rainSize, 0.3);
this.rainSpeed = Cesium.defaultValue(options.rainSpeed, 60.0);
this.viewer = viewer;
this.init();
}
init() {
this.rainStage = new Cesium.PostProcessStage({
name: 'czm_rain',
fragmentShader: this.rain(),
uniforms: {
tiltAngle: () => {
return this.tiltAngle;
},
rainSize: () => {
return this.rainSize;
},
rainSpeed: () => {
return this.rainSpeed;
},
},
});
this.viewer.scene.postProcessStages.add(this.rainStage);
}
destroy() {
if (!this.viewer || !this.rainStage) return;
this.viewer.scene.postProcessStages.remove(this.rainStage);
this.rainStage.destroy();
delete this.tiltAngle;
delete this.rainSize;
delete this.rainSpeed;
}
show(visible: boolean) {
this.rainStage!.enabled = visible;
}
rain() {
return `
uniform sampler2D colorTexture;
in vec2 v_textureCoordinates;
uniform float tiltAngle;
uniform float rainSize;
uniform float rainSpeed;
float hash(float x) {
return fract(sin(x * 133.3) * 13.13);
}
out vec4 vFragColor;
void main(void) {
float time = czm_frameNumber / rainSpeed;
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 = tiltAngle;
float si = sin(a), co = cos(a);
uv *= mat2(co, -si, si, co);
uv *= length(uv + vec2(0, 4.9)) * rainSize + 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;
vFragColor = mix(texture(colorTexture, v_textureCoordinates), vec4(c, 1), .5);
}
`;
}
}
代码主要修改了片源着色器中varying
,修改为in
的方式定义。同时,不再使用默认的gl_FragColor
,而是使用out
自定义。最后texture2D
需要修改为texture
。
// 主要修改 varying
varying vec2 v_textureCoordinates;
// 主要修改 gl_FragColor 和 texture2D
gl_FragColor=mix(texture2D(colorTexture,v_textureCoordinates),vec4(finalColor,1),.5);
2.3 代码调用
// 下雨效果
new RainEffect(viewer, {
tiltAngle: -0.6, //倾斜角度
rainSize: 0.6, // 雨大小
rainSpeed: 120.0 // 雨速
})