第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的粒子系统和天气系统,主要内容包括:
- 粒子系统架构:核心组件和工作原理
- 创建粒子效果:发射器、属性动画、自定义效果
- 预设粒子效果:火焰、烟雾、萤火虫、爆炸等
- 天气系统:雨天、雪天、雾天、晴天效果
- 环境效果:天空盒、日夜循环、环境光照
- 后期特效:泛光、景深、色调映射、抗锯齿
- 性能优化:对象池、LOD、质量调整
通过本章的学习,读者应该能够为3D场景添加丰富的粒子特效和天气系统,创建更加生动逼真的可视化效果。
下一章预告:第七章将介绍Astral3D的动画编辑器,包括关键帧动画、曲线编辑、动画控制器、骨骼动画等功能的使用方法。

浙公网安备 33010602011771号