原神为啥不全局渲染了

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原神为啥不全局渲染了相关的知识,希望对你有一定的参考价值。

首先我还没去破解原神的防抓帧(虽然已经有很多人破了),米哈游法务就不要动我这篇文的主意了。
首先是全局光照部分。因为原神自己宣称是全动态光照……直接光部分好说,反正都已经延迟了,而间接光部分,做成动态的也就是lpv,以及升级版的vxgi。lpv……成本在于最开始的rsm部分,也就是和原始光照数量有关。如果只处理天光,体素再稀疏点还是有可能在手机上运行的。而且看之前有人拆包的结果,里面确实有个lpv的库(顺便一提lpv UE内置,vxgi也有插件进行支持)。
但这种东西,真想在手机上跑还是疯狂了一些。而且原神在时间变动和天气变动时光照其实是有跳变的,如果真是实时GI好像并不会这样,这种跳变更容易出现在多套烘焙数据切换上。而且就原神的画面效果……多套烘焙数据插值也完全能做到。所以我觉得原神使用烘焙probe方式的间接光照还是可能的,即使包里有lpv,也可能只是放着没用,这个要看抓帧结果了。
传统lightmap肯定没用,用了以这个尺度包体不会这么小,而且画面上也没体现出lightmap的存在感。但室内有没有用就不知道了。
路灯一类光源必定用的实时光。毕竟没有lm,只靠probe的精度不容易处理点光的光照边缘。而且原神的路灯是有严重的漏光现象的,因为点光一般不投射阴影。少数几个场景则开了实时投影,估计漏光已经到了不能忍受的程度。其实点光漏光有个visible probe的技术可以处理,在模型上记录实时光照大概允许的角度,不清楚原神用没用,但用了应该能缓解现在的问题。不过他们即使没处理看起来漏光也不太严重的样子。

体积光部分肯定没用ray系的技术,原神体积光本来也不多。窗户应该就是普通的片+粒子尘埃,因为正面看体积光会变弱。路灯外围有个谈谈的体积光,估计是用的球形根据深度算距离积分的方式来模拟的,不是单纯的片,这种只处理单个不重叠的点光的体积光还是比较物理正确的,但原神路灯的体积光很弱,大部分靠bloom,也不好讲。
(好吧,之前没认真看,白天的教堂窗户确实是正常的体积光,但是本身侧面看到的纹路就不像体积光产生的,而纹理在某个角度会消失。而晚上地面上看不到光投入了,侧面看到的蓝色纹理却还在,但转到正面看蓝光就全没了。所以可能就是体积光和片的结合,只是到了晚上,正常体积光就没了或者降低到看不到。
但我还是有疑问的。如果是正常的体积光,那么就完全可以让透过彩色玻璃的光带上玻璃的颜色,但现在这个体积光看着却是纯色的。用ray tracing或者View体素本来很容易做到这样的效果,没做仅仅是因为不好看吗?而且现在窗户的体积光形状其实很不精确,仅仅是这样的效果,做点近似,比如近似为椭球体,就可以简单通过计算获得结果了,类似这个https://github.com/Fewes/VolumetricTracer。
算了,不管他,max说话本来就这样,未必不是如此。但这样依然没有用ray系的技术。
教堂里柱子都没法完全挡住体积光的部分,爆炸性漏光,肯定不是ray的方案。估计就是圆积分加深度遮挡,正好和街灯的方案一样。)

原神的bloom……bloom的具体方案其实早就没啥可说的了,只有卡通渲染控制bloom强度这个事情可谈。原神肯定不是按物理方式处理bloom的,需要在gbuffer写入参数来控制bloom的强度。但有个现象是,他们有些明明是黄色树叶的树木,却能打出红色的bloom来……而且明显不是调色出来的结果,因为是逐物体的。
这说明他们bloom的颜色都是可以变换的。这就需要在gbuffer里输出更多的参数(直接输出bloom颜色或者映射lut)。但做到这样的必要性真的有吗?
而我觉得,这更像是在一般bloom外面叠了个glow。这并不用重新计算一次模糊,直接在用于计算bloom的那张rt上画上额外的颜色,多级模糊后再叠回没有画额外颜色的那张图,这种自定义bloom的方式其实比起加通道更省(但因为有额外pass,只能少量物体用)
抓帧后都能明白。

