|
|
@@ -1,337 +0,0 @@
|
|
|
-// 天气效果实现
|
|
|
-class WeatherEffect {
|
|
|
- constructor(viewer) {
|
|
|
- this.viewer = viewer;
|
|
|
- this.scene = viewer.scene;
|
|
|
- this.currentWeather = 'sunny'; // 默认晴天
|
|
|
- this.rainParticleSystem = null;
|
|
|
- this.snowParticleSystem = null;
|
|
|
- this.rainEffect = null;
|
|
|
- }
|
|
|
-
|
|
|
- // 设置天气类型
|
|
|
- setWeather(weatherType) {
|
|
|
- this.currentWeather = weatherType;
|
|
|
- this.clearWeatherEffects();
|
|
|
-
|
|
|
- switch (weatherType) {
|
|
|
- case 'sunny':
|
|
|
- this.setSunnyWeather();
|
|
|
- break;
|
|
|
- case 'cloudy':
|
|
|
- this.setCloudyWeather();
|
|
|
- break;
|
|
|
- case 'rain':
|
|
|
- this.setRainWeather();
|
|
|
- break;
|
|
|
- case 'snow':
|
|
|
- this.setSnowWeather();
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 清除所有天气效果
|
|
|
- clearWeatherEffects() {
|
|
|
- // 清除粒子系统
|
|
|
- if (this.rainParticleSystem) {
|
|
|
- this.scene.primitives.remove(this.rainParticleSystem);
|
|
|
- this.rainParticleSystem = null;
|
|
|
- }
|
|
|
- if (this.snowParticleSystem) {
|
|
|
- this.scene.primitives.remove(this.snowParticleSystem);
|
|
|
- this.snowParticleSystem = null;
|
|
|
- }
|
|
|
-
|
|
|
- // 清除后处理效果
|
|
|
- if (this.rainEffect) {
|
|
|
- this.rainEffect.destroy();
|
|
|
- this.rainEffect = null;
|
|
|
- }
|
|
|
-
|
|
|
- // 重置大气效果
|
|
|
- this.scene.skyAtmosphere.hueShift = 0.0;
|
|
|
- this.scene.skyAtmosphere.saturationShift = 0.0;
|
|
|
- this.scene.skyAtmosphere.brightnessShift = 0.0;
|
|
|
-
|
|
|
- // 重置光照
|
|
|
- this.scene.globe.enableLighting = true;
|
|
|
- if (this.scene.sun) {
|
|
|
- this.scene.sun.show = true;
|
|
|
- }
|
|
|
- if (this.scene.moon) {
|
|
|
- this.scene.moon.show = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置晴天效果
|
|
|
- setSunnyWeather() {
|
|
|
- this.scene.skyAtmosphere.hueShift = 0.0;
|
|
|
- this.scene.skyAtmosphere.saturationShift = 0.1;
|
|
|
- this.scene.skyAtmosphere.brightnessShift = 0.2;
|
|
|
- this.scene.globe.enableLighting = true;
|
|
|
- if (this.scene.sun) {
|
|
|
- this.scene.sun.show = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置阴天效果
|
|
|
- setCloudyWeather() {
|
|
|
- this.scene.skyAtmosphere.hueShift = 0.1;
|
|
|
- this.scene.skyAtmosphere.saturationShift = -0.3;
|
|
|
- this.scene.skyAtmosphere.brightnessShift = -0.4;
|
|
|
- this.scene.globe.enableLighting = true;
|
|
|
- if (this.scene.sun) {
|
|
|
- this.scene.sun.show = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置雨天效果
|
|
|
- setRainWeather() {
|
|
|
- this.setCloudyWeather();
|
|
|
- this.createRainEffect();
|
|
|
- }
|
|
|
-
|
|
|
- // 设置雪天效果
|
|
|
- setSnowWeather() {
|
|
|
- this.setCloudyWeather();
|
|
|
- this.createSnowEffect();
|
|
|
- }
|
|
|
-
|
|
|
- // 创建下雨效果
|
|
|
- createRainEffect() {
|
|
|
- console.log('创建雨天效果');
|
|
|
-
|
|
|
- // 尝试使用粒子系统实现雨天效果
|
|
|
- const rainParticleSize = this.scene.drawingBufferWidth / 500.0; // 进一步减小雨滴宽度
|
|
|
- const rainRadius = 4000.0;
|
|
|
- const rainImageSize = new Cesium.Cartesian2(rainParticleSize, rainParticleSize * 10.0); // 调整雨滴形状,更加细长
|
|
|
- const rainGravityScratch = new Cesium.Cartesian3();
|
|
|
-
|
|
|
- const rainUpdate = (particle, dt) => {
|
|
|
- Cesium.Cartesian3.normalize(particle.position, rainGravityScratch);
|
|
|
- Cesium.Cartesian3.multiplyByScalar(rainGravityScratch, -40, rainGravityScratch); // 增加下落速度,使雨滴更自然
|
|
|
- Cesium.Cartesian3.add(particle.position, rainGravityScratch, particle.position);
|
|
|
- const distance = Cesium.Cartesian3.distance(this.scene.camera.position, particle.position);
|
|
|
- if (distance > rainRadius) {
|
|
|
- particle.endColor.alpha = 0.0;
|
|
|
- } else {
|
|
|
- particle.endColor.alpha = this.rainParticleSystem.endColor.alpha / (distance / rainRadius + 0.1);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // 创建雨滴粒子系统
|
|
|
- const rainColor = new Cesium.Color(0.5, 0.6, 0.7, 0.4); // 调整为更暗的雨水颜色,增加透明度
|
|
|
- console.log('雨滴颜色:', rainColor);
|
|
|
-
|
|
|
- // 使用与雪天相同的纹理,确保显示
|
|
|
- const rainTexture = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iNSIgY3k9IjUiIHI9IjUiIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC43Ii8+PC9zdmc+';
|
|
|
-
|
|
|
- this.rainParticleSystem = new Cesium.ParticleSystem({
|
|
|
- modelMatrix: new Cesium.Matrix4.fromTranslation(this.scene.camera.position),
|
|
|
- speed: -1.0,
|
|
|
- lifetime: 10.0, // 减少生命周期,使雨滴更密集
|
|
|
- emitter: new Cesium.SphereEmitter(rainRadius),
|
|
|
- startScale: 1.0,
|
|
|
- endScale: 1.0,
|
|
|
- image: rainTexture,
|
|
|
- emissionRate: 5000.0, // 增加粒子数量,使雨更密集
|
|
|
- startColor: rainColor,
|
|
|
- endColor: rainColor,
|
|
|
- imageSize: rainImageSize,
|
|
|
- updateCallback: rainUpdate,
|
|
|
- performance: false,
|
|
|
- });
|
|
|
-
|
|
|
- this.scene.primitives.add(this.rainParticleSystem);
|
|
|
- this.rainParticleSystem.lodRangeScale = 10000;
|
|
|
-
|
|
|
- // 参考示例,添加相机位置监听,确保粒子系统跟随相机移动
|
|
|
- this.scene.camera.changed.addEventListener(() => {
|
|
|
- if (this.rainParticleSystem) {
|
|
|
- const modelMatrix = new Cesium.Matrix4.fromTranslation(this.scene.camera.position);
|
|
|
- this.rainParticleSystem.modelMatrix = modelMatrix;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- console.log('雨天效果创建完成,粒子系统数量:', this.scene.primitives.length);
|
|
|
- console.log('粒子系统颜色设置:', {
|
|
|
- startColor: this.rainParticleSystem.startColor,
|
|
|
- endColor: this.rainParticleSystem.endColor
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 创建下雪效果
|
|
|
- createSnowEffect() {
|
|
|
- const snowParticleSize = this.scene.drawingBufferWidth / 150.0; // 减小雪花大小
|
|
|
- const snowRadius = 4000.0;
|
|
|
- const snowImageSize = new Cesium.Cartesian2(snowParticleSize, snowParticleSize);
|
|
|
- const snowGravityScratch = new Cesium.Cartesian3();
|
|
|
-
|
|
|
- const snowUpdate = (particle, dt) => {
|
|
|
- Cesium.Cartesian3.normalize(particle.position, snowGravityScratch);
|
|
|
- Cesium.Cartesian3.multiplyByScalar(snowGravityScratch, -15, snowGravityScratch); // 减慢下落速度
|
|
|
- Cesium.Cartesian3.add(particle.position, snowGravityScratch, particle.position);
|
|
|
- const distance = Cesium.Cartesian3.distance(this.scene.camera.position, particle.position);
|
|
|
- if (distance > snowRadius) {
|
|
|
- particle.endColor.alpha = 0.0;
|
|
|
- } else {
|
|
|
- particle.endColor.alpha = this.snowParticleSystem.endColor.alpha / (distance / snowRadius + 0.1);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // 创建雪花粒子系统
|
|
|
- const snowColor = Cesium.Color.WHITE.withAlpha(0.7); // 按照用户要求设置
|
|
|
- console.log('雪花颜色:', snowColor);
|
|
|
-
|
|
|
- // 使用更适合的雪花纹理
|
|
|
- const snowTexture = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iNSIgY3k9IjUiIHI9IjUiIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC43Ii8+PC9zdmc+';
|
|
|
-
|
|
|
- this.snowParticleSystem = new Cesium.ParticleSystem({
|
|
|
- modelMatrix: new Cesium.Matrix4.fromTranslation(this.scene.camera.position),
|
|
|
- speed: -1.0,
|
|
|
- lifetime: 20.0, // 增加生命周期,使雪花飘落更自然
|
|
|
- emitter: new Cesium.SphereEmitter(snowRadius),
|
|
|
- startScale: 0.8,
|
|
|
- endScale: 1.2, // 增加大小变化,使雪花更自然
|
|
|
- image: snowTexture,
|
|
|
- emissionRate: 3000.0, // 增加粒子数量,使雪更密集
|
|
|
- startColor: snowColor,
|
|
|
- endColor: snowColor,
|
|
|
- imageSize: snowImageSize,
|
|
|
- updateCallback: snowUpdate,
|
|
|
- performance: false,
|
|
|
- });
|
|
|
-
|
|
|
- this.scene.primitives.add(this.snowParticleSystem);
|
|
|
- this.snowParticleSystem.lodRangeScale = 10000;
|
|
|
-
|
|
|
- // 参考示例,添加相机位置监听,确保粒子系统跟随相机移动
|
|
|
- this.scene.camera.changed.addEventListener(() => {
|
|
|
- if (this.snowParticleSystem) {
|
|
|
- const modelMatrix = new Cesium.Matrix4.fromTranslation(this.scene.camera.position);
|
|
|
- this.snowParticleSystem.modelMatrix = modelMatrix;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- console.log('雪天效果创建完成,粒子系统数量:', this.scene.primitives.length);
|
|
|
- console.log('粒子系统颜色设置:', {
|
|
|
- startColor: this.snowParticleSystem.startColor,
|
|
|
- endColor: this.snowParticleSystem.endColor
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 获取当前天气类型
|
|
|
- getCurrentWeather() {
|
|
|
- return this.currentWeather;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 后处理阶段实现的雨天效果
|
|
|
-class RainEffect {
|
|
|
- constructor(viewer, options) {
|
|
|
- console.log('初始化 RainEffect');
|
|
|
- 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.1); // 雨滴大小
|
|
|
- this.rainSpeed = Cesium.defaultValue(options.rainSpeed, 1000.0); // 雨速
|
|
|
- this.rainIntensity = Cesium.defaultValue(options.rainIntensity, 1.0); // 雨的强度
|
|
|
- this.viewer = viewer;
|
|
|
- console.log('RainEffect 初始化参数:', { tiltAngle: this.tiltAngle, rainSize: this.rainSize, rainSpeed: this.rainSpeed, rainIntensity: this.rainIntensity });
|
|
|
- this.init();
|
|
|
- }
|
|
|
-
|
|
|
- init() {
|
|
|
- console.log('创建后处理阶段');
|
|
|
- this.rainStage = new Cesium.PostProcessStage({
|
|
|
- name: "czml_rain",
|
|
|
- fragmentShader: this.rain(),
|
|
|
- uniforms: {
|
|
|
- tiltAngle: () => this.tiltAngle,
|
|
|
- rainSize: () => this.rainSize,
|
|
|
- rainSpeed: () => this.rainSpeed,
|
|
|
- rainIntensity: () => this.rainIntensity,
|
|
|
- time: () => performance.now() * 0.001
|
|
|
- },
|
|
|
- });
|
|
|
- console.log('后处理阶段创建完成:', this.rainStage);
|
|
|
- this.viewer.scene.postProcessStages.add(this.rainStage);
|
|
|
- console.log('后处理阶段添加到场景:', this.viewer.scene.postProcessStages.length);
|
|
|
- }
|
|
|
-
|
|
|
- rain() {
|
|
|
- return `
|
|
|
- uniform sampler2D colorTexture;
|
|
|
- varying vec2 v_textureCoordinates;
|
|
|
- uniform float tiltAngle;
|
|
|
- uniform float rainSize;
|
|
|
- uniform float rainSpeed;
|
|
|
- uniform float rainIntensity;
|
|
|
- uniform float time;
|
|
|
-
|
|
|
- // 随机函数
|
|
|
- float random(vec2 st) {
|
|
|
- return fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453123);
|
|
|
- }
|
|
|
-
|
|
|
- void main(void) {
|
|
|
- vec4 color = texture2D(colorTexture, v_textureCoordinates);
|
|
|
-
|
|
|
- // 计算雨滴位置
|
|
|
- float t = time * rainSpeed;
|
|
|
- float rainDensity = 0.02 * rainIntensity;
|
|
|
-
|
|
|
- // 倾斜角度
|
|
|
- float angle = tiltAngle;
|
|
|
- mat2 rotation = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
|
|
|
-
|
|
|
- // 雨滴效果
|
|
|
- vec2 uv = v_textureCoordinates * 10.0;
|
|
|
- uv = rotation * uv;
|
|
|
- uv.y += t * 0.01;
|
|
|
-
|
|
|
- // 创建雨滴
|
|
|
- float rain = 0.0;
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- vec2 grid = fract(uv * vec2(1.0, 20.0)) - 0.5;
|
|
|
- float d = length(grid);
|
|
|
- float size = rainSize * (1.0 + float(i) * 0.5);
|
|
|
- float fade = smoothstep(size, size * 0.5, d);
|
|
|
- rain += fade;
|
|
|
- uv *= 1.5;
|
|
|
- }
|
|
|
-
|
|
|
- // 应用雨滴效果
|
|
|
- rain *= rainDensity;
|
|
|
- color.rgb *= (1.0 - rain * 0.5);
|
|
|
- color.rgb += rain * vec3(0.5, 0.6, 0.7); // 雨滴的颜色
|
|
|
-
|
|
|
- gl_FragColor = color;
|
|
|
- }
|
|
|
- `;
|
|
|
- }
|
|
|
-
|
|
|
- // 显示雨天效果
|
|
|
- show() {
|
|
|
- if (this.rainStage) {
|
|
|
- this.rainStage.enabled = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 隐藏雨天效果
|
|
|
- hide() {
|
|
|
- if (this.rainStage) {
|
|
|
- this.rainStage.enabled = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 销毁雨天效果
|
|
|
- destroy() {
|
|
|
- if (this.rainStage) {
|
|
|
- this.viewer.scene.postProcessStages.remove(this.rainStage);
|
|
|
- this.rainStage = null;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export default WeatherEffect;
|