当前位置: 首页 > news >正文

swiper 移动端选项卡_UE4 助力高品质移动游戏(2)-移动平台光照

之前写了一篇针对移动平台优化的文章(里面也包含了PC方面的一些东西):链接

今天这篇文章,来写一下移动平台的光照,先了解一下移动平台的光照特性,然后才能根据这些特性进行方向开发,在这篇文章开始之前读者需要有一定的基础知识,包括对前向、延迟渲染器、ES3.1、Vulkan、VLM、ILC、CSM等一定了解,渲染器可以参考我再Unity板块中写过的Rendering Path文章,ES3.1和Vlukan可以看UE4版本的移动游戏(1)的那篇文章中有一定讲解。

VLM和ILC是代表一中新的体积光照贴图和老的间接光照缓存,体积光照贴图在418默认开启,位于世界设置中的VolumeLightingMethod:

fe6acc5547a57f88aadd45e6a526d137.png

VolumetricLightmap就是新的体积光照贴图,下面的SparesVolumeLightingSamples就是间接光照缓存,新的体积光照等下再说,先说一下给物体设置间接光照缓存的2个质量,或者说叫物体捕获的标准(这么叫可能不太准确),一个物体,可以选择除了不使用间接光照外,还可以选择以Volume捕获,或者Point捕获,只有当前Lightmass处于旧的间接光照缓存时才可以修改这两个选项,他们位于动态物体的Lighting选项卡下:

048ba29e99e1bdb090659c0109281654.png

这两个区别在哪里,我们知道使用间接光照缓存进行烘焙后,会生成许多采样点,这些采样点部署在高密度和低密度的静态物体受光照上,如下图所示:

ac1bccbd069da90a95057b70e82e3d69.png

左边使用的是Point,右边使用的是Volume,区别就在于他们处理动态物体在受光照和不受光照的情况下,阴影过渡的更平滑,如果使用Point,他会以每个采样点的光照信息作为角色间接光照的信息,当采样点较大,角色在环境光线下移动,会看到突然切换的亮或者暗的间接光照,如果使用Volume,他会在一个区域内的采样点信息作为间接光照的采集信息,这个有点像Unity我之前讲过一个光照探针的东西,其实就是越多的采样点,该动态物体则会获取更详细的周围光照环境。

这个蓝色的小点就是当前动态物体在采样点所被影响的某一个点或某一个区域,可以使用以下命令行开启:

r.Cache.DrawInterpolationPoints 1 /绘制采样点

r.Cache.UpdateEveryFrame 1 /每帧去更新采样点(其实不止是采样点,还有光照阴影什么得如果每帧去查看都要开启这个)

这里要注意的是,使用Point或者Volume,是在PC或者主机平台上,在移动平台上他们两个不会有非常明显的变化,就直接理解成没有变化就好了,不用那么纠结。

上面是闲扯了一下关于间接光照缓存的2个捕获方式,下面来说下新的体积光照贴图。

体积光照贴图可以提供更精确的光照质量和动态物体的光影表现,在官方提供的体积光照贴图说明页面有一个对比如是这样的:

b406f2c56957dc99d497e42eb9c932a9.png

我们可以很明显的看到角色脸部和身上的细节表现,在旧的间接光照缓存中,采样点是一个只有存储光影明暗度的小点,而体积光照贴图中,他的采样点变成了每一个体积,而这个体积可以获取来自四面八方的照明环境,照明方向信息,同样一个对比图可以看出来两者之间的差距:

d9d4f7b7e89055989cd54f7d40adfa26.png

这样就有了更准确和精度的带有方向和环境细节的间接照明信息表现在角色身上。


简单的讲了下VLM和ILC,下面就是进入到文章正题了,在移动平台中,我们会遇到直接影响画面表现的很多内容,这虽然是和移动平台的硬件性能有关,但是我们也可以合理的对问题进行一一排查使用适合移动平台的相对内容进行开发获取最佳的质量。

