第06章-粒子系统与天气系统

第六章:粒子系统与天气系统

6.1 粒子系统概述

Astral3D内置了强大的粒子系统,可以创建各种视觉特效,如火焰、烟雾、雨雪、萤火虫、爆炸等效果,为3D场景增添生动的动态元素。

6.1.1 粒子系统架构

┌─────────────────────────────────────────────────────────────────┐
│                        粒子系统架构                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                  ParticleSystemManager                   │   │
│  │               (粒子系统管理器)                            │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│           ┌───────────────┼───────────────┐                    │
│           ▼               ▼               ▼                    │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐              │
│  │  Emitter    │ │  Emitter    │ │  Emitter    │              │
│  │  发射器     │ │  发射器     │ │  发射器     │              │
│  └─────────────┘ └─────────────┘ └─────────────┘              │
│        │               │               │                       │
│        ▼               ▼               ▼                       │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    Particles Pool                        │   │
│  │                   (粒子对象池)                            │   │
│  │  [●][●][●][●][●][●][●][●][●][●][●][●][●][●][●][●]      │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    GPU Renderer                          │   │
│  │                  (GPU渲染器)                             │   │
│  │      Points | Sprites | InstancedMesh | Custom Shader   │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

6.1.2 核心组件

组件 说明
ParticleSystem 粒子系统主类
Emitter 粒子发射器
Particle 单个粒子对象
ParticleRenderer 粒子渲染器
ParticleModifier 粒子修改器(力场、颜色变化等)

6.2 创建粒子效果

6.2.1 基础粒子系统

import { ParticleSystem, ParticleEmitter } from '@astral3d/engine';

// 创建粒子系统
const particleSystem = new ParticleSystem({
  name: '火焰效果',
  maxParticles: 1000,
  duration: -1,  // -1表示持续循环
});

// 创建发射器
const emitter = new ParticleEmitter({
  // 发射形状
  shape: 'point',  // point, sphere, box, cone, circle
  position: new THREE.Vector3(0, 0, 0),
  
  // 发射参数
  rate: 50,        // 每秒发射50个粒子
  burstCount: 0,   // 单次爆发数量
  burstInterval: 0,
  
  // 粒子生命
  lifetime: { min: 1, max: 2 },  // 1-2秒
  
  // 初始速度
  speed: { min: 1, max: 3 },
  direction: new THREE.Vector3(0, 1, 0),
  spread: 30,  // 扩散角度
  
  // 初始大小
  size: { min: 0.1, max: 0.3 },
  
  // 初始颜色
  color: new THREE.Color(0xff6600),
  
  // 初始透明度
  opacity: { min: 0.8, max: 1.0 }
});

particleSystem.addEmitter(emitter);
viewer.scene.add(particleSystem);

6.2.2 发射器形状

// 点发射器
const pointEmitter = {
  shape: 'point',
  position: new THREE.Vector3(0, 0, 0)
};

// 球形发射器
const sphereEmitter = {
  shape: 'sphere',
  position: new THREE.Vector3(0, 0, 0),
  radius: 1,
  radiusRange: 0.5  // 内部空心半径
};

// 立方体发射器
const boxEmitter = {
  shape: 'box',
  position: new THREE.Vector3(0, 0, 0),
  size: new THREE.Vector3(2, 2, 2)
};

// 圆锥发射器
const coneEmitter = {
  shape: 'cone',
  position: new THREE.Vector3(0, 0, 0),
  radius: 1,
  angle: 45,  // 圆锥角度
  height: 2
};

// 圆形发射器
const circleEmitter = {
  shape: 'circle',
  position: new THREE.Vector3(0, 0, 0),
  radius: 2,
  radiusRange: 0,  // 0表示边缘发射,1表示整个圆面
  arc: 360  // 发射弧度
};

// 网格发射器
const meshEmitter = {
  shape: 'mesh',
  mesh: someThreeJSMesh,
  emitFrom: 'surface'  // surface, volume, edge, vertex
};

