英雄联盟手游截帧分析(持续偷塔中...)
小猴哥TA

前言

我从高中就开始玩英雄联盟,上大学的时候一天最多能玩18局,最高段位是大师,大二时由于一直打不上王者觉得自己没天赋,因此就弃撸了,因为喜欢游戏所以放弃了物理专业屁颠屁颠地转到计算机去了,此次出手游必定是要回味一下年轻时的心动哈。

BlockNote image

登录界面

BlockNote image

特效贴图+Mesh做出 闪电柱的效果

5_副本.webp

用骨骼动画做出人物摆动的效果,(动图有点压缩,这种2D展示界面效果很赞,给美术同学加鸡腿)

6_副本.webp

这个暗角效果很灵性,强化视觉中心(图小可能看不太出来)

7_副本.webp

整体效果

8.gif

英雄展示界面

以下都是分析蛮王哈,毕竟第一个拿五杀的英雄

BlockNote image

展示界面里的东西都是常规操作,唯一可以注意的点是,用了一张2k的背景图贴在一个圆柱上去模拟景深的感觉。因为视角是固定的,所以可以做这种trick,将前景与背景结合得好,即省资源效果也OK。

10_副本.webp

另外一点就是相比于PC上的BlinPhong那套人物渲染,移动端使用了PBR算法,增加了金属质感,人物的皮肤也是用SSS效果


场景比较暗,所有美术同学又补了一盏灯,增加金属高光与皮肤的红润散射效果(目测是偏红色的聚光灯,只照亮英雄)

11_副本.jpg

整体效果

12.gif

人物渲染

模型

13_副本.jpg

截取的数据长这样,也没有直接的数据名称

BlockNote image

根据经验推测

TEXCOORD0是 Position

TEXCOORD1是 UV

TEXCOORD2是 UV2

TEXCOORD3是 Normal

TEXCOORD4是 VertexColor(因为有四个分量)

meshData.VTX.Add(int.Parse(words[index++]));
meshData.IDX.Add(int.Parse(words[index++]));
meshData.Position.Add(new Vector3(float.Parse(words[index++]), float.Parse(words[index++]), float.Parse(words[index++])));
meshData.Texcoord0.Add(new Vector2(float.Parse(words[index++]), 1f - float.Parse(words[index++]))); //uv颠倒了
meshData.Texcoord1.Add(new Vector2(float.Parse(words[index++]), 1f - float.Parse(words[index++])));//uv颠倒了
meshData.Normal.Add(new Vector3(float.Parse(words[index++]), float.Parse(words[index++]), float.Parse(words[index++])));
meshData.VertexColor.Add(new Color(float.Parse(words[index++]), float.Parse(words[index++]), float.Parse(words[index++]), float.Parse(words[index++])));

完整代码链接:

https://github.com/ipud2/Unity-Basic-Shader/blob/master/CSV2ObjLOLMobile.cs​github.com/ipud2/Unity-Basic-Shader/blob/master/CSV2ObjLOLMobile.cs

顶点数量

展示界面 英雄 6W

游戏内 英雄 1w

导入Blender效果

15_副本.jpg

贴图

AO信息是单独的一张贴图,其实可以直接放到Mix贴图的Alpha通道就行了,节省空间。

用Mix.B 的曲率 与 NL 去采样预积分贴图模拟次表面散射效果。

//采样代码
float3 SSS = tex2D(_SSSMap,float2(NL*0.5+0.5,Mix.b)))

NormalMap没必要整2k,1k足矣 (这是制作错误???)

16_副本.jpg

这张Mix贴图RGB通道分别是 光滑度 金属度 曲率

17_副本.jpg

存在的一些问题:

1.红色的部分 死黑,这是间接光不足导致的(就算是一块黑铁也不应该是一团黑的效果,)

2.黄色的部分 应该是一个绿色的发光,加上Bloom有点闪闪泛光的效果,可以把Emission贴图单独拆出来(也可能只是一块普通的宝石哈,没有自发光效果)

3.BaseColor贴图中有居然有高光信息,这是传统BlinPong的那套做法的,非常地不物理,可以猜测英雄联盟手游项目组应该是直接拿端游的那套资源 在上面加了点PBR效果。

18_副本.jpg

一个正确的PBR贴图应该是长这样,每个通道只负责自己的事情,其他的交给算法就行:

19_副本.jpg

还原渲染效果

UE4还原效果

20_副本.jpg21_副本.jpg

用UE4也拯救不了。。。(我太菜我太菜)

22_副本.jpg

Unity还原效果

Unity默认的PBR算法非常地丑陋,因此我使用了改进的PBR算法:

  • 直接光漫反射 :DisneyDiffuse (考虑Roughness的漫反射,在暗部比直接用Basecolor/PI 更细腻 )

  • 直接光高光 :GGX (抄袭UE4)

  • 间接光漫反射:SH(Unity 自带的球协函数)

  • 间接光高光 :IBLCubeMap * NumericalFitting(参考使命召唤黑色行动2,表现金属亚光质感会更细腻一些,且比采样BrdfLut速度快)

PBR实现原理部分请参考 我的另一篇文章 光照模型的PBR部分: 一文看懂光照模型

(没有加预积分次表面散射皮肤的效果,因为这个效果在这种皮肤上表现起来太挫了)

23_副本.jpg

调个色,皮肤部分表现好看了,但是金属质感又不行了,都是贴图的问题,讲道理,这种展示氪金的界面,英雄应该做得更精细一点,比如把皮肤与盔甲拆开,用两个Shader分别表现,PBR的算法当然不适合表现皮肤,皮肤要单独做效果。

24_副本.jpg

场景渲染

地图 是由几张2048x2048的大贴图块组成的,手绘的阴影信息,在风格化方面肯定比直接烘培得更细腻,手绘适合这种需要精细控制的小场景地图,地图太大的场景没法手绘哈

25_副本.jpg

地图上的石头贴图

26_副本.jpg

场景之外的背景图片

27_副本.jpg

脚下的Buff圈 使用一个圆形Mesh + 一张Alpha贴图

28_副本.jpg

蛮王Q的回血效果

29_副本.jpg

石头野怪的攻击范围

30_副本.jpg

草是一堆合并的Mesh面片加上Alpha贴图做的,使用AlphaTest

31_副本.jpg

双Pass挤出模型外法线 描边

32_副本.jpg

UI部分

33_副本.jpg

小地图图片+战争迷雾Mask(128x128)

34_副本.jpg

几张小贴图 做出敌方攻击水晶时的 警告提示UI

35_副本.jpg

整体效果

36.gif

对比一下农药

37_副本.jpg38_副本.jpg

农药也是用了PBR算法。移动端用PBR做风格化渲染表现最好的还是决战平安京(颜值与吸金没有很大的相关性)

39_副本.jpg

以下为个人观点:

手机上英雄联盟画质 UI 整体的美术质量都比王者荣耀好,但在游戏操作上以及整体的游戏体验上都没王者荣耀好,节奏比较拖沓,许多pc上的英雄做到手机上要么无脑强 要么太难操作,玩起来没王者荣耀那么爽快,但英雄联盟依然是天下第一!!!我要氪10个648!!!

总结:

总体来说,英雄联盟手游并没有用到什么风骚的渲染技术,还是以还原端游的美术效果为主,且为了在更多的手机上跑起来做出了一定的效果牺牲。相比于端游的纯手绘BlinPong那套做法,只是采用了PBR算法,多了金属度与光滑度贴图,增加了一点金属质感,但并没有完全得走PBR流程,美术资源也不符合PBR规范,估摸着还是想经量还原端游的手绘质感!