首先我们在移动平台上,使用的是前向渲染,那延迟渲染也不是不能使用,延迟渲染和前向渲染有什么区别,有什么限制,可以去我在Unity分类里写的Rendering Path看一下,所以我们在移动平台上使用的,必然是前向渲染。

移动平台上可以提供给我们使用TAA和MSAA,TAA可以使物体边缘变得较为模糊,锯齿感不会很强,MSAA会消除TAA带来的模糊感,但根据倍数不同,所产生的锯齿颗粒也会逐渐变小,但是MSAA会比TAA更加损耗GPU性能。

关于抗锯齿可以看一篇博文,对当下很多抗锯齿技术和原理进行了分析,我觉得非常不错:

https://www.cnblogs.com/ghl_carmack/p/8245032.html

所以在移动平台上,我们根据自己的需求使用抗锯齿类型,MSAA的采样数量可以在项目设置的Rendering选项卡设置,或者控制台变量使用r.MobileMSAA进行设置,2x就是2x MSAA,这里还有一个控制MSAA质量的命令,叫做r.MSAA.CompositingSampleCount,和r.MobileMSAA不同,前者针对渲染质量,后者针对使用MSAA的采样方式。

下面来说一下光照,移动平台的光照,对主光源,最好的2个一个是static一个是stationary,如果不是特别需要,尽量不要使用Movable,当然随着现在移动设备硬件的越来越强大,使用Movable在一些游戏上也可以做出不做的效果,或者移动端做那种24h的游戏。

在移动平台上使用static光照,是获得最佳效率的最佳方法,缺点就是角色无法投射实时阴影,或者说动态物体无法投射阴影,但是因为阴影贴图已经被烘焙,所以能够获得最低的性能开销,另外在移动设备上static光源可以与动态物体产生被遮挡关系,如下图所示:

ff0db7ef2d2e93ce6fa9f4ca1603d6f5.png

如果对效果要求不是很精确的话,而且如果是那种topdown或者不是特别逼真的游戏,其实现代战争那个游戏整体画面不错,但是3和4的时候角色地面投影还都是做造假处理,也就是角色脚底弄一个圆形向外透明渐变的黑色圆片,5没有玩过,但是看5的一些画面截图好像角色是产生实时投影,而且还有软阴影。

在移动端静态构建后,我们使用的是VLM体积光照贴图,根据场景的复杂程度,我们可以直观的观察到体积光照贴图当前占内存占比,可以使用stat memory来查看:

8a62a1f491a728b2fb3bb43c7f7154a1.png

这里有一点要注意,在PC上预览的体积光照贴图,不是实际手机上预览的,因为在移动设备上贴图会根据我们的目标格式进行压缩,比如ASTC,所以他的贴图也是压缩后的,占用内存应该以ES预览模式,或者真机上的内存占用为实际值,包括texture memory used也一样。

所以如果对效果要求不高的话,追求极致的性能,主光源和天光都应该是static,这样也会减少内存占用,天光的静态无法处理动态物体的阴影,但是当主光源为静态时,动态阴影失效,所以天光在这里其实选用stationary没什么卵用,反而还会造成内存占用增加。

Stationary和Movable,就只说下前者就好了,对于后者,看项目需求使用,效果表现方面如果追求细腻没有前者好,动态光影必然会丢失精度的。但是这个也不是绝对正确,因为可以即便是动态的主光源,还是可以存在静态构建的点光源,如果非要说的话,在这样对比下,一定程度上身边带有构建点光源和动态点光源的质量还是构建后的好一些,不过这样没什么意义因为主光源是动态,你构建了光源会发生变化,而且阴影也不会融合,反而会更假,性能开销也大,效果也更假,除非闲的没事玩那也没什么好说,所以这个东西存在两面性,没有100%的绝对。

Stationary可以允许我们在移动设备上,动态物体投射实时光影,但是会有一个问题,它不像static一样可以直接处理明暗过渡,如下图所示:

89e357c4176324cd5a980d0cbc1a3d0f.png

可以看到静态物体可以产生正确投影,动态物体没有被遮挡。

如果也想要动态物体产生遮挡,我们需要把墙体改成Stationary或者完全动态,如下图所示:

05c9ab1534bb2085f328b21ab352fcc0.png

其实上图中的表现光影是不正确的,为什么呢,因为墙体是可移动对象,也就是说他会实时的产生投影,那么这个空间里面都应该会更亮一些,因为动态物体不会参与构建,所以烘焙时,会忽略当前的墙体,正确的光影表现如下:

933dd3466f1dcf55e16cfd7b7c70e409.png

那么这样效果肯定是有折扣的,但是没有办法,或者说没有100%的解决办法,如果想要内部空间烘焙成相对来说有阴影的虚实关系,同时角色还会实时遮挡,要么就等烘培后,再把想要遮挡的改成移动,或者使用全动态灯光,都可以解决。烘培后改成移动是个临时方法,适合没有动态功能的组件,也就是说他不会参与游戏逻辑,只是个世界对象。

固定光模式下(以下简称混合光照),静态物体被构建,动态物体实时处理阴影,拥有更真实的画面,但是无法处理墙体遮挡角色的影子,我们只能将当前墙体改为移动或者混合光照,这样影子会被动态处理,自然也可以遮挡动态物体和静态物体,同时,如果为混合光照,CSM将会被开启,我们需要配合CSM来进行阴影的设置。

CSM-级联阴影是游戏中常用的一种阴影渲染方法,它是将以摄像机为开始的向远处的横切面开始裁剪,根据用户自定义的可视距离,进行分级渲染,越靠近相机阴影质量越高,越靠近远处阴影渲染质量越低,在PC和主机平台上,可以使用CSM结合软阴影做一个平滑的过渡,近距离使用CSM进行高质量动态阴影渲染,远距离使用软阴影,因为软阴影的质量低,所以适合处理视线外的阴影,同时软阴影过渡比较柔和,在现实生活中也是这样影子不会一直都很实,在配合DFIS可以正确处理间接阴影。

在移动平台不允许我们使用DFIS,包括软阴影,因为这些是延迟渲染器的技术。

CSM有几个属性:

8a73ddae94b9568d108fe781b445fdd3.png

有一个比较重要的值是num dynamic shadow cascades,级联阴影的动态叠加数量,这个直接影响到阴影的精度,质量越高,精度越高,更高的动态阴影对性能损耗也更大,定向光限定最大为4,可以使用控制台命令:r.Shadow.CSM.MaxCascades进行更改,最大修改为10,4以后对简单的光影场景并不明显,如果是很精美的室外场景影响很大。

那第一个可用的值,就是绘制动态阴影的距离了,我这里是5000,这里有一点要注意,就是如上图中的inset shadows for movable objects,我这里取消勾选了,这个的意思是说开启后我们可以使用一种更廉价的阴影技术,而且这种技术是针对移动端的,对动态物体使用一种更廉价的动态阴影,对动态物体的阴影颜色可以单独修改,但是并不怎么好用,而且还会有一些问题,他不会和静态构建或者CSM阴影融合,所以这里就简单做一个效果示意下:

43f17d4fb91b7bb207f597f3b859a54f.png

可以看到使用这种投影,会使用一种更廉价的阴影,自身的阴影细节表现不够,这种情况下可以使用r.Shadow.EnableModulatedSelfShadow来开启对自身阴影的使用。

一般情况下很少使用这种阴影,除非设备或者游戏要求设备很低,比如说游龙传说就使用了这种阴影(虽然不知道他是什么游戏引擎,但是原理一样)。

单独的物体还可以使用独立的阴影采样,动态物体可以勾选single sample shadow from stationary lights选项来启用独立的阴影采样,但是这个仅限于延迟渲染器。

