模拟数百万粒子来创造太阳

2025-06-10

模拟数百万粒子来创造太阳

我最近写了一篇博客文章,讲述了我如何学习使用 Unity 游戏引擎制作电子游戏。在那篇文章中,我构建了一个简单的太空场景,并添加了一些基本的游戏机制。写完那篇文章后,我想尝试一些更炫酷的东西,比如在场景中心放置一个太阳的戏剧版本。这个项目让我深入了解了 Unity 中的粒子模拟。起初,模拟完全在 CPU 上完成。后来,我发现了 Unity 可视化特效编辑器 (Visual Effect Graph) 以及 GPU 的惊人性能。

我的第一次尝试是在场景中添加一个球体,并用太阳表面的等距矩形投影包裹它,就像我在上一篇文章中对火星所做的那样。结果并不令人满意。太阳表面充满活力,散发着能量,但我的球体看起来就像一个巨大的橘子漂浮在太空中。

为了让效果更生动一些,我在 Unity 中创建了一个密集的粒子系统,然后用 Photoshop 用一张烟雾图像创建了自定义纹理。我找到了一张着火船只的图片,裁剪出一部分烟雾,并根据烟雾的暗度为每个像素添加 Alpha 值,本质上就是将黑暗转化为透明。下图是大约 1000 个粒子在球体表面淡入淡出的效果。

太阳表面现在有了运动,这无疑比以前更有趣了。可惜的是,效果仍然不太好,而且看起来有点不对劲。我很快意识到我创建的纹理实际上并不透明。稀薄的烟雾区域并没有渲染成透明的,而是完全不透明的!

修复这个问题花了我好几个小时,大部分时间都花在了如何将图片中较暗的像素转换为透明像素上。对于初学者来说,在 Photoshop 中使用 Alpha 通道并不直观!修复完图片中的 Alpha 通道,并弄清楚如何将透明纹理导入 Unity 后,效果如下:

好多了!接下来我尝试添加日冕。日冕是太阳大气的外层,比太阳表面暗得多。所以我又添加了一层粒子,但让它们更暗,颜色也更偏橙色。

我对此非常满意,但我想更进一步。上图中的太阳包含大约 1200 个粒子,所有这些粒子都是在 CPU 上模拟的。最近,我一直在阅读有关 Visual Effect Graph 的信息,这是 Unity 即将推出的一项功能,它允许你完全在 GPU 上模拟粒子。事实证明,GPU非常擅长这项任务。这个项目给了我一个很好的机会,让我深入研究 VFX Graph,看看它究竟有多强大。

首先,我创建了一个包含数十万个粒子的球体。然后我开始增加粒子数量,最终一次模拟了 2,000,000 个粒子:

尽管我的屏幕上渲染了大量粒子,我仍然可以在整个场景中飞行,并保持恒定的 200 FPS。为了将 FPS 降至稳定的 60,我采取了以下措施(请注意,FPS 看起来较低,因为我的 GIF 录制软件限制为 15 FPS):

这是实时模拟的1400 万个粒子的爆炸。

我想利用 VFX Graph 的强大功能来让我的太阳栩栩如生。

我创建了一个球形粒子体积,并配置了粒子图,以便在球体表面生成新的粒子实例。为此,我创建了一个随机数向量,然后将其归一化,使其长度为 1。该向量表示单位球体上的一个随机点。在我的场景中,代表太阳的球体的半径为 42。为了得到这个表面上的随机点,我将表示单位球体上随机点的向量乘以 42。最终结果是太阳表面的一个随机点。

既然能够在球体表面生成微型粒子系统,我的下一个任务就是引入一些混沌效果。我希望它们看起来像是恒星表面的。

Unity VFX Graph 的“湍流”节点给了我一种令我满意的效果,而且我认为这种效果单独来看很漂亮。

此时,我已经构建了一个巨大的空心粒子球,我希望当它们包裹住我之前制作的太阳时,看起来不会显得突兀。我把太阳放在这个粒子球里面,然后添加了一个脚本来让整个球旋转。

此时,我对目前的状况已经很满意了,但我意识到太阳表面和周围的粒子运动确实能有效地吸引人们的注意力。为了进一步吸引人们的注意力,并让画面更具戏剧性,我添加了一股粒子流,它们在太阳表面生成,向外传播,最终消失。

最后,我想添加一些日珥,于是打开 Photoshop 绘制了另一张纹理。这次我手动绘制,而不是根据真实图像进行绘制。我生成了 50 个粒子实例,使其环绕太阳,并在粒子生成时对其大小进行了细微的变化。粒子以随机旋转的方式生成,并缓慢地围绕太阳旋转。

最终结果不是最现实的,但肯定相当引人注目,总体来说我很满意。

如果我要继续研究它,我可能会用着色器替换太阳表面,而不是反复产生烟雾粒子,并尝试使用照明而不是粒子使它看起来比现在更“发光”。

感谢阅读!

鏂囩珷鏉ユ簮锛�https://dev.to/_darrenburns/simulated-millions-of-articles-to-create-the-sun-2ppo
PREV
6 个将代码片段转换为图像的超棒工具
NEXT
增强你的命令行,第 3 部分