- 0
- 0
- 0
分享
- Unity 大咖作客 | 地球渲染、引力模拟、尾焰特效… 这是要上天?
-
2021-12-22
最新一期的 [Unity 大咖作客],B 站 UP 主矢速老师带大家体验了一把太空之旅。不得不感叹,如今创作者的灵感已经突破了地球,冲向外太空啦!
大家好!我是矢速。很荣幸受邀来分享我们制作航天模拟 CG 动画的一些 Unity 技术经验,我先讲讲这样做的来历。
我本人目前是一名学生,喜欢航天与单机游戏。在 2016 年的时候巧合接触了《坎巴拉太空计划》这款游戏,当时的感觉是相见恨晚。这款游戏是基于 Unity 开发的一款沙盒航天模拟游戏,在 2015 年正式发售,官方支持基于 Unity 的 mod 开发,目前有一个活跃的 mod 开发者社区。
而 Kerwis 团队全称中国坎巴拉太空计划智库团队,是 2014 年创建的 KSP mod 制作团队。在我和其他几个制作《坎巴拉太空计划》游戏视频的 UP 主,在 2020 年加入 Kerwis 团队以后,获得了有多年开发经验的老成员的技术指导,之后我们直接在 Unity 编辑器内制造航天模拟类 CGI。同时又因为一些巧合,获得了中科院网络信息中心的支持,在开始制作航天科普模拟视频后,我在团队中主要担任 Unity 内的 CGI 特效、渲染、模拟工作。这页 PPT 背景,是我们开发的中国航天器 mod 在《坎巴拉太空计划》中运行时的一张截图。
我先把今天要讲的内容做一个总览,首先要说明的是我本次分享的内容更偏向 Unity 与航天 CG 结合的技术点。
第一点,首先讲一下我们是怎样做出乍一看很高的画质,这些其实都是 Unity 内嵌好的渲染功能。
第二点,讲一些 CG 动画相关的东西。这一点在细节上会有别于游戏渲染。
第三点,航天中近地轨道占了很大比例的时间,在近地轨道的视角中,地球的渲染效果会很重要。
第四点,运动方面。其实在 CGI 中手动做动画曲线也可以,但是因为我们特别看重动画的真实性,外加 Unity 中有物理引擎的内嵌,所以尽可能使运动过程动画基于物理模拟。
第五点,讲一些视觉特效。
首先大致讲一下渲染方面的总体效果,我们使用的是 Unity 的 HDRP 高清渲染管线,并开启了光线追踪的全局光照、反射、环境光遮蔽与阴影。
关于开启的方法,B 站 Unity 官方账号中有一个专门的系列视频,栋哥做了详细讲解,然后使用 Post Processing 后期处理来进一步提升画面观感。
我们的模型也都是基于 PBR 流程制作的,在 Substance Painter 中有 Unity HDRP 贴图方案的预设,直接使用就可以了。
除了模型与材质外,光照渲染方面也全部基于 HDRP 的流程标准。
在渲染时,我首先会创建几个基础场景,比如说在发射场、大气中、近地轨道,然后为每个分镜复制并布置场景中的具体细节,使用 Cinemachine 插件实现运动镜头与镜头语言的设计;使用 Timeline 插件来控制诸如助推器分离、镜头运动、引擎点火这样时间轴上的事件;然后使用 Recorder 插件来渲染出最终的用于剪辑的分镜。
一般来说,我们会借助 Unity 实时渲染高速迭代的优势,通过关闭光线追踪与降低分辨率的形式来大大降低渲染的时间,并使用 Recorder 插件录制体积很小的 H.264 视频,发到团队群中做测试分镜。
这样差不多一个下午就能为一个分镜做 5 到 10 版的迭代改进,在最终效果达到较为妥当状态时再开启光线跟踪,录制 4K 分辨率 Quick Time 格式的最终分镜文件。
接下来讲讲地球的渲染,这一点首先需要说明的是目前我们仅仅是实现了渲染效果,但是暂时还没有做优化。从目前的 GPU 性能与显存需求来看,只适合做 CGI 渲染。我之后有计划做性能优化与效果的进一步提升。
我首先去 NASA 官网下载了 86K 分辨率的基础色与高程的清卫投影图。
然后是拆分成了满足 Unity 分辨率限制的 14400×14400 分辨率的贴图,这些就是我拆分后的基础色图。
第三是在 Unity 编辑器中将它们打造成 2D 纹理阵列,在 shader 中可以通过 UV 两个浮点数与阵列层整数获取到一个颜色。
注:要获取一个片元的基础色,可以先获取到片元的物体空间坐标系,这个坐标是直角坐标系,而经纬投影的经度和纬度是球坐标系的,那么可以先通过算法把片元位置直角坐标转化成球坐标,然后再使用乘/取小数/取整等计算获得这个坐标在贴图阵列中的 U,V 与层数位置。例子:图中红海边上这个点的片元最终用于查询纹理颜色的坐标就是 9 号纹理层,U 值为 0.6,V 值为 0.35。在 BC1 纹理压缩下,这个 14400x14400x18 个像素的 T2D Array 大约会占用 5G 显存。
第四是建模一个球体网格作为地球模型。我是在 Blender 中生成了一个 800 万顶点的棱角球,然后删掉了它的 UV。
第五步可选,是在顶点着色器中使用曲面细分进一步平滑基础的网格,同时可以基于高程图置换出山脉等细节。我制作这个地球的时候,似乎 HDRP 的光线追踪阴影等功能与顶点置换并不兼容,所以这一步我并没有在 CG 中实装。
第六步是在片元着色器中,根据片元的物体空间位置计算出对应的贴图阵列中的 UV 位置与层数。
然后是使用高程图计算出法线贴图,并在 shader 中设置一个高程的阈值。比如假设设置成 0,低于海拔高度 0 的地方光滑度高一些。实际上这里合理的做法是寻找水域遮罩图,因为并不是所有海拔低于 0 的地方都会被水覆盖,也不是所有高于海拔 0 的地方都很粗糙。例如贝加尔湖、青海湖等地方。不过,目前我并没有这样做,因为其实看起来已经大差不差了。
第八是使用 HDRP 基于物理的天空来渲染大气,移动地球的位置(注:Physically Based Sky 组件中的星球位置选项)使之与地球的模型同步。这里有一个要注意的点,因为天空渲染时一定会置于所有物体的视角方向上的后方,所以需要使地球模型半透明,来与大气层混合。又由于不同视角方向,以这里的背景图为例,远处的地面比起近处由于视角方向与地平面夹角比较小,所以光线会穿过更厚的大气层。
我在这里基于菲涅尔计算地面模型的透明度,使得视角方向与地面夹角较小的部分拥有看起来更厚的大气层。
接下来讲讲关于引力的模拟,Unity 的世界坐标是单精度浮点数,精度远不能满足浩瀚的宇宙空间的位置精度要求,所以使用双精度浮点数来写一个独立的坐标系(就叫它”宇宙空间坐标”吧),每次物理帧更新时,以相机的宇宙空间位置作为宇宙空间的世界坐标原点。将所有 Transform 的位置从宇宙空间坐标系反推并应用到 Unity 的世界坐标。
这么做可以保证物体渲染时的位置仍能保持在单精度浮点的精度范围内,同时不会影响到双精度坐标系中的位置计算。在计算时,还可以将物体分为引力源与引力受体两种。例如在有行星、恒星和航天器的模拟系统中,无需考虑航天器对行星与恒星的引力产生的加速度。然后每个物理帧对每个引力受体遍历每一个引力源。
对于物体的运动方程,可以用数值方法计算,考虑引力后的位移与角位移。目前我们实现过的只是一个比较初级的系统,使用 Unity 物理帧时间为步长的 4 阶显式龙格库塔法,并使用 Unity Mathematics 包的有单指令多数据流优化的双精度三维向量结构体。同时使用 Job system 可以使计算线程并行于主线程。
至于我们之前做的祝融火星车在 CG 中对轮架的模拟,这个并没有复杂的东西。直接使用 Unity 自带的轮子碰撞器,编写一个 C# 脚本,让它可以做出这些行为就行了,包括轮子的悬挂效果模拟等等功能都是 Unity 自带的。
然后使用注视\旋转\位置约束等现成的组件,使得轮架行为可以配合轮子的行为即可。这两个动图是我们模型师做完白模以后,直接在 Max 中手 K 动画曲线,然后离线渲染的。我在 Unity 里做的实时模拟测试视频,与有这个表现的成品 CG 在 B 站都可以看到。
接下来讲讲特效。
RCS 发动机燃气没什么特别的,直接找一张类似引擎燃气的照片,然后对着做一个模型网格,在 shader 中使用分型噪波与 UV 动画做出向外喷射的效果。最后再基于菲涅耳透明度,做出边缘透明度升高的淡出效果就可以了。这一点与地球渲染时的操作大同小异。
接下来是我们特效的重头戏,就是火箭发动机的尾焰。我需要说明的一点,由于目前我们并没有固体燃料发动机的模拟需求,并且固体燃料发动机的尾焰涉及了大量流体体积模拟与渲染,看起来类似这里背景图中的导流槽水雾。这方面我们并不擅长,所以这里我分享的仅限液体燃料发动机的尾焰效果。与固发效果不同的是,液体燃料的燃气不再发光后便几乎不可见,而不可见对于图形渲染来说就是不存在。
液体燃料主要分为四种,他们也都对应了四种特征迥异的尾焰种类。先说一些共同的特点,首先说明的是本人并没有高超音速流体模拟方面的专业背景,以下说明的都是针对视觉效果的经验特征。
尾焰分为较为稳定的部分与较为紊乱的部分,从喷嘴开始沿着喷射方向,较为稳定的部分会逐渐减少,并且从第一次收缩开始较为紊乱的部分会有内而外代替比较稳定的部分。并且随着环境气压的降低,尾焰的边界会逐渐膨胀,马赫盘会逐渐拉长乃至消失。
接下来看看四种尾焰的特点,偏二甲肼+四氧化二氮燃料的尾焰看起来比较清澈透明,在稳定段以蓝紫色为主,到了紊乱段以黄色为主。我们目前并没有做过液氧甲烷燃料的尾焰,不过外观与偏二甲肼+四氧化二氮燃料尾焰较为相似,发光颜色可以参考家里的天然气灶。
液氧+煤油燃料的尾焰特点,是在喷出后的一段距离内有很高的亮度,并且似乎透明度也很低。目前我并不清楚这是因为很高的亮度导致背景光相比之下看起来很暗,还是因为这段亮度很高的区域类的对光的吸收也会比较强,亦或二者都有。但对着照片做,总不会有问题的。在亮度比较高的区域,以明亮的黄色为主;而之后的一段区域内,则是比较黯淡的蓝色。
液氢+液氧的尾焰一般看起来是黄色偏红的,较为透明,并且亮度会比液氧+煤油的尾焰低很多。在这里由于照片的曝光,所以看起来似乎是差不多的。但是这一点可以在液氧+煤油发动机与液氢+液氧发动机同时出现的照片中看到,比如可以去找到一张长征五号起飞时的照片看一看。
下附图长征五号,芯级液氢液氧,助推液氧煤油,芯级尾焰极不显眼。
长按关注
第一时间了解Unity引擎动向,学习最新开发技巧
-
阅读原文
* 文章为作者独立观点,不代表数艺网立场转载须知
- 本文内容由数艺网收录采集自微信公众号Unity官方平台 ,并经数艺网进行了排版优化。转载此文章请在文章开头和结尾标注“作者”、“来源:数艺网” 并附上本页链接: 如您不希望被数艺网所收录,感觉到侵犯到了您的权益,请及时告知数艺网,我们表示诚挚的歉意,并及时处理或删除。