RainEffect.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. (function (Cesium) {
  2. function RainEffect(viewer, options) {
  3. if (!viewer) throw new Error("viewer is undefined")
  4. this.viewer = viewer;
  5. this.speed = Cesium.defaultValue(options.speed, 10)
  6. this.size = Cesium.defaultValue(options.size, 20)
  7. this.direction = Cesium.Math.toRadians(Cesium.defaultValue(options.direction, -30));
  8. this.enabled = Cesium.defaultValue(options.enabled, true)
  9. this.init();
  10. }
  11. RainEffect.prototype.init = function () {
  12. this.rainStage = new Cesium.PostProcessStage({
  13. name: 'czm_rain',
  14. fragmentShader: this.FragmentShader_Rain(),
  15. uniforms: {
  16. direction: () => { return this.direction },
  17. size: () => { return this.size; },
  18. speed: () => { return this.speed; }
  19. }
  20. });
  21. this.rainStage.enabled = this.enabled
  22. this.viewer.scene.postProcessStages.add(this.rainStage)
  23. }
  24. //定义下雨场景 着色器
  25. RainEffect.prototype.FragmentShader_Rain = function () {
  26. return `uniform sampler2D colorTexture;//下雨前输入的场景渲染照片
  27. varying vec2 v_textureCoordinates;
  28. uniform float speed;
  29. uniform float size;
  30. uniform float direction;
  31. float hash(float x){
  32. return fract(sin(x*23.3)*13.13);
  33. }
  34. void main(void){
  35. float time = czm_frameNumber * speed / 1000.0;
  36. vec2 resolution = czm_viewport.zw;
  37. vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
  38. vec3 finalColor=vec3(0.1,0.2,0.3);//粒子的颜色
  39. float si=sin(direction),co=cos(direction);
  40. uv*=mat2(co,-si,si,co);
  41. uv*=length(uv+vec2(0,4.9))*0.3+1.0;
  42. float v=1.-sin(hash(floor(uv.x*100.0))*2.0);
  43. float b=clamp(abs(sin(20.0*time*v+uv.y*(5./(2.0+v))))-.95,0.0,1.0)*size;
  44. finalColor*=v*b; //屏幕上雨的颜色
  45. gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1.0), 0.5); //将雨和三维场景融合
  46. }
  47. `
  48. }
  49. RainEffect.prototype.show = function (visible) {
  50. this.rainStage.enabled = visible;
  51. }
  52. RainEffect.prototype.destroy = function () {
  53. if (!this.viewer || !this.rainStage) return;
  54. this.viewer.scene.postProcessStages.remove(this.rainStage);
  55. this.rainStage.destroy();
  56. delete this.direction
  57. delete this.size
  58. delete this.speed
  59. }
  60. Cesium.RainEffect = RainEffect
  61. })(Cesium)