6.2.3 粒子属性动画

// 大小随时间变化
const sizeOverLifetime = {
  enabled: true,
  curve: [
    { time: 0, value: 0.1 },
    { time: 0.5, value: 0.3 },
    { time: 1, value: 0 }
  ]
};

// 颜色随时间变化
const colorOverLifetime = {
  enabled: true,
  gradient: [
    { time: 0, color: new THREE.Color(0xffff00) },   // 黄色
    { time: 0.3, color: new THREE.Color(0xff6600) }, // 橙色
    { time: 0.7, color: new THREE.Color(0xff0000) }, // 红色
    { time: 1, color: new THREE.Color(0x330000) }    // 深红
  ]
};

// 透明度随时间变化
const opacityOverLifetime = {
  enabled: true,
  curve: [
    { time: 0, value: 0 },
    { time: 0.1, value: 1 },
    { time: 0.8, value: 1 },
    { time: 1, value: 0 }
  ]
};

// 速度随时间变化
const velocityOverLifetime = {
  enabled: true,
  linear: {
    x: 0,
    y: { min: -0.5, max: 0.5 },  // 随机抖动
    z: 0
  },
  orbital: {
    x: 0,
    y: 1,  // 绕Y轴旋转
    z: 0
  }
};

// 旋转随时间变化
const rotationOverLifetime = {
  enabled: true,
  angularVelocity: { min: -180, max: 180 }  // 度/秒
};

// 应用到粒子系统
particleSystem.setSizeOverLifetime(sizeOverLifetime);
particleSystem.setColorOverLifetime(colorOverLifetime);
particleSystem.setOpacityOverLifetime(opacityOverLifetime);
particleSystem.setVelocityOverLifetime(velocityOverLifetime);
particleSystem.setRotationOverLifetime(rotationOverLifetime);

6.3 预设粒子效果

6.3.1 火焰效果

import { ParticlePresets } from '@astral3d/engine';

// 使用预设火焰
const fire = ParticlePresets.fire({
  position: new THREE.Vector3(0, 0, 0),
  scale: 1,
  intensity: 1
});

viewer.scene.add(fire);

// 自定义火焰配置
const customFire = new ParticleSystem({
  name: 'CustomFire',
  maxParticles: 500,
  emitter: {
    shape: 'cone',
    radius: 0.3,
    angle: 20,
    rate: 100,
    lifetime: { min: 0.5, max: 1.5 },
    speed: { min: 1, max: 3 },
    size: { min: 0.1, max: 0.4 }
  },
  sizeOverLifetime: {
    curve: [
      { time: 0, value: 0.5 },
      { time: 0.3, value: 1 },
      { time: 1, value: 0 }
    ]
  },
  colorOverLifetime: {
    gradient: [
      { time: 0, color: 0xffff00 },
      { time: 0.3, color: 0xff6600 },
      { time: 0.7, color: 0xff0000 },
      { time: 1, color: 0x000000 }
    ]
  },
  blending: THREE.AdditiveBlending,
  texture: 'textures/particles/flame.png'
});

6.3.2 烟雾效果

// 烟雾预设
const smoke = ParticlePresets.smoke({
  position: new THREE.Vector3(0, 0, 0),
  color: 0x444444,
  scale: 1,
  density: 0.5
});

// 自定义烟雾
const customSmoke = new ParticleSystem({
  name: 'Smoke',
  maxParticles: 200,
  emitter: {
    shape: 'circle',
    radius: 0.5,
    rate: 20,
    lifetime: { min: 3, max: 5 },
    speed: { min: 0.3, max: 0.8 },
    size: { min: 0.5, max: 1.5 },
    direction: new THREE.Vector3(0, 1, 0),
    spread: 45
  },
  sizeOverLifetime: {
    curve: [
      { time: 0, value: 0.3 },
      { time: 1, value: 1 }
    ]
  },
  opacityOverLifetime: {
    curve: [
      { time: 0, value: 0 },
      { time: 0.1, value: 0.3 },
      { time: 0.8, value: 0.3 },
      { time: 1, value: 0 }
    ]
  },
  colorOverLifetime: {
    gradient: [
      { time: 0, color: 0x333333 },
      { time: 1, color: 0x888888 }
    ]
  },
  blending: THREE.NormalBlending,
  texture: 'textures/particles/smoke.png',
  depthWrite: false
});

