硬爆了!Cocos宇宙,仅一个网页链接,欣赏咫尺蓝星到亿万光年

大家好,我是圣子,一名大厂码农,业余的天文爱好者,从事游戏和前端互动相关方面的开发工作多年。

Cocosmos是我利用业余时间完成的一款展示宇宙全貌的程序,无需下载,点开即用,实时交互。您可以长按文末二维码或者在浏览器输入https://cocosmos.online 直接访问。

意料之外的是上个月网页发布后,瞬间访问量爆棚,导致CDN直接欠费。本月恢复网站的访问,圣子也上线了近日恒星的近距访问功能。后续还会有黑洞、超新星等一系列的内容加入,您可关注我的公众号和视频号获取第一时间更新消息。

我们来随机欣赏几颗近日恒星(文末有完整视频):

40b7ba9653e032df87ba10c9f75cf785.gif

全天亮度第二,老人星,船底座α,亮巨星

987c7a9e4b0bfb30bd69d800318e2042.gif

全天亮度第四,大角星,牧夫座α,橙巨星

e79f40fa6adbc794411277075a221e16.gif

全天亮度第六,五车二,御夫座α,黄巨星

dcd59199b73c97b4b48fa1c9dc110c41.gif

全天亮度第七,参宿七,猎户座β,蓝超巨星

3f5704df49a8086add9d9b8e7ad56abc.gif

全天亮度第八,南河三,小犬座α,主序星

3c769162a3848e26cfc04c2eb0cd19d2.gif

全天亮度第十,参宿四,猎户座α,超红巨星

这里也有我的序章介绍,内含概要描述后续技术分享的计划。

本篇为第一章节【从咫尺蓝星到亿万光年】的上半部分,主要介绍分级渲染大尺度下的宇宙。鉴于读者可能是天文爱好者或同时为游戏/页端开发人员,本文也分别从内容和技术两个不同角度做介绍。

Cocosmos

内容介绍

尺度划分

Cocosmos

宇宙很大,大到单纯用语言难以形容。我们生活在地球上,地球属于太阳系,太阳系又只是银河系中一刻普通的恒星。太阳系内除了包含地球的八大行星还有什么?银河系内有多少像太阳一样的恒星?宇宙中有多少像银河这样的星系呢?银河之上、银河之下又还有什么内容?

为了能真实的还原宇宙我们首先要有基本尺度上的认知,圣子选取了10概念上的尺度划分,每一个尺度级别都是上一个的3-5个数量级大小倍(数千到数十万倍大)。如此一来,我们不光在数学和概念和概念上有了初步的界定,同时也能在特定的范围内关注于其需要渲染的内容,做到不迷失。

2113a1017eed3a64e96cfbf11fda218f.jpeg

宇宙层次模型,点击查看大图

这里的层级划分这只是暂时,后续圣子可能会扩展层级,比如:

  1.  -1级,行星表面:可以在各个星球的地表探索和观测星空。

  2. 0级,近地轨道:同步轨道、着陆星表的过程等。

  3. 11级,非可观测宇宙,平行宇宙:想象中的外延或多个宇宙场景。

长度与单位

Cocosmos

在了解尺度划分前,我们首先来熟系几个长度单位,以便于在后续过程中有更好的数值概念基础:

  1. 公里(Kilometer,缩写km):既千米,这个大家都熟悉,大概是你家附近大型商场送外卖到你家的距离,地球的直径是12742公里。

  2. 光秒(Light Second,缩写c):光在真空中一秒跑的距离,接近30万公里,既1秒绕7个地球半,这个尺度是适合用来描述行星系统和观察天体轨道的尺度范围。

  3. 天文单位(Astronomical Unit,缩写AU):地球到太阳的平均距离,1天文单位=149,597,870千米,光需要跑8分20秒。这个尺度适合来描述恒星系统,八大行星中距离太阳最远的海王星轨道半径约30个天文单位。

  4. 光年(Light Year,缩写LY):光在真空中跑一年的距离,1光年=9,460,730,472,580公里。距离太阳最近的恒星南门二(比邻星)与太阳的直线距离是4.244光年,银河系的直径大约10万光年。

  5. 秒差距(Parsec,缩写pc)是一种最古老的,同时也是最标准的测量恒星距离的方法,它是建立在三角视差的基础上的。从地球公转轨道的平均半径(一个天文单位,AU)为底边所对应的三角形内角称为视差。当这个角的大小为1秒时,这个三角形的一条边的长度(地球到这个恒星的距离)就称为1秒差距。天文学家更多的是使用秒差距而非光年来描述天体尺度的距离。

  6. 哈勃直径(Hubble Diameter):从理论上推测宇宙大爆炸后到目前宇宙膨胀的直径,大约940亿光年,是人类能够观测到宇宙的极限。值得一提的是在这个尺度之外并不是类似黑洞洞空无一物的平常意义上的虚无,它连空间和时间的概念都不存在的真正虚无。

