threejs宇宙尺度:从量子到宇宙的62个数量级

基于 Three.js 构建的宇宙刻度可视化页面:一根对数刻度轴横跨 10^-35 米(普朗克长度)到 10^27 米(可观测宇宙),滚轮即可在 62 个数量级、95 个刻度项之间连续穿行,每种尺度都有程序化生成的专属 3D 形态。

尺度可视化 (Universe Scale)

上一篇的「宇宙层级之旅」是离散的 11 个层级,这一篇是它的极限版:连续的对数刻度轴。从普朗克长度到可观测宇宙约 62 个数量级,中间排布了 95 个真实或假想的尺度对象——量子泡沫、夸克、DNA、病毒、细胞、珠峰、太阳系、星系团、宇宙丝状结构……滚轮一滚,镜头就沿着刻度轴滑行,到达某个刻度时,对应的 3D 形态会淡入展开。

目录结构

1
2
3
4
5
6
src/pages/scale/
├── ScaleApp.vue # 主页面:刻度轴、导航、交互、全部 3D 形态生成
└── scaleData.ts # 95 个刻度项的数据定义
└── locales/
├── zh.ts # 中文翻译
└── en.ts # 英文翻译

数据模型 (scaleData.ts)

每个刻度项是一个 ScaleItem:

字段 含义
size 实际尺寸(米),如普朗克长度 1.616e-35
exponent 10 的指数(-35 ~ 27),用于刻度轴定位
shape 形态类型,共 22 种(见下文)
color 主题色,随数量级渐变:量子尺度偏紫红,日常尺度偏绿,宇宙尺度偏青

数据按物理量真实排布:夸克 < 10^-18 m,电子 ~2.8×10^-15 m,DNA 直径 ~2 nm,病毒 ~100 nm,红细胞 ~7 μm,珠峰 ~8.8 km,太阳 ~1.39×10^6 km,本星系群 ~10^23 m……约 62 个数量级的跨度在一条对数轴上被完整还原。

核心机制:对数刻度轴

状态与插值

页面只有两个核心状态:

1
2
logPosition          // 当前对数位置(-35 ~ 27)
targetLogPosition // 目标位置

滚轮和触屏捏合只改 targetLogPosition,动画循环里把 logPosition 平滑地插值逼近目标值(每帧按比例收敛),形成”顺滑穿行”的手感。位置变化时自动匹配最近的刻度项,切换其 3D 形态。

与 OrbitControls 的配合

一个容易踩的坑:滚轮默认会被 OrbitControls 拿去做相机缩放。这里刻意 controls.enableZoom = false,把滚轮和双指捏合完全接管用于尺度切换,OrbitControls 只负责旋转和平移——否则”缩放视角”和”切换尺度”两个语义会打架。

22 种程序化形态

所有 3D 形态都是程序化生成的,没有任何外部模型。按尺度从小到大:

形态 对应尺度 实现要点
quantum-foam 普朗克长度、弦 二十面体概率云核心 + 300 个紫-青渐变涨落粒子
particle 中微子、夸克、电子 小型发光球体
nucleus 原子核、质子 多球簇状组合
atom 原子 核心 + 轨道电子
molecule 分子、水分子 多球连接结构
helix DNA、蛋白质 双螺旋曲线
virus 病毒 带刺突的球体
cell 细胞 有机形态球体
organism 蚂蚁、人 椭球体
object 硬币、书 立方体/长方体
building 楼房、埃菲尔铁塔 高耸柱体
mountain 珠峰 锥体
orbit 近地轨道 球体 + 环
planet 地球、木星 带纹理球体
star 太阳、蓝巨星 发光球体 + 光晕
solar-system 太阳系 中心恒星 + 轨道行星
nebula 猎户座星云 粒子云团
galaxy 银河系 螺旋粒子盘
galaxy-cluster 星系团 多球分布
filament 宇宙丝状结构 丝线网络
cosmic-void 宇宙空洞 边界球
universe 可观测宇宙 边界球 + 粒子

每种形态由 createShapeObject(shape, color) 按主题色生成,装入 shapeGroup;切换刻度项时清空重建,几何体和材质全部 dispose,保证长时间滑动不泄漏显存。

交互设计

尺度切换

操作 桌面端 移动端
切换尺度 滚轮 双指捏合 / 上下滑动
旋转视角 左键拖动 单指滑动
平移视角 右键拖动 双指滑动

