跳至正文

Three.js 构建数字天文台(实时太空可视化)

用 Three.js 把宇宙装进浏览器,从地球到月球,从 ISS 到星辰大海——这不是静态模拟,是一个活着的宇宙。

前言

你有多久没好好看过星星了?

大多数人认识宇宙的方式,是教科书上的图表、NASA 发布的卫星照片、或者手机上的星图 App——它们很美,但总觉得隔着一层。

Atlas26 想做的是:把宇宙变成一个可以触摸的数字窗。

用 Next.js + Three.js + React Three Fiber 构建的实时 3D 太空可视化平台,通过 NASA 和 Celestrak 的实时数据,让行星、卫星、轨道都在你浏览器里活起来。

这不仅仅是一个 Demo,而是一个持续进化的"现代数字天文台"。

航空航天

一、项目概览

GitHub:Abdul-Wasay-008/Atlas26

在线演示:https://atlas26.vercel.app

核心愿景

"What if space felt alive, beautiful, and emotionally engaging, not just educational?"

作者希望让太空不再只是冷冰冰的数据和图表,而是一个活着的、可感知的、有情感的宇宙


二、Atlas26 能做什么?

2.1 实时地球可视化

地球不是一张贴图,而是一个动态球体

  • 昼夜交替渲染:基于真实太阳光方向计算晨昏线(terminator)
  • 动态光照:太阳位置随时间变化,地球阴影实时更新
  • 大气层效果:用 Shader 模拟地球大气散射
// 昼夜交替 Shader(示意)

varying vec3 vNormal;
varying vec3 vPosition;

uniform vec3 uSunDirection; // 太阳光方向

void main() {
  vec3 viewDir = normalize(cameraPosition - vPosition);
  float dotSun = max(dot(vNormal, uSunDirection), 0.0);

  // 白天:反射太阳光 + 大气散射
  // 黑夜:城市灯光 + 自发光
  vec3 dayColor = texture2D(uDayTexture, vUv).rgb * dotSun;
  vec3 nightColor = texture2D(uNightTexture, vUv).rgb * (1.0 - dotSun);

  vec3 finalColor = mix(nightColor, dayColor, dotSun * 0.7);
  gl_FragColor = vec4(finalColor, 1.0);
}

2.2 ISS 轨道追踪

国际空间站(ISS)不是静止的模型,而是基于真实轨道数据运行的:

  • 轨道周期:约 90 分钟绕地球一圈
  • 实时位置:根据时间计算轨道参数
  • 可视化路径:绘制轨道轨迹,预测未来位置
// ISS 轨道计算(示意)

const issOrbit = {
  inclination: 51.64,    // 轨道倾角(度)
  altitude: 408,         // 轨道高度(km)
  period: 92.68,         // 轨道周期(分钟)
  epoch: Date.now(),     // 起始时间
};

function getISSPosition(time: number) {
  const elapsed = (time - issOrbit.epoch) / 1000 / 60; // 分钟
  const angle = (elapsed / issOrbit.period) * 2 * Math.PI;

  // 简化的圆形轨道计算(实际需考虑偏心率等)
  const radius = (EARTH_RADIUS + issOrbit.altitude) / 1000; // 单位转换

  const x = radius * Math.cos(angle);
  const z = radius * Math.sin(angle);

  // 应用轨道倾角旋转
  const y = z * Math.sin(issOrbit.inclination * DEG_TO_RAD);

  return new Vector3(x, y, z * Math.cos(issOrbit.inclination * DEG_TO_RAD));
}

2.3 动态月相模拟

月球的位置、光照、阴影都是实时计算的:

  • 月地距离:约 38.4 万公里(按比例缩放)
  • 月相周期:约 29.5 天
  • 光照方向:与太阳对齐,产生真实阴影
// 月相计算(示意)

function getMoonPhase(date: Date): number {
  // 朔望月周期(天)
  const SYNODIC_MONTH = 29.53;
  // 已知新月日期
  const KNOWN_NEW_MOON = new Date('2025-01-01');

  const daysSinceNew = (date.getTime() - KNOWN_NEW_MOON.getTime()) / DAY_MS;
  const phase = (daysSinceNew % SYNODIC_MONTH) / SYNODIC_MONTH;

  return phase; // 0 = 新月, 0.5 = 满月, 1 = 下一个新月
}

2.4 电影级相机系统

相机不是简单的 OrbitControls,而是预定义的电影镜头路径

// CameraControls.tsx

import { useFrame } from '@react-three/fiber';
import { useSpring } from '@react-spring/three';

const presets = {
  earth: { position: [0, 0, 5], target: [0, 0, 0] },
  moon: { position: [1, 0.5, 3], target: [0.5, 0, 1.5] },
  iss: { position: [0.2, 0.3, 1], target: [0, 0, 0] },
};

function CameraControls({ currentPreset }) {
  const { position, target } = useSpring({
    position: presets[currentPreset].position,
    target: presets[currentPreset].target,
    config: { mass: 1, tension: 120, friction: 20 },
  });

  useFrame(({ camera }) => {
    camera.position.lerp(new Vector3(...position.get()), 0.1);
    camera.lookAt(new Vector3(...target.get()));
  });

  return null;
}

解析useSpring 提供平滑的物理缓动(mass/tension/friction 模拟弹簧系统),相机在预设位置之间切换时,会自然地加速和减速,而不是生硬地跳变。