第一级:单一天体

Cocosmos

Cocosmos下每个天体都可以拉近距离,以观察其星表、大气、天文信息(比如公转与自转、轨道与周期等)、物理和几何结构信息(质量、密度、磁场、面积和地质构成等)以及一些人文方面的信息和介绍(东西方神话、天文发现史)等。内容较多,部分内容会在后续持续补充。在重要和著名天体上圣子会使用真实的静态数据(比如纹理)、动态属性上使用真实的参数进行计算,以尽量从以知的天文数据上还原内容。

除了我们熟知的母恒星太阳、我们的家园母行星地球外,太阳系内的其他七大大行星、以及其各自携带的数十颗著名卫星、已公认的五颗矮行星、数十颗著名的小行星、数十颗著名的彗星、主小行星带和柯伊伯带都会在列。

7b4408fc1ebfbdc1619df452a128c37a.gif

地球同步轨道与自转

4f917a4aa289604989bfef028178a9da.gif

地球与黄道面&白道面

71436de25a2cfd0d9cb1a17687f600df.gif

木星与木磁场

第二级:行星系统

Cocosmos

我的地球拥有一颗天然的卫星月亮,类似地球的固态行星,水星和金星没有天然卫星,火星拥有两颗较小的天然卫星。而类木行星(包含木星和土星)、类海行星(天王星和海王星)都各自拥有非常复杂的卫星系统或星环,其中木星和土星截止2023年底已发现的天然卫星数量达到惊人的95和82颗,然而其中大多数是很小和不知名的卫星。

圣子还原大多数知名卫星,比如四颗巨大的伽利略卫星(比水星还要大的木卫三盖尼米得),灭霸的老家土卫六泰坦,部分矮行星的知名卫星(比如冥王星的卫星冥卫一卡戎)也包含在列。圣子还特地在访达面板中对各类天体进行了质量、体积、距离、周期等排序,以方便我们直观的看到他们在各个维度的排名。

aa0978a21e2810e07035774e4b9e5973.gif

我们的天然卫星月亮

c449fdbc4b6ee82fddfa17834e51cadd.gif

土星和土卫系统

e68fb08cd42a78f3ef839d733e26b4a4.gif

天王星和天卫系统

第三级:恒星系统

Cocosmos

太阳系(Solar System)是相较于上两个系统来说比较热闹的尺度范围,也是第一个统一的系统(更具母星不同我们会在不同的行星系统中)。这里包含的内容众多,除了G2黄主序星太阳、已知八大行星(冥王星已被降级为矮行星)、多颗已经被国际公认和排队候选中的矮行星、近500个卫星、至少120万个小行星、数以亿计的陨星和冰块外还有众多的彗星。从距离太阳的远近程度大致可划分为内太阳系(水金地火)、主小行星带、外太阳系(木土天海)、海外区域(柯伊伯带、离散盘、奥尔特云等)

若以海王星轨道作为太阳系边界,则太阳系直径为60个天文单位,即约90亿千米。若以日球层为界,则太阳距太阳系边界可达100个天文单位(最薄处)。若以奥尔特云为界,则太阳系直径可能有20万天文单位。

除了能看清楚各天体的相对运行轨迹外,在太阳系中我们还可以通过调整天体的相对尺度缩放和时间快进等方式以更加生动地呈现整个系统的运行。

849fe4f3ad4cd6b679549f676cd987e1.gif

太阳系全景

c8ad03290ce0cd366e86453a8d11d928.gif

主小行星带近景

第四级:恒星系外围

Cocosmos

日球层顶(Heliopause)是太阳的太阳风被星际物质阻止的理论边界。在这里,太阳风与恒星际介质“两军对垒”形成的边界层挡住了高能宇宙线等的侵袭,是地球家园最外围“城墙”。在日球层顶之外,在大约230天文单位处,存在着弓形激波(Bow Wave),它是当太阳在银河系中穿行时产生的。