6.3.3 萤火虫效果

// 萤火虫预设
const fireflies = ParticlePresets.fireflies({
  position: new THREE.Vector3(0, 1, 0),
  count: 50,
  area: new THREE.Vector3(10, 5, 10)
});

// 自定义萤火虫
const customFireflies = new ParticleSystem({
  name: 'Fireflies',
  maxParticles: 100,
  emitter: {
    shape: 'box',
    size: new THREE.Vector3(20, 5, 20),
    rate: 5,
    lifetime: { min: 5, max: 10 },
    speed: { min: 0.1, max: 0.3 },
    size: { min: 0.02, max: 0.05 },
    color: new THREE.Color(0xffff88)
  },
  velocityOverLifetime: {
    linear: {
      x: { min: -0.2, max: 0.2 },
      y: { min: -0.1, max: 0.1 },
      z: { min: -0.2, max: 0.2 }
    }
  },
  opacityOverLifetime: {
    curve: [
      { time: 0, value: 0 },
      { time: 0.2, value: 1 },
      { time: 0.4, value: 0.3 },
      { time: 0.6, value: 1 },
      { time: 0.8, value: 0.3 },
      { time: 1, value: 0 }
    ]
  },
  blending: THREE.AdditiveBlending,
  texture: 'textures/particles/glow.png'
});

6.3.4 爆炸效果

// 爆炸预设
function createExplosion(position) {
  const explosion = new ParticleSystem({
    name: 'Explosion',
    maxParticles: 500,
    duration: 2,  // 2秒后自动销毁
    
    emitter: {
      shape: 'sphere',
      radius: 0.1,
      rate: 0,
      burstCount: 300,  // 一次性发射
      burstInterval: 0,
      lifetime: { min: 0.5, max: 2 },
      speed: { min: 5, max: 15 },
      size: { min: 0.1, max: 0.5 },
      position: position
    },
    
    sizeOverLifetime: {
      curve: [
        { time: 0, value: 1 },
        { time: 0.3, value: 1.5 },
        { time: 1, value: 0 }
      ]
    },
    
    colorOverLifetime: {
      gradient: [
        { time: 0, color: 0xffffff },
        { time: 0.1, color: 0xffff00 },
        { time: 0.3, color: 0xff6600 },
        { time: 0.6, color: 0xff0000 },
        { time: 1, color: 0x000000 }
      ]
    },
    
    velocityOverLifetime: {
      linear: {
        x: 0,
        y: -5,  // 重力
        z: 0
      },
      damping: 0.95  // 阻尼
    },
    
    blending: THREE.AdditiveBlending
  });
  
  viewer.scene.add(explosion);
  
  // 2秒后自动移除
  setTimeout(() => {
    viewer.scene.remove(explosion);
    explosion.dispose();
  }, 2000);
}

// 使用
createExplosion(new THREE.Vector3(0, 5, 0));

6.4 天气系统

Astral3D提供了完整的天气系统,可以模拟晴天、雨天、雪天、雾天等各种天气效果。

6.4.1 天气系统架构

import { WeatherSystem } from '@astral3d/engine';

// 创建天气系统
const weather = new WeatherSystem(viewer);

// 天气系统配置
interface WeatherConfig {
  type: 'clear' | 'rain' | 'snow' | 'fog' | 'cloudy';
  intensity: number;  // 强度 0-1
  windSpeed: number;  // 风速
  windDirection: THREE.Vector3;  // 风向
}

6.4.2 雨天效果

