揭秘《死者之书》之风、场景地形及优化技巧
在揭秘《死者之书》的系列文章中,我们已经分享了:
本篇文章将由Unity Demo团队环境艺术家Julien Heijmans从内容创作者和环境艺术家的角度,为我们提供一些关于《死者之书》制作过程的深入解读。本篇文章我们将关注点放在风系统、场景地形和内容优化技巧。
Unity与Quixel的合作
我们不仅仅让《死者之书》只供人欣赏,我们还提供了这个项目中的环境资源,前往Asset Store资源商店搜索“Book Of The Dead: Environment“,即可免费下载。
在此资源文件中,我们在使用了摄影制图法进行创作。而其中一些资源来自Quixel公司Megascans库的扫描环境艺术资源,Unity与Quixel在这个项目的制作上达成了紧密的合作。
在制作过程中,Unity Demo团队创建了一个所需资源的列表,如果现有的扫描库中缺少合适的对应资源,Quixel则会为之采集新资源。这其中的不少资源都是植被,例如:草地、植物和灌木丛,这些资源需要合适的设备和布置来进行扫描。
Quixel不仅为我们提供了资源的纹理集,还创建了相应的几何,带有LOD和顶点色设置,用来支持我们的风着色器。
在这个过程中,我们收到了超过50个高质量资源,这些资源较为复杂,我们不得不依靠着团队中为数不多的艺术家努力有限的时间中完成项目。
在制作期间,我们快速的将资源载入到Unity中,得到不错的外观效果。我们经常会调整纹理,修改反照率、亮度、等级和曲线,修改色彩从而使它们与场景效果更为统一。我们重新调整LOD到所希望的等级,并且将纹理指定给一个新的HDRP光照材质。
幸运的是,Quixel发布了一个工具Megascans Bridge,它能完成之前大量我们需要手工完成的导入工作。Megascans Bridge在为HDRP重打包纹理时节省了大量时间。
如果你对Megascans中资源感兴趣,想要获取更多这类资源, 可以访问Asset Store资源商店获取。所有这些资源都能够导入到项目配置中,不管项目使用的是高分辨率渲染管线还是轻量级渲染管线。
风
为植被资源及其整个管线建立风系统始终是一个非常棘手的过程。 在场景中,许多不同种类的植被资源需要以不同的方式进行动画处理,例如:二种不同的树或许需要完全不同的设置和不同的着色器复杂度来完成。
因此,我们决定创建一个基于自定义顶点着色器的程序动画,应用于对植被资源产生风效果。它适合我们的特定项目中的树木或灌木丛,并且允许我们完全控制它。
技术主管Torbjorn Laedre开发了一个着色器,能够支持多种植被,这个着色器使用了三个不同的技术:
层级轴心(Hierarchy Pivot):应用于树木和一些非常明确结构、层级的植物。
单个轴心(Single Pivot):应用于草地、小型植物和带有不确定结构、层级的大型灌木。
程序动画(Procedural Animation):应用于无法确定轴心点的植被资源。
树木是更为复杂的资源,它们使用的是层级轴心类动画,依赖三个不同的层级:
树干(Trunk):根植于地面的部分。
A级树枝(Branches Level A):与树干相连。
B级树枝(Branches Level B):与A级树枝相连。
着色器需要知道层级等级和树木每个顶点的轴心点。首先,我们要创建树木本身的几何图形,然后使用绿色顶点颜色通道为树木的每个多边形指定层级等级。
顶点颜色的绿色通道数值为0时,表示这个部分是树干。
数值在0和1之间则是A级树枝。
数值为1则是B级树枝。
这部分任务使用了Maya完成,通过使用一些小脚本,可以在10-15分钟内设置好一个资源的所有LOD。
除此之外,我们还使用了“Flutter Mask”(抖动遮罩)。抖动遮罩是纹理遮罩,能够帮助确定在几何上树枝的轴心位置。下图是这个遮罩的图示。
准备好所有信息后,就可以输入树木预制件的C#脚本,并生成一个新的预制件,其中包含每个顶点的轴心信息。在添加WindControl对象到场景中后,便可以将树木导入到场景中,并开始处理材质属性。
https://v.qq.com/txp/iframe/player.html?vid=a0723mxcit8&width=500&height=375&auto=0
我们可以看到,每个层级等级都具有范围属性,基本上是树干或树枝长度和弹性属性。
还有一些属性用来设置风抖动动画。它们给顶点位置添加了一些程序化噪音,从而模仿出当风吹到树干时的振动效果。
最后我们还需要使风的音效对动画产生影响。音效的音量会驱使动画的风力。这个简单想法加入项目的方式非常惊人,你可以打开项目,然后在场景中四处走动。当听到大风吹过身边时,你会发现树木和周围的草地都在摆动。
布局
在处理《死者之书》这样的项目的细节和密度时,思考如何构建等级十分重要,从而避免在制作中出现的性能问题。其中一个所考虑的想法是限制场景中的远景距离。我们可以通过在场景布局中放置“过道”和“障碍”来实现这个想法。
这些布局结合正确设置“Occluder static”和“Occludee static”标记的资源后,会使Unity的遮罩剔除更为高效。
https://v.qq.com/txp/iframe/player.html?vid=f0723myh6h5&width=500&height=375&auto=0
上面的视频展示了遮罩剔除的可视化过程,我们可以看出摄像机是从顶部视图进行观察的。在视频结尾,启用/禁用了遮罩剔除,然后查看对象如何被遮罩剔除功能剔除。
我们也能看到一些没被剔除的对象,这些对象大多是非常高大的树木,有些超过25米高,这些树有很大的边框,因此很难在峭壁后剔除。
Unity传统地形的使用
在《死者之书》预告片发布后,我们看到有些评论说:决不可能在这个项目中使用传统地形系统。但实际上我们使用的就是传统地形系统,我们修改了HD渲染管线的Layered Lit着色器来支持它。HDRP Layered Lit着色器允许使用高度图纹理来混合图层,所以得到的结果会比传统地形着色器的线性混合功能更好。
此动画中,仅修改了不同图层的高度偏移值
当然,这是一种临时的解决方案,不能在UI中适当集成。为了修改地形,我们需要编辑应用于它的材质,而不是使用在地形对象中Paint Texture(绘图纹理) 标签下的“Edit Texture”(编辑纹理)按钮来处理。
这些图层主要是为了帮助绘制地形上的不同图层。它们不是用来渲染地形的,除非是使用平铺设置。
与此相反,寻找适用于地形的材料,我们会发现所有纹理和材质属性都会影响地形。
如果要创建新地形并在其上应用不同纹理,则需要拷贝TerrainLayeredLit材质,并将其指定到新地形上。还需要在Paint Texture标签中创建4个纹理集。指定的纹理不会用来渲染地形,但它们会让我们在地形上绘制不同的图层,还可以修改不同图层的平铺设置。
此外,为了能够完全使用LODGroup功能,所有在地形上放置的资源都会设置为树木(Trees)而不是具体的资源。
但实际上,这个项目有大量零散的资源分布在地面上:草、灌木丛、植物、小树枝、岩石等。即使有那么多零散资源,地形还是比较简单,在下一部分我们可以了解到,在这个画面中地形只是一个简单的平铺材质。
零散的细节资源
当在关卡中移动时,我们会注意到在地上散落大量的小树枝和松果。
如果只是在关卡附近移动时,这并不明显,但我们开始注视地面时,这些小树枝和松果给场景带来了细节。
有时候地面会有数百根细小的树枝,分散在岩石和枯萎树干之间,这感觉就像它们自然从树上脱落在这些位置。手工放置它们是不可能的,所以Torbjorn Laedre制作了一个工具帮助我们将这些小型细节对象分散这些关卡中。
小树枝是带有Alpha材质的简单切口平面。我们给这些小树枝添加了物理胶囊碰撞体。
该脚本首先会在变换位置周围生成指定数量的零散对象,然后为它们模拟落到地面的物理效果,它们落下后会与地形、其它资源岩石、枯萎树干等相互碰撞。然后按下按钮“Bake”,小树枝的碰撞体会被移除,合并为单个对象,然后指定给一个带有特定剔除距离的LODGroup。
https://v.qq.com/txp/iframe/player.html?vid=y0723issf15&width=500&height=375&auto=0
此脚本在场景中被应用于名为“UberTreeSpawner”的对象,你可以根据需要随意使用它。
关于此工具的附注:为了使其它零散对象适当落在地面和其它资源上,在场景中的所有资源上需要有较高密度的网格碰撞体。同时在游戏运行时,这些大型碰撞体不能被使用。 出于这个原因,场景中的多数资源带有二个不同的碰撞体:一个是轻量的,会被PlayerController用在运行模式的实时环境中,指定为默认图层。另一个则用于小树枝的物理效果模拟上,指定为GroundScatter图层。
光照
《死者之书》项目使用了带有实时方向光的已烘焙间接全局光照。
来自太阳的间接光照和来自天空的直接加间接光照都被烘焙到光照贴图和光照探针中。反射探针、遮蔽探针和其它遮蔽源也会被烘焙。另一方面,直接太阳光阳光直射贡献也是实时光照。在使用实时直接光照时,在HD渲染管线中的着色效果最好,它也能让我们给运行时方向光的旋转、强度和色温设置动画。
由于间接光照已被烘焙,我们不能对方向光的强度和颜色进行太多调整,否则它会无法与烘焙光照相匹配。尽管树林能够掩盖不匹配的间接光照,是个容忍度较大的环境,但我们还是不能在这个设置中脱离完整的昼夜循环。
已烘焙光照贴图大多用于地形和少数资源,但我们更喜欢为项目中的石块和峭壁使用光照探针和遮蔽探针,因为它们有尖锐的角度和卷曲的法线贴图,能给项目提供更好的结果。
遮蔽探针
在实时环境中,给茂密的森林添加照明难以实现。 树木的树叶和树枝都有巨大的表面积和复杂的几何形状,因此给它覆盖上光照贴图很不切实际。为每棵树使用单个光照探针可以从下至上给它一致的光照效果。光照探针代理体积(Light Probe Proxy Volume)能实现更接近我们想要的效果,但通过提高网格分辨率来采集精良细节的做法并不实际。所以,我们的高级图形程序师Robert Cupisz开发了这个光照探针。
从艺术家的角度看,这是个非常不错而简易的功能:只需将对象添加到场景中,它就会显示一个体积辅助图示用来缩放,从而覆盖想要的区域,然后以X、Y、Z来设置它的分辨率参数即可。
如果希望场景中某些区域拥有更高密度的探针,它还能允许创建“细节”遮蔽探针。设置完成后,需要烘焙整个场景的光照。遮蔽探针会在这个过程中被烘焙。
通过在上半球发射光线,3D网格中的每个探针会对天空可见度进行采样,并将其存储为从完全遮蔽的0到完全可见的1的8位值。这使得我们在有更高浓度的树叶和树枝的地方使用更暗的区域。即使那里只有几棵树聚集在一起也会如此。
落到树干或石块中的探针完全是黑的。为了避免黑色泄露出来,它们会被标记为无效,并被周围的有效探针重写。
由于探针会对天空的可见部分进行采样,它们只能减弱直接天空贡献。所以,光照贴图会设置为从常规光照探针中排除直接光照贡献,然后探针光照由光照探针和直接天空探针组成,这些直接天空探针都被遮蔽探针遮挡。
这样一来我们就获得了大量低功耗廉价遮蔽探针,它们会对叶子遮挡天空的细节进行采样,为图像带来深度,我们也得到了少量性能消耗较大的光照探针,用来采集缓慢变化的间接光照。
如果想要更清楚地了解它们如何影响场景效果,我们可以使用SkyOcclusion Debug视图进行查看。
这个遮蔽探针API已经加入到Unity 2018.1中,它可以用于烘焙遮蔽探针并从光照探针中排除直接天空贡献,项目中的提供了所有脚本和着色器。
大气散射
我们移植并重用了为《Blacksmith》演示项目所开发的大气散射(Atmospheric Scattering)解决方案。
我们的高级程序师Lasse Jon Fuglsang Pedersen对其进行了拓展,使之可以利用临时超采样功能,从而使外观更为平滑。
HD渲染管线传输
HD渲染管线的默认光照着色器支持多种漫反射效果。它能让你得到带有次表面散射效果的材质,或是就如我们在本项目中为植被所使用的效果,一个更为简单的半透明材质,它只带有透光性。
此效果在二个不同位置设置:
我们需要选择“Translucent”(半透明)材质类型的材质上,输入一个厚度贴图,然后选择漫反射配置,而这个配置则在第二个位置。
第二个位置是漫反射配置设置,我们可以编辑透光效果的其它参数。
注意:我们添加了额外的滑块来分别控制直接和间接透光,从而能够让最终结果有更好的可控性。但这个改动并不遵循PBR原则,所以不会将它加入HD渲染管线。
Area Volumes
Area Volumes被构建在由SRP提供的核心系统上,与Post Process Volumes非常相似。它们的功能根据主摄像机对象的位置修改对象属性。
包括方向光照、大气散射、自动聚焦和WindControl在内的多个对象都有受Area Volumes控制自带属性,因此,如果想要修改当前的光照设置,则需要在对应Area Volumes中进行操作。那些Area Volume对象在主场景中,位于_SceneSettings > _AREASETTINGS目录下,带有后缀“_AV”。
调试窗口
针对使用HD渲染管线不多的用户,现在有一个特定的SRP调试窗口,你可以通过菜单Window > General > Render Pipeline Debug打开它。
通过这种方式,你可以看到独立的GBuffer图层、光照组件或是材质中的特定纹理贴图,或甚至是重写反照率/平滑度/法线。当一些对象没正确渲染或是有其它视觉bug时,这是个非常有用的工具。它会帮助你更快标出问题的源头。
这些调试视图是从着色器自动生成的,编码器能够非常轻松地创建新的调试视图。
有一些调试视图能够从渲染管线调试窗口打开
我们使用这些调试视图来创建在场景背景中使用的树状广告牌。过程很简单,仅需把自定义资源放到空白场景中,然后捕获带有可见反照率、粗糙度和法线Gbuffer图层等属性的截图,然后将它们用来创建自定义的纹理贴图。
优化
虽然优化的大部分内容属于代码部分,但如果你想要拥有合适的帧率,合理设置好资源和场景也很重要。
下面是一些为项目优化内容的方法:
所有的材质都使用了GPU实例化(GPU Instancing)。
我们对场景中的多数资源使用了LOD。
LOD交叉淡入淡出(The LOD Crossfade)功能很棒,它能够给不同细节等级的对象带来好看又平滑的混合效果。但这个功能消耗性能,而且会提升项目中的绘图调用。所以尽可能在大量资源上禁用这个功能。
为了避免LOD之间的可见过渡区域,我们在大型石块和峭壁资源上使用对象空间(Object Space)法线贴图。
注意:这里使用的是对象空间法线贴图,而不是切线空间(Tangent Space)法线贴图,这样做会降低法线贴图的精度。实际上,这在我们那些粗糙的资源上并不明显,但你或许不想要把它用在硬表面资源上。
尽管通过构建场景和遮蔽剔除限制视野距离很重要,但你也要知道,这其中的不少用于渲染场景的绘图调用实际上来自渲染每个阴影的联级地图。
我们有大量来自散落在地形的小型植被资源的绘图调用,有些位置会有成百个绘图调用。通过创建草和植物资源的大型补丁,我们减少了大量绘图调用,现在没有数百个,只有15-20个。
请注意:这会对视效质量有影响,如此庞大的资源,很难避免岩石和其它地上的资源不与草相互切分。
我们使用了图层剔除功能,这是Unity中已有的功能,但却没有任何UI。此功能允许你根据对象与摄像机之间的距离,剔除被指定为特定图层的对象。
Torbjorn拓展了这个功能,使之能够剔除这些对象在不同距离的阴影投射。例如:我们的大部分小型植被资源会在15米左右停止投射阴影,由于有地面上的草丛和其它植物,这个效果并不明显,在25米左右的对象会被完全剔除,不管它们的LODGroup如何设置。
参考资源
《死者之书》环境资源下载:
https://www.assetstore.unity3d.com/en/?stay#!/content/121175
Quixel Megascans资源下载:
https://assetstore.unity.com/publishers/26035
小结
我们将继续分享《死者之书》的创作过程,在下篇文章中我们将探索《死者之书》中创建着色、光照和后期处理等内容,尽情关注。 更多Unity项目创作经验尽在Unity官方中文技术论坛(UnityChina.cn) !
《死者之书》系列文章
官方活动
首期Unity官方在线培训课程
7月18日,Unity将正式举办首期Unity官方在线培训课程,打破地理位置的限制,通过在线一日系统化教学,帮助你掌握和使用Unity。参加完此次一天的在线课程后, 参会者将被授予Unity官方培训证明。[了解详情]
报名地址:
https://connect.unity.com/events/UnityTrainingWorkshop
实时优化,智造收益 - Unity Monetization开发者生态沙龙
8月3日,Unity将于举办为期半天的Unity Monetization开发者生态沙龙!本次活动将与大家共同探讨移动游戏开发与变现相关难点与痛点。[了解详情]
报名地址:
https://connect.unity.com/events/unityads
7月Asset Store资源商店促销
7月,只需在Asset Store资源商店消费满30-199美元,最高可获得价值235美元的5款免费资源,参与活动,获得夏日精选资源包。
活动地址:
https://assetstore.unity.com/g/july-promo-activation-cn
点击“阅读原文”访问Unity官方中文论坛