从太阳50000AU延展至100000AU左右是一片巨大的球体云——奥尔特云(Oort Cloud),通常认为,奥尔特云就是太阳系的引力极限与边界。这里拥有数量高达1兆的冰天体,是所有长周期彗星的来源。它被认为是被外层行星的引力作用从内太阳系逐出的彗星组成的。

eb5ab4a20f902d6beb278eb32e97373d.gif

太阳系边界和绕行银心方向

ce6c6e4d4d449c9031566f3ecdf2b2b6.gif

太阳系外围:希尔斯云与奥尔特云

第五级:近日群星

Cocosmos

从距离太阳最近的恒星比邻星开始(南门二/半人马座α三星系统中的一颗)到人肉眼可见的6等星以上约7000颗亮恒星,基本上都集中在了这个区域,其中不乏我们熟知的“牛郎织女”、“北斗七星”、“大角星”、“天狼星”等等。

这个范围从太阳系引力极限外围开始,到临近的恒星所在的3000光年直径内的古尔德带(Gould Belt),包含大量O型、B型、A型恒星,从银河盘面翘起16至20°,又隶属于本地臂/猎户臂(Orion Arm/Local Spur)银河系内的一条小螺旋臂,我们所熟知的全天88星座的主要构成恒星也在这个区域内,除此以外这里还有梅西耶天体中包含的部分星云和星团。

f262ab184ba0b23850796d8e1da432ab.gif

近日恒星与命名法切换

4dcf6cd2a2138f3f705678f7a235427a.gif

全天星座与主星连线

第六级:银河系

Cocosmos

银河系(milkyway galaxy)是太阳系所在的一个棒旋星系,总质量大约是太阳质量的1.5万亿倍,直径大约10万光年,包含1000亿至4000亿颗恒星,并可能拥有1000亿颗系外行星。古代很多著名的诗句中都有对银河的描写:“星汉灿烂,若出其里”、“飞流直下三千尺,疑是银河落九天。”、“醉后不知天在水,满船清梦压星河”……

银河系呈椭圆盘形,具有巨大的盘面结构,最新研究表明银河系拥有四条清晰明确且相当对称的旋臂,旋臂相距4500光年,拥有两个较大的伴矮星系:大麦哲伦星系和小麦哲伦星系。银河系的年龄大概在100亿岁左右,而科学界认为宇宙大爆炸大约发生于138亿年前。

6474c91ff108bebae0da1d9c48ca5c2f.gif

穿越银盘和银心

cb2e8abcb5e62f22e1c4fd15556803a4.gif

银河系棒旋结构

第七级:本星系群

Cocosmos

本星系群(Local Group of Galaxies),是银河系更上一层次结构,包含了银河系和相邻仙女星系、麦哲伦星云等50个星系成员组成了一个规模较小的集团。本星系群中的全部星系覆盖一块直径大约1000万光年的区域,质量约6.5万亿个太阳质量,它又属于范围更大的室女座超星系团。

本群是一个典型的疏散星系团,没有明显的向中心聚集的趋势。银河系仙女星系是本星系群成员星系中最大的两个,它们大体上位于本星系群的中心。除银河系和仙女星系外,绝大部分成员星系是矮星系,他们基本形成了两个次群:由银河系和大小麦哲伦云组成的银河系次群及以仙女星系为中 心 、包括 M 32 、NGC 205 、NGC147、NGC185、仙女矮星系和三角星系(M33)在内的仙女星系次群。

47983d4c868bc4254eecbb536d478f9d.gif

本星系群与主要星系

第八级:超星系团

Cocosmos

室女座超星系团(Virgo Supercluster,简称Virgo SC)又称作本超星系团(Local Supercluster,简称LSC或LS)是个不规则的超星系团,包含银河系和仙女座星系所属的本星系群在内。

室女座星系团约位于其中心位置。本星系群位于室女座星系团的边缘并且仍在继续向远离室女座星系团的方向移动。至少有100个星系团与星系群聚集在直径33百万秒差距(1亿1千万光年)的空间内,是在可观测宇宙中数以百万计的超星系团中的一个。