// 设置雨天
weather.setWeather({
  type: 'rain',
  intensity: 0.7,     // 中等强度
  windSpeed: 2,       // 轻风
  windDirection: new THREE.Vector3(1, 0, 0)
});

// 雨天详细配置
weather.setRain({
  // 雨滴参数
  count: 10000,       // 雨滴数量
  speed: { min: 10, max: 15 },  // 下落速度
  size: { min: 0.02, max: 0.05 },  // 雨滴大小
  length: 0.5,        // 雨滴长度(拖尾)
  color: 0xaaaaff,    // 雨滴颜色
  opacity: 0.6,       // 透明度
  
  // 范围
  area: new THREE.Vector3(100, 50, 100),  // 降雨区域
  
  // 地面效果
  ripples: true,      // 水波纹
  splashes: true,     // 水花
  puddles: false,     // 水坑
  
  // 环境效果
  fog: true,          // 添加雾气
  fogDensity: 0.002,
  darken: 0.3,        // 环境变暗
  
  // 声音
  sound: true,
  soundVolume: 0.5
});

6.4.3 雪天效果

// 设置雪天
weather.setWeather({
  type: 'snow',
  intensity: 0.5,
  windSpeed: 1,
  windDirection: new THREE.Vector3(0.5, 0, 0.5)
});

// 雪天详细配置
weather.setSnow({
  // 雪花参数
  count: 5000,
  speed: { min: 0.5, max: 2 },
  size: { min: 0.05, max: 0.15 },
  rotation: true,     // 雪花旋转
  color: 0xffffff,
  opacity: 0.8,
  
  // 范围
  area: new THREE.Vector3(100, 50, 100),
  
  // 飘动效果
  turbulence: 0.5,    // 湍流强度
  swirl: true,        // 漩涡效果
  
  // 地面效果
  accumulation: true,  // 积雪
  accumulationRate: 0.001,  // 积雪速率
  
  // 环境效果
  fog: true,
  fogColor: 0xeeeeee,
  brighten: 0.1       // 环境变亮
});

6.4.4 雾天效果

// 设置雾天
weather.setWeather({
  type: 'fog',
  intensity: 0.6
});

// 雾效详细配置
weather.setFog({
  // 雾类型
  fogType: 'exponential',  // linear, exponential, exponential2
  
  // 线性雾参数
  near: 10,
  far: 100,
  
  // 指数雾参数
  density: 0.01,
  
  // 颜色
  color: 0xcccccc,
  
  // 体积雾
  volumetric: true,
  noiseScale: 0.5,
  noiseSpeed: 0.1,
  
  // 高度雾
  heightFog: true,
  fogTop: 20,
  fogBottom: 0,
  
  // 动态变化
  animate: true,
  flowDirection: new THREE.Vector3(1, 0, 0),
  flowSpeed: 0.5
});

6.4.5 晴天效果

// 设置晴天
weather.setWeather({
  type: 'clear',
  intensity: 1
});

// 晴天详细配置
weather.setClear({
  // 天空
  skyColor: 0x87CEEB,
  horizonColor: 0xffffff,
  
  // 太阳
  sunPosition: { azimuth: 45, elevation: 60 },
  sunIntensity: 1.5,
  sunColor: 0xffffd0,
  
  // 光晕
  lensFlare: true,
  lensFlareIntensity: 0.5,
  
  // 云
  clouds: true,
  cloudCoverage: 0.2,
  cloudSpeed: 0.5,
  
  // 环境光
  ambientIntensity: 0.4,
  
  // 阴影
  shadows: true,
  shadowIntensity: 0.7
});

6.4.6 天气过渡

// 平滑过渡到新天气
weather.transition({
  type: 'rain',
  intensity: 0.8
}, {
  duration: 5000,     // 5秒过渡
  easing: 'easeInOut'
});

// 自定义过渡
await weather.transitionTo('snow', 3000);

// 天气变化事件
weather.on('weatherChange', (oldWeather, newWeather) => {
  console.log(`天气从 ${oldWeather.type} 变为 ${newWeather.type}`);
});