在项目设置的Rendering中,有一项叫Mobile HDR的选项,像Vulkan这些,ES3都支持HDR线性空间,如果关闭后,默认使用的是LDR,针对低端手机使用,另外对于移动平台的光照,我们要限制移动光源的数量,可以使用命令r.MobileNumDynamicPointLights或者是项目设置中的max movable point lights中设置,如果设置大于实际使用的数量,那么多余的没有使用的动态点光源会增加一次着色器数量。

还是在项目设置中,use shared movable point light shaders勾选后,可以让相同的动态点光源,使用同一个着色器,这样的好处是可以减少着色器的开支,但是带来的结果是同一个着色器在不同的环境下会计算2次或者多次,会带来时间上的增加。

ARM公司写过一篇UE4移动设备的优化文章,可以参考:

https://developer.arm.com/docs/100959/latest/optimizations-and-optimization-techniques/unreal-engine-best-practices/unreal-quality-settings

另外EPIC官方对移动设备的优化也有一篇文章,里面描述了LDR和HDR的支持特性:

https://docs.unrealengine.com/en-us/Platforms/Mobile/Performance

还有一篇EPIC官方文章里是需要了解的,比如光照贴图密度,还有光照复杂程度,可以参考文章:

https://docs.unrealengine.com/en-us/Engine/UI/LevelEditor/Viewports/ViewModes

针对关于静态光照烘焙的一些参数,这个其实没有必要做太多的讲解,lightmass构建的参数,可以去看alex以前写过的一个《解密照片级表现技术》的一篇网络文章,地址:

http://www.manew.com/thread-92273-1-1.html

文章最后我们来看一个对比,PC是原版光照测试场景的效果,右边是我转成移动端后的效果,因为移动端很多后期特性不支持,所以肯定是没有办法100%做成和PC一样的效果,只能做到接近,包括反射也会低很多,这里使用了high quality reflections :

3f94fd6cd1214c954aa4108e88d43628.png

相关文章:

  • Linux 中文网站链接
  • python 正则匹配png_Python正则表达式之初始篇:字符匹配
  • jq获取页面高度_jquery常见获取高度
  • 用XML作sql和web应用的桥
  • 梅林安装opkg后安装iperf3_压滤机安装时需要注意的事项和安装后调试
  • 使用VSS-本地练习最基本的用法
  • 操作excel方便么_如何免费将Excel转PDF?
  • QQ斗地主记牌器主程序脱壳并解除使用次数限制
  • 《rust腐蚀》建服视频教学_二年级上册语文识字4田家四季歌朗读+视频+知识点+图文解读+练习...
  • 今天玩得很开心
  • jedispool redis哨兵_应用 | Redis实现 主从,单例,集群,哨兵,配置应用
  • CsvJdbc - Java 访问csv 文件的的JDBC驱动
  • restapi如何传图片_没有网络,电脑如何传文件给手机?
  • 男人必看得5个故事
  • python词云图代码示例 无jieba_python中实现词云图的示例
  • 【翻译】babel对TC39装饰器草案的实现
  • 08.Android之View事件问题
  • 2017前端实习生面试总结
  • Angular 响应式表单之下拉框
  • JavaScript实现分页效果
  • js作用域和this的理解
  • Just for fun——迅速写完快速排序
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • QQ浏览器x5内核的兼容性问题
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • Windows Containers 大冒险: 容器网络
  • windows下mongoDB的环境配置
  • 回流、重绘及其优化
  • 如何用vue打造一个移动端音乐播放器
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • # 安徽锐锋科技IDMS系统简介
  • #HarmonyOS:基础语法
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .htaccess配置常用技巧
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET 设计模式初探
  • .NET 使用配置文件
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .sh
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @ModelAttribute 注解
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • [Android] Android ActivityManager
  • [Android]竖直滑动选择器WheelView的实现
  • [c#基础]值类型和引用类型的Equals,==的区别
  • [C++]类和对象【下】
  • [GXYCTF2019]禁止套娃
  • [IM] [Webhook] Webhook实现IM平台机器人