(function () { function SnowEffect(viewer, options) { if (!viewer) throw new Error("viewer is undefined") this.viewer = viewer; this.speed = Cesium.defaultValue(options.speed, 10) this.enabled = Cesium.defaultValue(options.enabled, true) this.init(); } SnowEffect.prototype.init = function () { this.snowStage = new Cesium.PostProcessStage({ name: 'czm_snow', fragmentShader: this.FragmentShader_Snow(), uniforms: { speed: () => { return this.speed; } } }); this.snowStage.enabled = this.enabled this.viewer.scene.postProcessStages.add(this.snowStage) } //定义下雪场景 着色器 SnowEffect.prototype.FragmentShader_Snow = function () { return `uniform sampler2D colorTexture; //输入的场景渲染照片 varying vec2 v_textureCoordinates; uniform float speed; float snow(vec2 uv,float scale){ float time = czm_frameNumber * speed / 1000.0 ; float w=smoothstep(1.0,0.0,-uv.y*(scale/10.0)); if(w<0.1)return 0.0; uv+=time/scale; uv.y+=time*2.0/scale; uv.x+=sin(uv.y+time*0.5)/scale; uv*=scale; vec2 s=floor(uv),f=fract(uv),p; float k=3.0,d; p=0.5+0.35*sin(11.0*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.0))-f; d=length(p);k=min(d,k); k=smoothstep(0.0,k,sin(f.x+f.y)*0.01); return k*w; } void main(void){ vec2 resolution = czm_viewport.zw; vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y); float c = 0.0; c+=snow(uv,15.); c+=snow(uv,10.); c+=snow(uv,9.); c+=snow(uv,8.); c+=snow(uv,7.); c+=snow(uv,6.); c+=snow(uv,5.); c+=snow(uv,4.); vec3 finalColor=(vec3(c)); //屏幕上雪的颜色 gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1.0), 0.5); //将雪和三维场景融合 } ` } SnowEffect.prototype.show = function (visible) { this.snowStage.enabled = visible; } SnowEffect.prototype.destroy = function (visible) { if (!this.viewer || !this.snowStage) return; this.viewer.scene.postProcessStages.remove(this.snowStage); this.snowStage.destroy(); delete this.speed } Cesium.SnowEffect = SnowEffect })(Cesium)