6.5 环境效果

6.5.1 天空盒

import { SkyBox } from '@astral3d/engine';

// 使用预设天空
const sky = new SkyBox({
  type: 'procedural',  // procedural, cubemap, equirectangular
  
  // 程序化天空参数
  turbidity: 10,       // 浑浊度
  rayleigh: 2,         // 瑞利散射
  mieCoefficient: 0.005,
  mieDirectionalG: 0.8,
  sunPosition: { azimuth: 180, elevation: 45 }
});

viewer.scene.add(sky);

// 使用立方体贴图
const cubeMapSky = new SkyBox({
  type: 'cubemap',
  textures: [
    'skybox/px.jpg', 'skybox/nx.jpg',
    'skybox/py.jpg', 'skybox/ny.jpg',
    'skybox/pz.jpg', 'skybox/nz.jpg'
  ]
});

// 使用全景图
const panoramaSky = new SkyBox({
  type: 'equirectangular',
  texture: 'skybox/panorama.hdr'
});

6.5.2 日夜循环

import { DayNightCycle } from '@astral3d/engine';

// 创建日夜循环
const dayNight = new DayNightCycle({
  // 时间设置
  startTime: 12,      // 开始时间(小时)
  speed: 60,          // 速度(1表示实时,60表示1分钟=1小时)
  
  // 太阳设置
  sunDistance: 1000,
  sunIntensity: { day: 1.5, night: 0 },
  sunColor: { day: 0xffffd0, night: 0xff8844 },
  
  // 月亮设置
  moonEnabled: true,
  moonDistance: 800,
  moonIntensity: 0.3,
  moonPhase: 0.5,     // 月相 0-1
  
  // 环境光
  ambientLight: { day: 0x404080, night: 0x101030 },
  ambientIntensity: { day: 0.4, night: 0.1 },
  
  // 雾
  fogColor: { day: 0xc0d0e0, night: 0x101020 },
  fogDensity: { day: 0.0005, night: 0.001 },
  
  // 回调
  onTimeChange: (time) => {
    console.log(`当前时间: ${time.toFixed(1)}:00`);
  }
});

viewer.add(dayNight);

// 控制时间
dayNight.setTime(18);  // 设置为18:00
dayNight.pause();      // 暂停
dayNight.resume();     // 继续
dayNight.setSpeed(120); // 2分钟=1小时

6.5.3 环境光照

// HDR环境光
import { HDREnvironment } from '@astral3d/engine';

const hdrEnv = new HDREnvironment({
  texture: 'environment/studio.hdr',
  intensity: 1,
  rotation: 0,
  blur: 0
});

viewer.scene.environment = hdrEnv.texture;
viewer.scene.background = hdrEnv.texture;

// 动态环境反射
const dynamicEnv = new DynamicEnvironment({
  resolution: 256,
  updateInterval: 100,  // 毫秒
  position: new THREE.Vector3(0, 1, 0)
});

// 应用到特定对象
reflectiveObject.material.envMap = dynamicEnv.cubeTexture;

6.6 后期特效

6.6.1 泛光效果

import { BloomEffect } from '@astral3d/engine';

const bloom = new BloomEffect({
  intensity: 1,
  threshold: 0.8,     // 亮度阈值
  smoothWidth: 0.01,  // 过渡宽度
  radius: 0.4,        // 扩散半径
  
  // 高级设置
  levels: 5,          // MipMap级别
  blendMode: 'add'    // 混合模式
});

viewer.addEffect(bloom);

// 选择性泛光(只对特定对象)
const selectiveBloom = new BloomEffect({
  intensity: 2,
  selective: true,
  selectionLayer: 1   // 在layer 1的对象才有泛光
});

// 设置对象到泛光层
glowingObject.layers.enable(1);

6.6.2 景深效果

import { DepthOfFieldEffect } from '@astral3d/engine';

