37 KiB
拼合内容
生成时间: 2026-02-07 13:57:40
然后我现在再给大家介绍一下,这个三角洲行动中的这个全局光照方案。
我是来自天美第三工作室引擎技术组的魏东陈。
然后讲之前我还是先自我介绍一下,我是15年加入的腾讯,然后最早是参加了乐高无限的开发。
然后到了天美之后,是先后参与了这个穿越火线手游,然后绝地求生、全军出击,还有这个CODM。
就是对我们现在的这个三角洲行动。
我们先看一下三角洲行动的这个总体画面效果。
OK, 我今天会按照这一个顺序,我先简单介绍一下项目,我会把常见的GI方案给罗列出来。
我们再根据三角洲行动这个项目,我们来看一下这个项目到底怎样进行一个技术选型,把这个完整的方案给讲一下。
这个项目现在已经累积了很多的DAU了。
从他第一天开始,我们就希望尽量支持广泛的平台,然后大家一起爽玩。
他所有地图都是单手通发的,就不会说只有一个地图就是在某一个特定平台上才发布,就不会这样。
对于每一个地图来说,就是要求玩家可见的这个区域,我们全都有全局光照的覆盖。
这就带来一些挑战,大家看就是要求所见的区域全都有这个GI的覆盖。
PC和这个手机这是性能差异很大的的平台。
这就是说你选这个GI方案,肯定是有一些拉扯的那我们还是先把所有的GI方案都回顾一下,然后我们再看看根据这个双端的体系到底该怎么选择。
首先是light map,这是最简单和最传统最节省的方案。
然后还有就是像这个volume GI,这个是在PC上可以稀疏化存储的这种光照体质体素数据,它又有高精度,它又显存控制得住是吧?
现在像刺客信条、孤岛惊魂这类游戏都非常广泛的用了。
或者你像手游上这种就是有3D纹理,规整3D纹理的这个volume DI。
因为它有3D纹理,所以说它寻址采样就是比较GPU友好,就节省性能。
然后还有就是像以鲁曼为代表的这个全动态的,它效果又好的,美术迭代效率又高。
那你看这些方案里,如果咱们比运行是性能的话,如果从性能的角度讲,那light map它肯定是最好的,对吧?
他给你给一个2U然后就把这个数据,把这个有微电子给采出来了,然后GI的数据就得到了,就非常的高效。
而且美术可以在局部增大这个light map的文字密度,就得到很高的精度。
然后volume GI的话,它这里是以这种稀疏化存储的GI为例子,它这个数据存储获取就稍微麻烦一点。
你就得在shader里去访问一个树形的体系结构,然后根据这个position去查询到这个光照,最后再还要根据法线去做一个解码。
因为你可你可能又保存了这个SH或者是MND cube这种结构,那这样的话它消耗当然是比lad mab要大一些,但是还是可以接受了。
就从我们经验看,就是说你660显卡就跑一个1080P下跑一个16G那3毫秒以内是没有问题的。
然后对于全动态DI像是roman d这个是没有办法,因为它迭代效率它是非常高的。
但是毕竟它是个全动态的效果,这那的pass的数量就比前两种都多了一个数量级。
刚才是比运行是性能,但是咱们如果比项目成本的话,light bank你虽然效率高,但是你它的项目成本也非常高。
你要制作这一堆2U而且这个麦氏和这个光照不解耦,做起来非常搞人心态的事儿。
而且你一个match到底在哪些地方要分配更多的文素,那迭代起来也绝对就是一个时间黑洞。
更大的地图,比如说像这个长空系统。
如果这全都铺上来的,不是你看你看这个框的数量,这根本就是一个不可能的事情。
那相比之下,这volunt这就舒服多了是吧?
你这没有2U这个烦恼,你迈出和光照解耦,运行师给定一个position之后,立刻就可以有根据算法查到自己所需要的这个数据。
尤其像这种大范围的这长工这种地图,如果你用volume GI,你甚至可以用一个自动化的流水线,就每天进行不停的进行滚动烘焙。
美术只需要拉一下数据就可以得到你所需要的光照,对不对?
再比如这个项目成本,就是像luman还有这些全能快捷,他把这个制作成本已经加压缩到接近为零,没有任何等待对吧?
那在这样一条光谱上大家看越靠近左边,它这个运行时效率越高,但是制作成本也越高越靠近右边,它这个开发者越爽,迭代也越快,但是性能消耗也越大。
这么多方案里,三角洲行,我跟大家说就全都用了全都用了。
包括你大家听昨天的远光八四的分享,还有你如果去看那个COD的分享,大家都是在这一条光谱上都做出了个自己,就是几乎全都用了。
我认为这可以是一种可以说这叫一种趋同进化了。
我们还是看一下这个双端它对GI到底是怎样一个需求呢?
PC这边我们希望当然说是拔高效果,那不用说,但是你不论是lead mp还是vollied MGI,尤其是vollied GI你这精度一旦上去之后,那显存就会出现一个几何级别的增长,对不对?
那PC这边所以你就要时刻提醒自己,就是说如何控制显存。
PC的match它也更加复杂。
如果你在PC match上搞这个light map,那这个制作成本会更大。
所以就希望就更加希望往里面嚼,把它这个制作成本降低这个优势给发挥出来,所以说这里打了四颗星代表对他的一个期待。
手游这边大家可能想不到,就是对于GI系统或者说对所有的系统,首要的要求就是你要把这个包量给我降下来,对吧?
这是体保证手游玩家体验的一个非常重要的一环。
如果你无脑的全都铺了个light map,那包量就会过于庞大。
尤其你这还有TOD的这么一个情况下,手游的性能比PC弱很多,所以你要控制好消耗。
现在你要注意大多数其实它就是普遍手游一个情况,就是GPU瓶颈。
所以说如果你有这个的方案的话,你这个消耗就不要比这个live map增长太多。
这就是我们对他的这样一个期望。
当然受限于性能的话,手游的这个light map使用范围确实还是要更大一些。
OK然后我们这个选用原则就是说我们希望各个平台上都要优先保证运行效率。
这不是说什么2K60FPS,因为多人竞技,你最好要上个120、130、100 44这种,然后在此基础上尽量的提高这个制作速度。
所有的多人体图端我们都用了light map加volume GI的这个组合方案。
当然TC上这个volume I用的就是更多一些。
单人战役的话,因为没有PVP竞技的情况下,就直接用鲁本拔高效果。
因为它这个迭代效率高,事实上能达到更好的一个品美术品质。
OK我们先看这个PCR这个light map,我先说一下这个light map Baker,这是我们自己研的一个ggs红莓器,从CF手游就开始用了,然后一直迭代一直用到三角洲行动,现在已经是一个基于GPU的这样一个烘焙器。
Line map这个东西可以说让人真是又爱又恨,它这个效率品质都很好。
但是它场景到了之后,离线制作的这个也是非常吞噬时间的一个东西。
我们我们又在希局部希望很拉高精度的地方,就还是用了这个light map。
面积最大的这个长空地图,只有这些标记为浅绿色的地方是用了light map。
这个light map上面只有只有人工光和天光的可见度。
Light map它主要是负责室内光照,可以说这也可以让可以让各地图制作局部的各个切块之后,各个美术同志他可以独立的进行烘焙,它不受整体太阳光照方向变化调整的影响。
这个大地图使用lid map的,它的主要限制就是制作效率。
你如果像长虹那种地图,你用了lid map之后全都用lid map,那你可能就是这地图永远就发布不了,尤其你还有这个TOD的情况下。
我们就来看一下PC上覆盖范围最大的这么一个部分,就是它这个volume键,这是我们的重点。
它最大的好处就是大幅的提升了制作效率品质,也能接进来的map。
我会从这个防漏光基础的数据元素,然后存储、拟合、压缩,最后到全世界方案的这样一个顺序来介绍一下这个GI的方案。
我们还是这里我就先得提一句,如果你准备开始用volume MGI之后,它就有一个非常隐私的陷阱。
这是就是经历那么几个项目你才能得出来的这么一个经验。
大家看这个函数图表,横轴代表制作代价,纵轴代表这个GI方案的综合效果。
综合效果就是指画面加运行效率,综合起来这种效果大家看在这个点,这是light map,它有很高的制作代价,但是它的综合效果也确实很好。
那理想中的volume jr是什么?
你应该是大幅提升制作效率,对不对?
然后代价大幅下降,但是它的综合效果下降很小,这是理想中的王俊杰。
但是就非常容易进去一个陷阱什么的。
就是你搞的这种就是你做出来之后确实和麦是解耦了,那程序觉得自己好厉害,然后美术由于工作负担下降,他也觉得很开心。
但是你别忘了,这就是volume GI他自己也有像是漏光这种固有问题。
这个问题如果处理不好就集中,极易造成制作成本虽然下降了,但是画面也有一点下降。
比如说有一点漏光瑕疵等等,或者说你画面没有下降,程序性能大幅下降。
就比如说你运行时必须花一个大代价去解决这个漏光问题。
这种volume GI相对于这个light map来说,大家发现没有,它的总的性价比并没有大的变化。
但是制作团队在做这个东西的时候,它就各有各的爽点。
我前面说了就是说对此对这个性价比提升就是感知不强。
然后最恐怖的时候,就当这个测试回单的时候,要么发现你这个东西效率不太好,要么发现画面有一些什么瑕疵之类的,然后产生很多很多bug的。
然后为了修复这些bug,又得去各种hack解决,反复折腾,然后把这个volley GI的清低成本的优势给搞没了。
说实话就是我见过一些项目是进入过这个陷阱的这也是经历了一些就是这样一些经验教训,然后才我们才开始特别重视这个事情。
这里所以我先提防漏光,就是防漏光。
其实volleyer之间从项目角度讲能否成功的一个关键因素。
所以说我因为我们就要追求高性价比,甚至我可就是漏光,它是一个volume GI就常有的一个瑕疵。
当这个体素的宽度比这个墙厚的时候,那漏光就可能产生你踩踩的踩到墙对面去,对不对?
如果什么时候这个漏光根本就无法预测的话,那制作组来bug单就会非常多。
那这种拉扯很很可能就把这个制作优势,这个制作成本低这个优势给抵消掉。
所以说这个方案必须本身必须能斩钉截铁的告诉美术,美术同事就说你怎么制作才能完全避免漏光。
如果说起来简单的话,那也是真简单,就是把这个体速精度给尽量的提高,但你就别超过性能的预算。
三角洲行动里面是0.25米。
然后告诉美术同事,就是说所有的墙只要超过0.25米,厚度超过0.25米,它就一定不漏光。
那0.25米对于大多数几何体来说,这是一个可以接受的方案。
那运行时三星应用插值的时候,你那你无论说都不可能踩到墙面后墙后面去,对不对?
因为你这个体你你这个墙比体塑要厚,那如果实在碰上必须小于0.25的,比如说铁皮房咱们再想hack的办法。
但是你存在这样一个非常清晰的标准,然后就能从制作层面比规避大多数绝大多数漏光。
但这件事你必须从项目第一天就开始做,否则那你只能运行时去搞个什么算法去防漏光了。
比如说做一个什么世界空间的那个奔驰刀等等。
对于每一个提速来说,我们还是看一下的基础的数据元素是什么。
每一个体系就存一个六个方向的irregular的这个amin cube,其实就是半成明二以来非常经典的一个结构。
像使命召使命召唤黑色行动系列也用了这个结构。
然后运行时是根据法线从这个六个方向里插值得到这个最终结果。
我们必须看一下,就是这个0.25它是一个很高的密度,比较高的精度。
如果你用这个规整的3D纹理去存的话,这显存很快就炸了,轻松给你上8个G16个G所以就需要一个稀疏化存储的方案,就是越靠近mesh我才存储高精度的提速。
那0.25米这么高精度的东西最好只贴着静态mesh版。
这里我们去读虚幻引擎自带的open VDB的存储代码的时候,我们就参考它实现了一个比较高效的方案。
那open VDB它其实也是这个胡迪尼的一个核心组件,提渲染就是很核心的一个组件。
大家看就是这个数据块,它横向大小为64乘64,这是我们一个离线分块存储,每一个数据块就是这么大,这就是GI的数据。
然后每个数据块内部,我按照以4米为精度存储规整的粗糙的体素元素。
这个体数个头大,它这个数量可以虽然它是一个规整的这么一个结构,大家看这就是这些黄色的体素,对于每一个4米的这个提速,我给它各个维度除以4,然后分裂产生64个这种1米宽度的提速,就这些蓝色的提速。
但是这一次我就要求这些蓝色的这一米提速,你必须得靠保只保留那些靠近麦是足够近的,加个阈值。
比如说这里是3米,大家看远处的都舍弃掉了,然后再来一次继续分裂这种一米的体素,然后形成0.25米的体速。
但这次再压缩阈值,要求只保留距离面试表面很近的0.3米的体速,你看这基本就贴着卖是摆了一层。
这样我们就可以形成一个逻辑上的,就是从上到下的这样一个数据结构,一个树形结构。
它其实是个六十四叉树,类似这个图。
我只是我们手机节点确实是从4米开始的,我们没有一个实际上的根节点。
当我们给定一个word position之后,我们怎么定位说这个word position到底对应到哪个0.25米高精度提速上呢?
这个还是我们去参考open ABDB实现了这样一个算法,就是我们先把这个提速数给按照广度优先便利给便利一遍,然后形成一个序列。
这里用二叉树做了一个示例。
给定一个word position之后,怎么快速知道所需求的这个光照数据究竟在这个序列中哪个位置呢?
它在每一个数字节点中,我们定义一个64 bit的exist mask,就是一个bit mask。
它表示出每个节点的64个子节点当中,究竟哪些子节点是保留了的,一代表保留,零代表这个子节点距离max太远就给舍弃掉了。
至于对于这个bit mask实际上相当于一个小型的局部正方体,它包含了规整的4乘4个,一共有64个子节点是否存在的这么一个情况。
任何一个子节点只要给定相对于父节点的这个局部坐标,就可以快速对应到究竟就自己究竟是bit mask里面究竟哪一个bit。
然后你得知道如果你这个子节点是保留了的,比如说是这个一对不对,那它是第几个子节点呢?
其实你只要数这个bit max,从开头到你这个一共经历了多少个一。
那正好C端里面有一条一个叫count base的指令,一条指令就可以帮你做好这个事情。
每个节点里我再保存好这个节点在第一个子节点的下标,比如说这是比如说就这是M再把count face的这个结果给加上来。
比如说是2,那你就可以得到M加2。
那这样就是用很低的代价就可以获得这个子节点在这个数里面这个下标,这里其实利用了一下这个BFS这个性质,就是说一个节点的子节点,它必定在这个序列中连续梦回大邑,然后你最多重复三次这个过程,直到访问或者miss。
然后按照这个顺序的这个序列这个顺序我们再把它对应的这个光照的这这个序列也给排布出来。
那你只要获得到任何一个position,只要查到了自己在树中的这个下标,就可以查到自己在这个光照序列中的下边,然后直接取用这里的数据就可以了。
然后当然运行是你要去采样八次,因为你要做三星星差值。
但是因为有大量的这种硬件方面的指令的支持,所以说这个访问速度其实它是很快的OK但是经过刚才这样的稀疏存储,总体体积依然是比较大的那毕竟每个尺寸它有48个bit,对不对?
它是一个六个方向的一个EAM and cube,那我们希望这个体积还是再小一点。
毕竟你相邻的体速,大家看相邻体速光照这个数值是接近的那我们希望再做一点压缩的处理,另外地图是支持TOD的,对不对?
那每个体数上可能存储更多的数据。
总之我们希望就是每个体数上存储的体积不要受总时段增长的影响。
然后为了你和压缩,我们还是要做点准备工作。
首先还是调用这个open ADB给这个场景,沿着match表面生成一层pro作为这个支撑点数据,这些probe的密度会远比那些提速要稀疏。
每一个proof上给它烘焙一个48 bt的MN的cube。
当然如果有多个时段,比如说一天有八个时段,那你那你就烘焙8份就存储这八份儿都存储在这个数这个游戏包里。
但是probe你可以控制的很稀疏,这些东西它上面的数据它不怕那个数据多。
我们希望每一个体数上,就是它存储的这个数据量远小于原生的48倍数据量,并且不随着时段增长而增长。
因此就可以用距离它最近的四个problem上的m and cube去做一个线性的组合,把这个原生的结果给拟合出来。
那这我其这就是我们希望让这个高纬度的向量上,就是48倍的那些很很好的向量,让这些稀疏的probe去存储。
而这些密集的体素只需保存,只去组合它们就可以了。
所以说每个密集的体系上就只需要存储四个index加四个float,这样只有恒定的16个bit,那就比48小多了。
而且这个相邻的提速的这个index也。
是一样的,那就很容易利用类似游程编码的方式进行进一步的压缩,但这个就不能展开讲了,就时间比较有限OK那令所有提速的这个权重,还有就是所有的这些绿色节点发出来,这些红色的这些边,就他们所有的这权重,还有令所有pro 5上的这些支撑点的这些数据,都可以作为变量变化。
我们就希望调整这些所有的这些数据变化,然后让每一个体素上线性组合出来的这个数值与原生数值这个差尽量的小。
这里用的是差的平方的形式,因为它好求导,然后我们就希望把所有这些差的平方加起来,就这个平方和让它尽量的小,这就是一个全局优化的问题。
这看似不好解决,但是这个函数无论是对于权重还是对于上的这个数值,都很容易把这个偏导数给写出来。
那这就容易多了,对不对?
你看这函数本身它也就是一个对偶图形函数,它也没有什么病态结构。
所以就可以可以直接利用基于导数的这个梯度优化进行数值优化。
这里具体用的就是一个共轭梯度法,这个并没有什么不可想象的困难。
然后具体优化措施就实现了一个基于SMD和面向数据的共轭梯度优化器。
对应于这样一个数据块来说,64乘6 14米单核心9毫秒就可以完成优化。
那实际上生产的时候肯定多核心并行了,平均不到半秒就优化这样一个数据块。
实际上优化这个数据块的时间远小于它烘焙器烘焙它的时间。
然后我们再看经过所有这些优化,大家可以看一下这个显存,这个图放的有点小了。
我给大家说一下,就典型的对于刀锋这个图,它的数据的垂直高度还是比较深的。
但是volume GI的总显存是控制在200兆左右,那这个量是可以接受的这一套说下来,我希望大家注意一下我们的这个思路顺序,就是优先考虑这网里面GI的这个方案的性价比,而不然后一步步推导出说必须用0.25米提速,然后再才有后续所有这些效率优化。
而不是说开发的时候觉得我怎么高大上了,我怎么做了,然后可能那你可能就掉进什么别的陷阱里面OK。
但是我们希望就是PC上GI的这个视距,尤其是太阳光的这个间接光,就能完整的覆盖地图。
注意这个图没有过头map,就是我们刚才说streaming进来那些高精度的铁GGI数据,大概也就覆盖这么远,那肯定是覆盖不了全图的,对不对?
我们就希望以最好有那么一份数据常驻内存。
它只有近景一个tell的GI那么大的大小,但是它把全图的这个GI全都给cover住了,这个该怎么搞呢?
像海岛这个图,这个视距还会更远一点,我们希望所有的视距下都有GI覆盖。
刚才的方法肯定不行,对不对?
这个需要全场景覆盖的这个方案,我们还是用稀疏的提速数据存储,这还是刚才一样的算法。
但这个提速个头巨大无比,达到了8米,是你你也可以调整的更大。
即使覆盖全场景,它的这个总数量也是不多的。
然后我们要求每个体素体体速里面存储的这个数据量,还是必须和48倍是一数量级。
你可以多两倍、三倍,但你绝对不能说翻个十倍、20倍,那是不行的那是不是就是我直接干脆存那个MM的Q不就完事了,那是不是就可以了?
但是这当然是可以,但是不够好。
我给大家看一下,大家看这个巨型提速,这个8米这个大型提速里面如果只有一个数值的话,那你在里面采样,你不管怎么采的,都采出来就是一个数值是吧?
因为你就存了一个,也不是不行,反正远处看去也就是糊的一团,但是总归是不够好。
我们就希望他最好能提供一个和近景接近的这么一个精度。
然后我们就希望大家看这个大cube里面,我们就希望给定一个任何一个XYZ的位置,这个XYZ是这个局部坐标,我们就希望有一个比较紧凑的函数F我输入一个XYZ之后,返回这个XYZ上面的这个光照,那这个返回值还是比较精确。
大家看把这个建筑移除了之后,这个函数F返回的是天光向上的这个可见度。
那么在我这个屋檐房子里的遮挡下,大家看里面是不是比较黑的,这个模拟的还是比较精确的。
但如果这个大Q0就只有一个数值的话,那你采出来就没有这种变化了。
那到底是什么函数?
怎么表达这个函数呢?
这个函数用的是这样一个小型的深度神经网络的宽度为四。
有两个隐藏层的激活函数用的就是VKREOU。
这个体系内部用烘焙器去密集的烘焙,它内部的这个光照数值相当于是提供大量的训练数据。
就是给定大量XYZ之后,这个ground choose的光照数值,然后用它这些大量的数据去训练这个小型的神经网络OK。
然后这个网络里面其实存储量也就是几个矩阵的事儿。
然后这个小型神经网络,它输入是xyzh,然后隐藏层一共是两层。
然后输出是一个单一的一个数值,就是一个luminance而不是RGB。
这就是为了增大这个训练的精度。
推理的话只需要有两个矩阵乘法的计算量,它虽然它是神经网络,但是因为它很小,所以它并不会造成很大运行时的负担。
但它在8米内又可以提供一个足够高的这么一个精度。
然后这个小型网络的函数表达,大家看,因为层数很小,你也用不着什么重度横向pat talk去做什么自动求导。
因为函数小。
可以手动的把里面各个参数导出写出来,然后继续使用一个共轭梯度优化器,就可以把它给优化出来。
是吧?
你用py tok部署到蓝盾服务器上那种流水线上,别自己再出点什么bug,把那个流水线给搞挂了。
大家看这个图,我们从外面看就是这个神经网络对天光可见性的拟合。
这个是不是已经非常接近烘焙器的烘焙效果。
但是你从房子内部看,它当然还是漏光的。
但是你作为远景GI这个漏光是没有关系的。
因为你远景GI都是从室外往从远处往室内看,所以说这个光照你这个光照拟合它也是从一定是从更亮的地方往更暗的地方漏。
因为你更亮的地方这个数值变化,它能造成那个优化器里面更大那个函数优化那个数值的惩罚。
所以说这个算法一定是照顾光更加亮的地方,它才会从室内往室内漏。
所以说它才作为远景点它没有问题。
那我们说这我还是稍微解释一下,这个小型神经网络里面的非线性就来自它上面这一堆lik IREOU。
Lik IRELU大家知道就是max 0.2A乘以a max 0.2AA所以说它这个函数总体上输出一定是一个分段线性函数。
大家看即便是在这些内部的漏光结构上,它是不是也是一个折线的,这样有个多个折线组成的。
所以说它就是用尝试用多个折线去拟合这个建筑的这个形状,这非常有点像是画素描。
我不知道有大家有没有画过素描,你画素描的时候有一种画法,就是只能就即便是对这个圆,你也只能一笔一笔去画直画尽量多的直线去拟合这个圆儿,当然了我们是不可没有尽量那么多的直线的,我们的直线这个折线的数量就是VKR1U的数量。
所以说这个拟合过程就是用画素描做了这样一个类比OK。
然后我们对比一下,这是没有只只有streaming p streaming GI的这么一个范围,还有这就是全图GI的这样一个范围。
OK这海岛站这当然是更远的视距。
我们看一下这个就是同样一个vive下这个监狱的这样一个对比,这个就非常明显了。
OK这就是全世界GI这样一个方案。
那这个它有多大显存呢?
大家看这些都是UR set存储的这些全数据GI的显离线数据大小,这些都是非压缩的数据,这上面显示有多大,存储显存就有多大。
大家看风风暴眼这么大,它大概是22兆,然后刀锋十一兆,监狱是八兆,那这个数据量是没有问题的。
这个数据量就是作为全图来说,这是一个很很合理这么一个数量,没有任何问题。
然后咱们再看一下这个地图,这个攀升取得攀升地图的GPU消耗。
总体GPU性能消耗全都加起来,就是远景加GI加上,就是所有都加起来它是与pray pass接近。
我这就不谈具体多少毫秒,因为不同显卡是有差异的这张图上是3080显卡。
这个可以看到就是当base pass是0.85毫秒的时候,它是0.35。
它的消耗其实更接近深度垂pass。
深度垂pass 0.32就说那这个性能接消耗的代价是可以接受的。
就是你你你用一个接近深度play pass这么性能,把全部的GI都给做出来。
再加上之前这个防漏光已经在制作阶段消灭了绝大多绝大多数运行时也没有任何昂贵的pass去做特殊处理漏光总显存可以控制在二百多兆,这才算的是高性价比。
GI在这些侠这在这些所有问题都没有后顾之忧之后,大幅下降的制作成本它才有意义。
我们还是谈谈mobile这边,总体方案还是LED mab加这个volume GI的这个组合。
由于volume MGI目前没有办法做的像PC覆盖的那么远了,所以说mobile上这个light mab用的范围确实是更大的,对吧?
大家看这个面积是比较大的,但是这个lde mab依然还是只有人工光加天光可见度,那太阳光的间接光还是靠的这个volume。
大家可以看一下这个view下这个使用light map的这个物体,就是这么多。
然后我们可以看一下就是不使用lima b加上这个volume GI的这个区别。
对,大家可以对比看一下。
但是大家注意这个billiam GI这个范围就只有这么远,这是眼前这么64米,再远都是全远景的平均数值。
但是配合着远景的有这个天光可见度,这个lid map这个房屋的看起来还是OK的。
关于light这个mobile上这个volume,它具体这个算法和PC就有比较大的差异了。
Mobile上面手游普遍情况就是它是GPU瓶颈,所以你添加新算法,你不能给GPU添加太多的负担。
如果让GPU去运行时访问一个提速数的话,那就太耗费了。
相比之下手游的PCCPU倒是目前是经常什么八核心?
4加4模式绑定一个比较节能的小核心,用它去来异步的组装的这个3D纹理,那还是比较合适的。
因此去异步组装一个包围相机的3D纹理,然后GPU里只要去采样一下就可以了,就立刻把这个UV电池给拿出来,对吧?
这不比烂的外部就是费多少。
你赖外部是采一个2D,你现在采一个3D的而已,然后手游同样是要离线的去分块存储数据,但是每一个数据块内部,你不能说就是这么稀疏的把它给存储了。
这个虽然省爆量,但是你去访问起诉数的话,那个CPU一定是有大量的cache miss,它就非常的CPU不友好。
你也不能这样暴力的就把给它做一个规整的存储,这样CCPU访问起来非常爽了,但是它这个空间占用就会非常大,就是非常的耗费包量。
大家别忘了说我们手游的一个很重要的要求就是节省包量。
这样我们就做一个折中,就是每一个数据块内部就是分块存储,每一个数据块内部把这个数据也做一个分段连续存储,每个分段内部是一个规整的长方体网格相当于一个局部的小型3D纹理。
但它只包围自己的局部空间,然后实时组装包围这个三相机的这个3D纹理的时候,就这个绿色的大框,它就是那个包围相机的3D纹理。
组装它的时候,把每个数据块对齐到3D纹理中自己对应的那个位置上,然后把这个数据给填充到3D纹理里面去。
当然这个3D纹理肯定是要做各种scoring,然后追求一个稳定的显示,然后分层分蒸的上传到GPU上去。
这里你需要注意的是,你可以多利用手机上这种特有的这种半精度浮点数的这个SMD指令,它它就可以极大的加速这个组装的过程。
然后大家这就到了整个GI方案里代码量最大的地方了,就是这个手游的防漏光。
手游大家注意这个3D门里精度是1米,那你墙是无论如何都不可能做到1米厚的。
所以说这个没有办法通过制作来解决,那怎么办呢?
这就要定义一种叫做iteration of volume的这个体积,就是简称IV。
这个IV是随着建筑一起做的,你可以认为是一个简化的麦氏,就是大体表达出这个建筑的形状。
这个IV其实是一个多面体了,它有多个面组成。
制作的时候要求一个建筑可以由多个IV拼起来,每一个IV必须是突兀多面体。
比如说这个IV的这个房子的核心区域,它是一个正方体,那IV的每个面正好是那这个IV每个面正好是卡在墙里面的那比如这个面它代表了这堵墙,我把它拉出来了,看的明显一些。
所以说就可以在离线根据IV的面片和这个体素的位置,识别出能够导致漏光的那些体素,然后把这些体素与这个面片给关联起来。
那在运行时的时候就可以根据相机在这个面片的前与后这个关系来判断出出这些体素是不是在墙的另一边。
如果是的话,就把这个体素的数值给fout掉。
我们看一下这个但是因为漏光的区域可能涉及到3D纹理里面各个区域,而这个纹理你又不得不分针上传,所以说你就不得不允许有一个滞后更新的这么一个现象。
其实在PVP对战的时候,这个倒是没有人在意的,这个实在是一个没有办法的事情。
这个防手游的防说起来简单,其实它是一个巨大的代码量,它可能是整个所有系统里代码量最大的地方,但其实没有关系,大家看我头发,然后手游的这个数据压缩和端游是类似的,只不过它这个pro不会稀疏很多。
咱们刚才不说了吗?
就是靠近麦氏的地方,每个数据库就是靠近麦氏的地方有这个数据块cover,远离mesh的地方那如果这个数据是什么呢?
那就直接采用这个地方,如果需要数据的话,就直接采用距离操最近的这个pro上的光照。
所以说运行时还去动态生成了一个distant back field,指向每一个位置,距离它最近的那个pro OK。
咱们看一下重点关注的爆量,volume加上这个报量最大这个图GI常规硒鼓达到了334兆。
那如果这个全都用lid map来做的,这个PI的报量会翻倍五倍不止。
但是这么大的地图你全用LDMAB做,那肯定也不太可能的事,就是工期就不允许。
然后这里就稍微总结一下,就是手机上的volume GI仍然是大幅的降低了制作的代价。
对比纯用来的mab相比,这个包量也大幅下降,都达这都达到了目的。
防漏光我们用了IV的方式,也没有造成什么太多的拉扯。
就是这个太阳光的棒子相对于来的map相比,确实是范围小了,就眼前64米这么远。
但是手游上也是确实足够了,总体性价比还是OK的,没有问题。
OK然后我们看看一下这个远景的方案。
是远景的话我刚才说了,就是远景就一个平均值替代,如果再高配一点机器用一个纵向俯拍的2d text。
这里有一个非常重要的是,我们大量的使用了SMD。
正好UE对SMD的这个封装也是非常完善的,就是直接很直观的用这个函数名字,你就不用再去写SMD的时候对应的一个一个那种鬼画符。
然后对,刚才这是多人的部分,咱们再看看单人战役的部分,这就是这个黑鹰坠落。
这个其实能说的并不多,就是黑鹰黑鹰坠落本身开发的时间非常短。
那作为罗那罗美作为不需要让人进行任何等待,这个实时也其实美术对它进行调节,能立即看到光照效果。
其实他那个反复调整的效率,它这个光照品质是更高的。
OK然后黑鹰的lemon没有做二次开发,就是优于我的原生lemon。
那是用的是软光追没,没有开硬光追。
从试验的情况看,就是3080级别以上显卡的时候,用硬光追的这个路面性能才会超过这个软光追,所以这里还是稍微照顾了一下显卡的性能OK。
然后咱们今天就做一下这个总结。
首先就是这个live map需要做取舍,你需要满你只要能满足性能和这个效果的时候,你可以更多的使用这个William GI去提升制作效率。
然后如果比如说你从0.25硬拉到0.1巷light my普遍这个文速精度是0.1。
你从0.25拉到0.1之后,其实这个边际效应是有点递减的。
所以说你可以多采用一下这个volunt来提升一下效率,非常关键的就是你做好防漏光是volume GI跳出性价比陷阱的关键。
甚至你说你做volume GI的话,你应该优先考虑防漏光,然后再想后边那些其他算法OK,然后PC上我们多关注一下显存的控制,然后包边上要多注关注包量,然后还有这个就是像罗曼能带来巨大的效率制作效率的提升。
我相信再过几年,等玩家最低显卡都已经到3080级别的时候,roman一定就是在市面上非常最普遍的一个方案。
OK这就是我今天的演讲,谢谢大家我的车,谢谢大家。




















