刻度轴 UI

  • 顶部/底部对数刻度轴:实时显示当前在对数轴上的位置(0-100%)与当前项的指数(如 10⁻¹⁵ m)
  • 尺寸格式化:根据量级自动换算单位——飞米、皮米、纳米、微米、毫米、米、公里、天文单位、光年,导航菜单里还有短格式(fm / nm / AU / ly)
  • 分组导航:95 个刻度项按四个分组折叠
    • ⚛️ 量子尺度(< 10^-15 m)
    • 🔬 微观世界(10^-15 ~ 10^-2 m)
    • 📏 日常尺度(10^-2 ~ 10^7 m)
    • 🌌 天文尺度(> 10^7 m)
  • 点击任意刻度项即可跳转,镜头沿对数轴滑行到目标

过渡动画

形态切换时新旧对象做透明度/缩放过渡,同时相机沿视线方向平滑过渡到目标距离(desiredCameraDistance),不同尺度的物体”远近感”由此统一:看原子和看星系团的构图体验是一致的。

性能要点

  • 按需构建:22 种形态只在对应刻度项激活时才生成,离开即销毁
  • 资源回收:clearShapeGroup() 对 Mesh / Points / Line 三类对象分别做几何体与材质的 dispose
  • 像素比上限:renderer.setPixelRatio(Math.min(devicePixelRatio, 2)),避免高分屏 4x 填充率开销
  • 插值收敛:刻度位置用帧率无关的比例逼近,不依赖固定步长,不同刷新率的屏幕手感一致

Three.js 特性与实现

相机与控制器的”重新分工”

本模块最有意思的 Three.js 用法是禁用了它的部分能力:

  • OrbitControls.enableZoom = false——滚轮被页面原生 wheel 监听器拦截,专门用于沿对数刻度轴滑行;touchmove 同理被接管为捏合切尺度
  • OrbitControls 只保留旋转和平移(rotateSpeed: 0.5、panSpeed: 0.5),并保留阻尼
  • 视角”远近感”不靠用户缩放,而是每个形态自带 desiredCameraDistance,切换时相机沿当前视线方向(_camDir 单位向量)平滑推进/后退到位——看原子和看星系团的构图体验因此完全一致

这本质上是把”缩放”这个自由度从相机转移给了世界本身:用户以为在放大物体,实际是在不同尺度间穿行。

程序化几何(Geometry 组合拳)

22 种形态全部由 Three.js 基础几何体组合生成,没有外部模型:

  • 量子泡沫:IcosahedronGeometry(二十面体,细分 4 级)做概率云核心 + 300 粒子的 BufferGeometry 涨落云,顶点颜色用 THREE.Color().setHSL() 在紫-青色域随机采样
  • 原子:核心 SphereGeometry + 电子轨道椭圆参数方程逐帧算位置
  • DNA:双螺旋是两条相位差 π 的正弦/余弦曲线点列 + 连接横档
  • 病毒:主体球 + 表面按斐波那契分布的刺突小球
  • 星系:粒子盘按对数螺旋分布,与层级之旅那篇的银河系同源但参数不同

所有用色都从当前刻度项的主题色 color.getHSL() 出发微调明度/饱和,保证 62 个数量级穿行时画面色调是连续渐变的。

材质选择

  • 发光体(粒子、电子、恒星):MeshStandardMaterial / MeshPhongMaterial 开 emissive 自发光
  • 粒子云:PointsMaterial + vertexColors + AdditiveBlending,透明叠加出星云质感
  • 不受光的容器/边界:MeshBasicMaterial 低透明度

帧循环与状态管理

每帧做三件事:

  1. logPosition += (targetLogPosition - logPosition) * k 指数收敛——帧率无关的平滑插值,不依赖固定步长
  2. 根据新位置匹配最近刻度项,若变化则重建 shapeGroup 并启动过渡动画(transitionProgress 0→1 驱动透明度和缩放)
  3. 相机距离向 desiredCameraDistance 收敛 + controls.update() + 渲染

资源管理

  • clearShapeGroup() 对 shapeGroup 里的 Mesh / Points / Line 三类对象分别 geometry.dispose() 和 material.dispose()(注意材质可能是数组,要遍历)——每次滚轮跨过刻度项都会触发重建,不做回收显存会迅速爆掉
  • renderer.setPixelRatio(Math.min(devicePixelRatio, 2)) 封顶像素比,4K 屏省一半以上填充率

技术栈

  • Vue 3: 组件框架(Composition API)
  • Three.js: 3D 渲染引擎
  • TypeScript: 类型安全
  • OrbitControls: 轨道控制器(禁用缩放,滚轮让给尺度轴)

threejs宇宙尺度:从量子到宇宙的62个数量级
https://cszy.top/20260902-threejs宇宙尺度/
作者
csorz
发布于
2026年9月2日
许可协议