const dof = new DepthOfFieldEffect({
  focusDistance: 10,  // 焦点距离
  focalLength: 0.05,  // 焦距
  bokehScale: 2,      // 散景大小
  
  // 自动对焦
  autoFocus: true,
  autoFocusTarget: 'center',  // center, cursor, object
  
  // 高级设置
  rings: 3,
  samples: 4,
  showFocus: false    // 显示焦点范围
});

viewer.addEffect(dof);

// 聚焦到对象
dof.focusOnObject(targetObject);

6.6.3 色调映射

import { ToneMappingEffect } from '@astral3d/engine';

const toneMapping = new ToneMappingEffect({
  // 色调映射类型
  type: 'ACES',  // Linear, Reinhard, Cineon, ACES, AGX
  
  // 曝光
  exposure: 1,
  
  // 对比度
  contrast: 1,
  
  // 饱和度
  saturation: 1,
  
  // 色温
  temperature: 0,  // -1到1
  tint: 0,
  
  // 暗角
  vignette: 0.3,
  vignetteOffset: 0
});

viewer.addEffect(toneMapping);

6.6.4 抗锯齿

import { AntiAliasEffect } from '@astral3d/engine';

// FXAA(快速近似抗锯齿)
const fxaa = new AntiAliasEffect({
  type: 'FXAA',
  quality: 'high'  // low, medium, high
});

// SMAA(子像素形态抗锯齿)
const smaa = new AntiAliasEffect({
  type: 'SMAA',
  preset: 'ultra'  // low, medium, high, ultra
});

// TAA(时间抗锯齿)
const taa = new AntiAliasEffect({
  type: 'TAA',
  samples: 8,
  blend: 0.9
});

viewer.addEffect(smaa);

6.7 性能优化

6.7.1 粒子系统优化

// 对象池复用
particleSystem.setPooling({
  enabled: true,
  initialSize: 1000,
  growSize: 500
});

// LOD设置
particleSystem.setLOD({
  enabled: true,
  distances: [50, 100, 200],
  reductions: [1, 0.5, 0.25, 0.1]  // 粒子数量比例
});

// 视锥裁剪
particleSystem.frustumCulled = true;

// GPU实例化
particleSystem.useInstancing = true;

// 限制更新频率
particleSystem.updateFrequency = 30;  // 30fps更新

6.7.2 天气系统优化

// 动态质量调整
weather.setQuality({
  auto: true,          // 自动调整
  targetFPS: 60,
  minQuality: 0.3,
  maxQuality: 1
});

// 距离裁剪
weather.setRenderDistance({
  rain: 100,
  snow: 100,
  fog: 500
});

// 禁用不必要的效果
weather.setFeatures({
  ripples: false,
  splashes: false,
  volumetricFog: false
});

6.7.3 后期特效优化

// 降低分辨率
viewer.setEffectResolution(0.75);  // 75%分辨率

// 禁用不必要的特效
viewer.removeEffect(dof);

// 动态特效
if (viewer.fps < 30) {
  bloom.intensity = 0.5;
  dof.enabled = false;
}

6.8 本章小结

本章详细介绍了Astral3D的粒子系统和天气系统,主要内容包括:

  1. 粒子系统架构:核心组件和工作原理
  2. 创建粒子效果:发射器、属性动画、自定义效果
  3. 预设粒子效果:火焰、烟雾、萤火虫、爆炸等
  4. 天气系统:雨天、雪天、雾天、晴天效果
  5. 环境效果:天空盒、日夜循环、环境光照
  6. 后期特效:泛光、景深、色调映射、抗锯齿
  7. 性能优化:对象池、LOD、质量调整

通过本章的学习,读者应该能够为3D场景添加丰富的粒子特效和天气系统,创建更加生动逼真的可视化效果。


下一章预告:第七章将介绍Astral3D的动画编辑器,包括关键帧动画、曲线编辑、动画控制器、骨骼动画等功能的使用方法。


posted @ 2026-01-10 13:17  我才是银古  阅读(10)  评论(0)    收藏  举报