室女座超星系团是拉尼亚凯亚超星系团的一部分,它也是星系细丝双鱼-鲸鱼座超星系团复合体的一部分。,著名的梅西耶天体M49、M60、M86、M87均位于此。

76533cbf4ee153fc4261f5c57497a571.gif

室女座超星系团与主要星系群

第九级:超结构体

Cocosmos

拉尼亚凯亚超星系团(Laniakea Supercluster)是本超星系团更上一层的大尺度结构,该名词来自于夏威夷语,意思是“无尽的天空”,它由本星系团和周边一众星系团组成,是银河系和附近总数约达10万个星系的家园。

此级别下,我们可以看到更多的宇宙物理学中的大尺度纤维状结构,比如:超星系团复合体、星系长城、星系板等。它们也是是宇宙中目前已知的最大结构,长度能达到几十万到上千万光年,是名副其实的悍然大物。

0246db5400f1402e4b05d260d1447a5f.gif

拉尼亚凯亚超星系团与周边长城

第十级:可观测宇宙

Cocosmos

哈勃体积(Hubble volume)是最高阶的尺度范围,也是目前根据理论推测出的可观测宇宙大小的理论极限,其直径大约为940亿光年。

这个值是根据哈勃定律推算得出的包围观测者的球区域,在其之外观测者不能观察到被退行速度超过光速之外的区域包围的范围,也就是上文提到的“真正虚无”。

dad820e29391851b7dde5c8d45a798d3.gif

可观测宇宙与哈勃体积

Cocosmos

技术实现

精度问题

Cocosmos

当我们制作大世界范围场景的时候,会遇到模型的抖动和物体间的穿插问题。由于我们现在要从公里到百亿光年,跨越大约20个数量级别来渲染一个等比的宇宙模型,那么这个现象将更为明显。

为了理解这个问题的成因,我们首先需要了解Javascript中的数字都使用双精度浮点数来表示,即IEEE 754标准规定的64位数字编码,见下图:

df11b599ddaf88382fe4be6a91d4ce71.jpeg

64位双精度浮点数的表示

其中指数固定有11位,尾数固定52位。因为任何一个数都可以用科学计数法来表示,既V=(-1)^s*1.M...*2^E。当我们需要类似0.666、6.66、66.6、666这四个数时,它们都会被表示为6.66*10^n,但n依次为-1、0、1、2,既它们使用了相同的精确的尾数部分M,但是指数部分的E各不相同。

正因为如此在计算机中表示数值时,越接近于0的位置,数值会越精确。因为整数部分为零,小数点可以尽量后移以保证尾数部分的精确(这也正是“浮点数”这个名字的由来,既小数点位置是浮动不固定的)。相反,如果一个数足够的大,则尾数部分能够精确表示的尾数就越少。

换一个形象的方式解释:计算机能够表示的数值是有限而离散的,而数轴上的数是可以无限细分而连续的。当用前者表示后者时,越接近原点的位置数值越密集而精确,越远离原点的位置则越会“漏洞百出”。

现在我们反过来就能理解,假设世界坐标系的原点就在你的脚下,则你脚下的两颗芝麻也能够被精确区分(比如:0.000001和0.000002)。但此时火星上的两个并排站立的人,则可能被计算视作在同一个坐标点(比如1000000000.1和1000000000.2)。当精读不足时,顶点位置自然会聚拢到一点,出现模型的渲染的抖动、炸裂;深度精读不足则出现本该能清晰区分前后的面出现深度上错乱和穿插。

相对变换

Cocosmos

为解决大世界尺度下的精读问题,我们不能使用通常的变换矩阵来渲染场景。世界空间中的所有物体将基于主摄像机相机的相对位置来进行计算,同时其他的剔除和优化的工作也基于相机所在的坐标原点来进行。

一种常用思路是先在CPU测算出观察(localToCamera)矩阵,来替代原先世界(localToWorld)矩阵参与的计算。然后将这个矩阵传递到GPU进行变换,变换出来的结果不是世界坐标,而是相机的相对坐标(positionRS)。再将这个相对坐标变换作为相机空间按原来的方式做投影变换就完成了。此外,这项功能在Unity引擎5.0版本以上中是已经实现的,在HDRP渲染管线中将(Quality Setting)中的(Camera-Relative Rendering)开启即可。

球面相机

Cocosmos

f7a26d22eede6a420b385d4810f6376c.jpeg

