threejs模拟太阳系
基于 Three.js 构建的交互式太阳系3D可视化页面,支持多语言、丰富的交互功能和视觉效果。
太阳系页面 (Solar System)
目录结构
1 | |
架构说明
1. 主页面 (SolarSystem.vue)
负责 UI 层面的控制,包括:
- 状态管理: 配置面板、导航面板、信息面板的显示状态
- 交互控制: 速度调节、显示开关、语言切换
- 事件处理: 天体点击、跟随模式、焦点切换
2. 场景核心 (SolarSystemScene.ts)
基于 Three.js 的 3D 场景实现,包含:
- 渲染系统: WebGL 渲染器、相机、轨道控制器
- 天体系统: 太阳、行星、卫星、彗星、矮行星
- 特效系统: 星空背景、银河系、河外星系、星座连线
- 标签系统: CSS2DRenderer 实现的 HTML 标签
3. 数据配置 (planetData.ts)
定义所有天体的物理参数和显示信息:
- 行星数据:半径、距离、公转周期、轨道倾角
- 卫星数据:各行星的卫星配置
- 彗星数据:轨道参数和周期
- 其他天体:黑洞、小行星带、柯伊伯带
功能特性
交互操作
| 操作 | 桌面端 | 移动端 |
|---|---|---|
| 旋转视角 | 左键拖动 | 单指滑动 |
| 平移视角 | 右键拖动 | 双指滑动 |
| 缩放 | 滚轮 | 双指捏合 |
| 查看信息 | 点击天体 | 点击天体 |
配置面板
- 语言切换: 中文 / English
- 速度控制: 0.1x ~ 100x 时间流速
- 显示设置:
- 彗星显示/隐藏
- 卫星显示/隐藏(月球始终显示)
- 标签显示/隐藏
- 银河系显示/隐藏
- 河外星系显示/隐藏
- 星座连线显示/隐藏
- 地球云层显示/隐藏
- 地球夜晚模式切换
- 金星云层显示/隐藏
导航面板
快速定位到指定天体:
- 全景: 重置视角
- 恒星: 太阳
- 行星: 水星、金星、地球、火星、木星、土星、天王星、海王星、冥王星
- 彗星: 哈雷彗星、恩克彗星、斯威夫特-塔特尔彗星等
- 其他: 黑洞、小行星带、柯伊伯带
信息面板
点击天体后显示详细信息:
- 天体名称(中英文)
- 物理参数(直径、距离、周期等)
- 科学描述
- 跟随模式开关
跟随模式
开启后相机将跟随选中天体运动,保持相对距离。
纹理系统
纹理路径
1 | |
纹理加载
- 预加载机制:启动时批量加载所有纹理
- 进度显示:加载进度实时更新
- 降级处理:纹理加载失败时使用程序生成纹理
天体特效
太阳
- 自发光材质
- 动态光晕效果
- 脉动动画
行星
- 真实纹理映射
- 轨道运动动画
- 自转动画
- 光晕效果
土星环
- 优先使用纹理渲染
- 降级为粒子系统
- 独立旋转动画
地球
- 可切换白天/夜晚纹理
- 可叠加云层效果
彗星
- 椭圆轨道运动
- 彗尾粒子效果
- 近日点/远日点计算
星空背景
- 随机分布的背景星点
- 闪烁动画效果
- 银河系粒子云
- 河外星系光点
- 星座连线和标签
国际化
支持中英文双语切换:
- 所有 UI 文本
- 天体名称
- 信息描述
- 操作提示
性能优化
- 纹理预加载
- 粒子系统数量控制
- 视锥剔除
- 材质复用
- requestAnimationFrame 动画循环
Three.js 特性与实现
整个太阳系场景约 4000 行 TypeScript,用到的 Three.js 能力可以按”渲染对象 → 材质 → 交互”三层来看。
粒子系统(THREE.Points + BufferGeometry)
粒子是本模块使用最密集的特性,共用 25 处 THREE.Points:
- 星空背景:三层不同距离的星层,每层是一个
BufferGeometry+Float32BufferAttribute位置数组 - 小行星带 / 柯伊伯带:数千粒子沿环形分布,
PointsMaterial控制大小与透明度 - 彗尾:离子尾 + 尘埃尾两组粒子,随彗星位置实时更新顶点坐标(
position.needsUpdate = true) - 银河系 / 河外星系:银河用粒子云盘模拟旋臂,河外星系是远处的小粒子团
所有粒子共享一个优化技巧:blending: THREE.AdditiveBlending(加法混合),让重叠的粒子自然叠加发亮,是低成本做出”发光体”感的关键。
自定义着色器(THREE.ShaderMaterial)
背景星星的闪烁效果没有用 CSS 或 JS 逐帧改透明度,而是三层星空各配一个 ShaderMaterial,在 GLSL 顶点/片元着色器里按时间做正弦透明度脉动,所有闪烁材质集中管理。相比逐帧更新 JS 对象属性,着色器跑在 GPU 上,几千颗星星同时闪烁也不产生 CPU 开销。
程序化纹理(THREE.CanvasTexture)
纹理加载失败时的降级方案:用 2D Canvas 程序化生成纹理(渐变、噪点、条纹)再包成 CanvasTexture 贴图,保证断网或纹理 404 时每个天体依然有可辨识的外观,而不是黑球。
渲染与光照
- WebGLRenderer + PerspectiveCamera:标准渲染管线,窗口 resize 时同步宽高比
- 光照组合:太阳用
PointLight(点光源,照亮所有行星的朝日面),辅以AmbientLight和HemisphereLight补环境光,避免行星背面死黑 - 材质分级:行星用
MeshPhongMaterial(有高光反射,适合岩石/海洋),发光体和光环用MeshBasicMaterial(不受光照,自发光),轨道线用LineDashedMaterial(虚线)——按”要不要被照亮”选择材质是场景性能与观感平衡的基本功
HTML 标签(CSS2DRenderer)
天体名称标签用 CSS2DRenderer + CSS2DObject 实现:Three.js 只计算每个标签的屏幕投影位置,标签本身是真实 DOM——文字永远清晰锐利,还能直接用 CSS 控制样式。与把文字画进 Canvas 纹理的方案相比,缩放时不会糊。
拾取与交互(THREE.Raycaster)
点击天体的实现是 Raycaster 射线拾取:点击时从相机向鼠标位置发射线,与所有天体的包围球求交,取最近者触发信息面板。配合 OrbitControls 的拖拽/缩放手势,构成完整的”看 + 点”交互闭环。
技术栈
- Vue 3: 组件框架
- Three.js: 3D 渲染引擎
- TypeScript: 类型安全
- CSS2DRenderer: HTML 标签渲染
- OrbitControls: 轨道控制器