三、使用技巧 

3.1 本地运行

# 克隆项目
git clone https://github.com/Abdul-Wasay-008/Atlas26.git
cd Atlas26

# 安装依赖
npm install

# 启动开发服务器
npm run dev
# 访问 http://localhost:3000

3.2 交互方式

操作说明
鼠标拖拽旋转视角
滚轮缩放推拉相机
点击天体查看详细信息面板
UI 按钮切换相机预设(地球/月球/ISS)

3.3 自定义天体数据

项目支持本地元数据系统,你可以扩展新的天体:

// data/celestial-objects.ts

export const celestialObjects = {
  earth: {
    name: 'Earth',
    radius: 6371, // km
    mass: '5.97e24 kg',
    texture: '/textures/earth.jpg',
    orbitPeriod: 365.25, // days
    rotationPeriod: 24, // hours
  },
  moon: {
    name: 'Moon',
    radius: 1737,
    distance: 384400,
    texture: '/textures/moon.jpg',
    orbitPeriod: 27.3,
    rotationPeriod: 27.3,
  },
  // 添加你自己的天体...
};

四、核心代码解读 

4.1 项目架构

src/
├── components/
│   ├── Earth/          # 地球组件(昼夜渲染、大气)
│   ├── Moon/           # 月球组件(月相、阴影)
│   ├── ISS/            # 国际空间站(轨道追踪)
│   ├── Stars/          # 星空背景(粒子系统)
│   └── CameraControls/ # 电影级相机控制
├── hooks/
│   ├── useOrbitalData.ts    # 轨道数据计算
│   ├── useSunPosition.ts   # 太阳位置计算
│   └── useTimeScale.ts     # 时间缩放控制
├── utils/
│   ├── orbit.ts       # 轨道计算工具
│   └── celestial.ts   # 天体常数(G、AU 等)
└── data/
    └── celestial-objects.ts  # 天体元数据

4.2 星空粒子系统

// Stars.tsx

import { Points, PointMaterial } from '@react-three/drei';

const COUNT = 10000;
const stars = Array.from({ length: COUNT }, () => ({
  position: [
    (Math.random() - 0.5) * 2000,
    (Math.random() - 0.5) * 2000,
    (Math.random() - 0.5) * 2000,
  ],
  size: Math.random() * 2 + 0.5,
  color: new Color().setHSL(Math.random(), 0.2, 0.8),
}));

function Stars() {
  return (
    <Points positions={stars.map(s => s.position)}>
      <PointMaterial size={1} vertexColors sizeAttenuation />
    </Points>
  );
}

解析@react-three/drei 的 Points 组件是 Three.js BufferGeometry 的 React 封装。一次性上传 10000 个顶点到 GPU,用 gl.POINTS 绘制,性能极高。sizeAttenuation 让点的大小随距离衰减,符合透视规律。

4.3 太阳位置计算(基于时间)

// hooks/useSunPosition.ts

export function useSunPosition(date: Date) {
  // 简化版:春分点方向 + 地球自转
  const dayOfYear = getDayOfYear(date);
  const declination = 23.45 * Math.sin((dayOfYear - 81) * DEG_TO_RAD);

  const x = Math.cos(declination * DEG_TO_RAD);
  const y = Math.sin(declination * DEG_TO_RAD);
  const z = 0;

  return new Vector3(x, y, z).normalize();
}

解析:太阳在地球坐标系中的位置受季节影响(赤纬角),约 ±23.45°(地球自转轴倾角)。这个简化计算忽略了岁差、章动等高阶项,对于可视化足够精确。


五、为什么这个项目值得关注?

5.1 诗意 × 技术

Atlas26 最打动人的地方在于它的情感表达——作者不是为了炫技而写代码,而是为了让人们"感觉"到宇宙的尺度与美。

这不是一个普通的技术 Demo,而是一个数字艺术作品

5.2 实时数据驱动的 3D 可视化

很多 Three.js 项目使用静态模型和动画,而 Atlas26 直接对接 NASA & Celestrak 的实时轨道数据,让天体位置是"真"的。

这种数据驱动的思路,可以应用在任何需要实时可视化系统的场景:金融、交通、物流、物联网……

5.3 WebXR & AR 的前瞻布局

README 中已经列出了 WebXR 和 AR 的长期规划——这意味着未来你可以在 VR 头显里"走进"太空,或者用手机 AR 把月球放在你的桌子上。

浏览器 + 3D + 空间计算,这是未来十年的重要方向。


六、未来计划 

时间范围计划功能
近期NASA/Celestrak 实时数据、更准确的行星位置、改进光照和 Shader
中期AI 驱动天体解释、教育模式、时间速度控制、多天体层(卫星/碎片/空间站)
长期WebXR 沉浸式探索、AR 模式、叙事驱动的宇宙故事、多用户共享探索、虚拟课堂

七、结语

Atlas26 是一个有温度的项目。

作者把一个"太空可视化工具",升级成了一个"数字天文台"——它不只是展示数据,而是让人与宇宙产生情感连接

如果你对 3D 可视化、数据驱动系统、天文科普、WebXR/AR 这些方向感兴趣,这个项目值得你深入研究。

5,051字
👁 阅读量:30
标签:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

扫码分享本文 分享二维码