原神的人物是独立计算光照的,延迟光照时候会过滤人物的部分。人物的光照信息是独立获取的,主要源于间接光R0,实时点光则用不乘NoL的方式应用。但人物的光照叠加方式一点都不正确,显然不是光照直接相加。因为在暗处依然很亮,也不是直接相乘,比较像是锁定了光强的范围。
原神在场景阴影下会做光照的硬切换,阴影下会直接去掉光照结果,让人物正光背光没有区别,这导致人物在室内缺乏细节(虽然正确)。
这里有个我无法理解的设计。原神场景阴影都是实时的,所以无法利用probe来获取,那么即使不想人物出现半阴影,也可以直接用脚或者身体中点什么的采样csm的方式来处理人物——现在看来是这样做的。但即使是这样做,也可以把这个颜色值写入一张小rt,然后叠加颜色,最后人物采样这个颜色,用这个方法来显示个几帧的过渡吧。这个的成本是很低的。
即使要考虑延迟管线的渲染顺序问题也没问题啊。倒不如说,这样搞可以让人物阴影可以直接用上帧的结果,人物的pass不再依赖本帧的shadowmap,那人物和basspass就可以一起画出去也没副作用了。
这个暂且不提。原神人物基本还是崩三那套,而固定绘制的阴影区域现在在光暗处也生效,这样保留了一些暗处的细节,室内没有直接光的情况也不至于不能看了,但因为这个也让一些特写画面下固定阴影和实时阴影连接的地方很违和。
另一个是明暗交界处有了额外的过渡颜色。一般认为是ramp,但通常ramp都没有计算快,所以也可能是公式算出来的。
原神人物完全没有自阴影。这肯定是不好的,虽然是稳,但是自阴影是贡献光照变化很好用的要素,好多游戏用了也没有任何问题,屏蔽脸上的阴影就够了。原神整体配置要求不低,csm精度也很高,直接csm精度都有可能够,不够也可以做per-object的自阴影,限制数量也没啥成本。

原神人物有个边缘发光的效果,是固定左右两次采样深度差算出来的,强度和直接光方向有关。但是这个变的颜色其实是能变化的(切换人物会瞬间亮一下),所以并非后处理(否则就要把这个变化值写入gbuffer太浪费了),那么,就必须在画人物的这个pass能拿到深度,所以即使是延迟,也用了pre-depth?这个需要抓帧确定下。
场景和天空交界处也有类似的描边,但这种就可以后处理直接做了。

原神是有ssr的,只是能够看到明显ssr效果的地方很少。水是ssr做的,倒影绝对不会反射出屏幕内没有的内容,但天空盒是例外。在倒影采样点快出屏幕的时候会渐变为天空盒。
不过这个天空盒也是动态的,上面有云,这个需要花费一些成本来处理。
ssao体现在场景上,效果比较弱。因为原神没有lm,再没有实时ao画面实在撑不住。原神画面就结果来讲虽然还行,但整体画面确实缺少光照细节,看起来很平,几乎全是简单直接光的贡献。虽然这确实更有卡通的感觉,但是“平”的感觉也是实实在在的。
人物和场景靠近的地方不仅有ssao,还有非常明显的椭球距离场阴影。在平时走路的时候也可以在脚附近的阴影处看到这个效果。这个特性是用计算(lut)来代替ray tracing,效率很高,否则如此不明显的效果早被砍掉了。总体效果还是不错的,以后的游戏也可以用。但是算它还是在延迟管线更方便点,前向有屏幕空间阴影流程也差不多,没有也没事,总之透明物体能取到深度图的游戏都能用上。

原神当然还有个视差贴图。它证明了卡通渲染和视差很搭,因为卡通渲染光照简单而且缺乏高光,所以和法线图一直不搭,导致最终结果缺乏细节。但视差的结果还是可以的。
视差肯定是陡峭视差,具体是哪种看不出来,如果是pom……采样数感觉得有16,至少也有8。虽然都是可以接受的成本,在手游上大规模用这种东西也是挺恐怖的。视差毕竟也是ray tracing系的特性。
原神有几个秘境出现了大规模可进入的云海,肯定不是粒子,是ray tracing云。应该是利用了多帧抖动处理过的,手机上理论上是能跑的,但这个云细节和精度还是很足的,有一定挑战。主线没有,放在完全可以不去的秘境可能也是出于一些保守的考虑……但这个云的效果真的不错,得做。
这个估计项目后期实现的,否则大世界顶端那片云海没道理不用的。
下一步就是要想办法弄可交互云了。

对了,还有个脸部法线修正。那东西其实是忽略了模型法线,然后用一张图来完全指定法线的具体位置,并且在计算的时候忽略了光照Z方向。
当然也可以是等价的其他方案。
其实原神这种处理方式……还是稳,但并不是很好,转光的时候太违和了。但确实这方面也没有完美的解决方式。
但用忽略模型法线的贴图来处理法线的方式是ok的,比改模型法线方便多了。