Cocosmos中的球面观察相机

在Cocos中,圣子并未通过修改渲染管线,而是使用了一个更好理解的折中的方案:相机只执行旋转变换(位置永远固定在半径为R的单位球面上),世界空间相对原点做缩放和平移变换。这么做的原因有二:

  1. 使用高度角加方位角的方式来控制相机,可以更方便的描述和计算视角动画。

  2. 由实际项目需求决定,在大尺度的场景下更多的是以第三人称视角来环绕观察目标,而非以第一人称视角来自由移动。

事实上在宇宙类型或空战类型的游戏中,第一人称视角也只是被限定在一个较小的空间范围内。试想如果让用户可以漫游在真实的宇宙空间中,那么这个“游戏场景”将会显得异常的空旷。即使以光速移动相机,用户光从太阳到海王星的路程就需要真实时间的6个小时。

/** 以下为代码截取部分,仅供参考 **/
/** 世界空间只做平移和缩放变换 **/
const scale = 10 ** exp, v3a = new Vec3;
this.node.setWorldScale(scale, scale, scale);
Vec3.multiplyScalar(v3a, center.node.position, -scale);
this.node.setWorldPosition(v3a);
// ...
/** 以下为代码截取部分,仅供参考 **/
/** 3D主相机只做旋转变换 **/
private _ha: num.deg;   // 高度角
private _az: num.deg;   // 方向角
private _R: number;     // 观察半径


// 方式一:通过3D球面极坐标计算
const [ha, az] = [Math.parseRadian(this._ha), Math.parseRadian(this._az)];
const [uHor, uVer] = [Math.cos(az), Math.sin(ha)];
v3a.set(Math.sin(az) * uHor, uVer, Math.cos(az) * uHor);
this.node.setWorldPosition(v3a.multiplyScalar(this._R));
this.node.forward = Vec3.negate(v3a, v3a);
// ...


// 方式二:以下代码是效果完全相同的另一种数学计算方式
this.node.setWorldRotationFromEuler(-this._ha, this._az, 0);
const dir = Vec3.multiplyScalar(v3a, Vec3.UNIT_Z, this._R);
Vec3.rotateX(v3a, dir, Vec3.ZERO, Math.parseRadian(-this._ha));
Vec3.rotateY(v3a, v3a, Vec3.ZERO, Math.parseRadian(this._az));
this.node.setWorldPosition(v3a);
// ...

视点切换

Cocosmos

另一个需要解决的问题是在任意两个天体间的无缝视角切换,虽然可以通过相对变换计算直接完成,但是这样会显得非常生硬。一方面是由于从A点到达B的直线位移路径上很可能穿透眼前的天体(俗称穿模),另一方面巨大尺度的直线移动会使人失去用于对比的参照物而体验感较差(有一种目的地莫名其妙怼到脸上的感觉)。

9fe66611b3ec2dbf34bdf4d21e34d365.gif

Cocosmos中使用的视点切换

圣子在这里使用了一各通用的过度方式,配合球面观察相机和世界场景的相对变换正好可以轻松实现,此过程分为三步:

  1. 计算一组合适的高度角ha、方位角az和一个世界的缩放半径R。然后,将相机从聚焦物体A拉远到这个计算位置上。

  2. 相机视角方向由物体A转向目标B。

  3. 相机瞬间从2位置移到3(保持方向不变),世界坐标系瞬间变换使得B到达A的位置。然后,将相机逐渐聚焦到目标B身上。

6929807a9bd662e05935f6d7c7b5617a.jpeg

Cocosmos中的大尺度视角过度

理解这个过程有两个关键点:

A. 步骤1的作用是让相机转到一个合适的俯瞰视角,并使得A和B(出发地和目标地)同框(因此,这里的半径R通常选区A和B两者公转轨道的最大半径)。

B. 图中的两条红线(分别是相机朝向A和朝向B的视线)相对于红色和蓝色的半圆是几何相似的,这也就是变换过程中相机并未脱离球面,但用户会从视觉上感到视野无缝穿越了空间的原因。

时间关系本次分享就到这里,下一期会就技术部分继续深入阐述。

3b8a27c19fae51a275dd6b94f96ae307.jpeg

公众号

大朵的爸爸和游戏开发

6679f18e42ee4375fb74d1c9f570309f.png

在线体验
https://cocosmos.online

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值