再补充一句,原神没有使用msaa,而是用smaa和taa(默认smaa)。但游戏里并没有感觉到锯齿的存在。所以,msaa很可能是不需要的,这能省去很多麻烦。
当然,原神不用msaa多半是因为延迟管线不好支持的原因。但结果看上去,没有msaa确实是可以的。
UE一直不内置smaa也是个迷。

手机版更新:
阉割了视差贴图,椭球距离场阴影,还有RayTracing云,但是体积光还留着,所以应该是那个球模拟的体积光。
CSM精度距离搞得很低,而且裁剪非常不保守,城里有面墙直接两级CSM都没有绘制导致了显示错误。
不过,距离搞这么近,就能看出原神除了最高一级CSM,其他其实都是有更新频率的,而且频率很低。这样的CSM性能就还行。
视差贴图我看着是完全阉割了。按说替换成一次采样的那个就行了,可能是效果不行?
距离场阴影按说性能成本不高,但是效果确实很不明显,这可能是阉割掉的原因。
RayTracing云整个干掉了,搞成和大世界里一样的方案。
基本上,稍微高级点的特性都被干掉了。所以LPV根本一点使用的可能性都没有。我觉得有可能是用的LPV的中间烘培数据,这也能解释为何包里会有LPV的代码。
原神手机版的性能也就这样,这大概能看出手机能够使用的特性级别,目前很不乐观。如果想使用高级特性,估计还是只能PC用。

但……原神手机也在继续使用延迟管线,而且据其他人反映并没有做onclip的SubPass(这个需要比较高的硬件API),本来性能也会非常糟糕,所以……它性能不好确实也说明不了任何问题。
现在发售的手游比较靠谱的还是继续使用Forward管线,因为SubPass的支持率太低,做不了延迟。那么原神为什么没有在移动端做一个前向管线?是因为真的在目前的特性下做不出来,还是仅仅是项目技术管理的问题?

不过问了下抓过帧的人,大概了解了下情况。原神虽然是延迟,但是和一般F+然后输出GBuffer提供给SSAO和SSR继续后面流程的做法差的也不远。Cluster Lighting其实不管是延迟还是前向版本性能都差不多,也就差一个ColorBuffer的带宽。那么即使换成F+,只是节约一个ColorBuffer,性能恐怕也不会多少提升,说不定还会因为额外的Pre-Depth变得更差。
所谓前向和延迟,也都仅仅是处理BasePass和直接光照时的差异。后面的部分其实大家都差不多,而那部分往往占的比例不小。现在Cluster延迟也就是输出ColorBuffer然后一个Pass完成光照输出到HDR,Cluster前向则是前面一堆Pass直接输出到HDR,两者也就是差一次ColorBuffer拷贝,而类似这种数据拷贝后面还会进行多次,能差多少呢?
只要还想要SSR这些高级特性,恐怕带宽也不容易比原神更低了(当然,前向有参数更加自由的优势,但这并不是性能上的优势)
也就是说,只要你还想要SSR,你也很难在手机上做的比原神好。这就是现况。
有onclip,其实也好不到哪里去。这东西又解决不了切RT的问题,也无法降低GBuffer仅一次读取和写入的成本,只能把N次变成一次而已。

另外……原神现在的性能问题,反正对我这台855plus来讲,主要是发热,而不是帧率。我开全高,只要解锁了30帧还是能上到接近60帧的(反正比30高),但是会火速变成暖手宝。只有在它的默认配置下才能正常玩。而带宽出问题一般也会很容易表现为发热。
一般玩家玩这个,保持默认配置可能会好点。它这个配置多半是考虑了发热和耗电后的结果。而且就算开全低,其实也没有那么差。
(比较建议原神在玩家硬把设置改成红条的时候弹窗提示下可能导致设备发热或者掉电,堵下嘴)
但原神的30帧体验确实不好,它的动画幅度都太大了,帧率低的感受很明显。即使明明是锁30,你依然总会觉得帧率低于30。那些30帧游戏都是控制了物件运动速度的。
参考技术A 因为游戏需要节省原神的运行内存所以不全局渲染了,应该是为了节省内存(手机都15G了)永远的捧哏 : 有道理!原来是这样,我都没想过内存的问题。因为是实时渲染的,不是一段做好的cg,所以没法回放。

以上是关于原神为啥不全局渲染了的主要内容,如果未能解决你的问题,请参考以下文章

为啥lua语言中使用全局变量就会造成内存泄漏

为啥“事件”在 Chrome 中全局可用,但在 FF 中不可用?

为啥 R 中的 ls() 不显示全局变量?

《原神》主机版渲染技术要点和解决方案

为啥全局对象属性在函数后不更新?

为啥全局变量不添加到浏览器的窗口对象? [复制]