《天涯明月刀手游》的渲染分析
—
最近,天涯明月刀手游上线了,它是腾讯北极光工作室的重量级产品,应该是做了好久好久了。想当年,天刀端游上线的时候,我还没毕业。现在我也是一只菜鸡游戏客户端开发了。
刚好,周末抽空对它进行了一些分析工作。 我图形学很菜,如果哪里有错误,请各位大佬指正。
本文没有针对天涯明月刀做任何破解行为,工具均为行业非常通用的工具,并且没有做任何针对天涯明月刀的修改。
本文所做工作仅用于行业技术交流和学习,没有用于任何其他方面。
一、渲染流程分析
下图是天涯明月刀大致的渲染过程。

天涯明月刀是一个前向渲染的管线,没有生成GBuffer。
1.1 天涯明月刀在天空渲染之前,利用ComputeShader做了一个Hiz的Cull。
这个Hiz好像仅针对于地形的Tile的渲染,具体没分析,因为我截不到ComputeShader的贴图。
1.2 基于查找表的大气散射的天空渲染。
这次渲染生成了2张图,一张给后面渲染天空,一张给每个物体渲染时候的天空光。贴图不知道是用的啥映射,不像半球的极坐标映射。

1.3 第二个Pass是阴影贴图的阴影生成。
阴影生成后,清理了RenderTarget后,开始了很长很长的前向渲染流程。
主要渲染的顺序是
1.4 不透明物体部分
1.4.1 渲染 不透明场景物体、角色、地形等不透明的物体。
天刀似乎整个游戏的资源加载都采用了Stream Loading,他们的地形采用了预混合,然后使用VirtualTexture来加载。 据大佬截帧分析,这个混合是在加载VT的Tile的时候进行混合的,并不是离线生成的。
如下图所示,分别是2张很大的VirtualTexture,刚开始视角没看到那么多地形的时候,它只有一部分。

采用这种方式的地形系统,我自己觉得,好处主要有以下:
- 每个地形小块的最大混合层数的上限没了,一般手机上最多就3-4种。
- 地形源混合纹理的数量限制也没了。
- 可制作更加复杂的法线贴图,因为法线也是预混合的。
- 节省混合时候的纹理采样次数。
缺点也很明显:
- 这2个纹理好大,虽然利用VirtualTexture延迟加载了,但是等玩家跑完很多地方后,整个Texture还是加载了。
- 预混合纹理不能太大,因此分配给每个地形Tile的纹理分辨率很低。我觉得这是天涯明月刀的地形质感远远不如原神的最重要的原因。
我在这里看到,天刀的某个场景VirtualTexture的大小是22x22个Tile,每个Tile 132x132的像素,格式是RGB565。据大佬指教,这里每个Tile有2个像素的padding,防止缝隙问题。
天涯明月刀的角色采用的是Bone Palette做的GPU的骨骼动画计算。 骨骼动画算了2遍,阴影计算和后面角色渲染都计算了一遍。
现在,手机CPU这么多核心,也许可以直接放到CPU端好了。
采用Bone Palette的好处,我估计应该是没有因为uniform变量上限导致的骨骼数量的上限了。
1.4.2 渲染天空和高空的云。
1.4.3 渲染3DUI。
在这里完成后,它复制了DepthTex,以及Color RenderTarget。
1.5 透明物体部分
1.5.1 渲染水面,包括屏幕空间反射。
前面的复制的Color RenderTarget在这里作为屏幕空间反射的源纹理。
从水面的效果来看,他们的水面的高度图似乎是用FFT预先烘培的,大小是128x128。(我猜的,不一定)。
这里,就是因为前面复制ColorRenderTarget在3DUI之后,所以导致了他们的文字也会在屏幕空间反射里的bug。如果这个Color RT没有其他地方用到的话,直接把这个复制过程放到3DUI前面就好了。

1.5.2 渲染体积云
这里的体积云是用RayMarching来做的。 他们的体积云效果看起来比较模糊,云的SDF的3D Texture是256x256x16. 不过在手机上,这样的大小已经算比较极限了吧。
1.5.3 渲染人物的半透明部分,眼睫毛,头发等。
1.5.4 渲染特效
1.5.5 贴花阴影
这种阴影是比较少见的。正常常见的Forward管线的阴影,一般都是CSM或者最普通的阴影。每个需要接收阴影的物体都要进行阴影的渲染。
天涯明月刀采用了一个比较trick的方式,使得阴影只要在最后2个DrawCall即可完成。我没仔细看这个方法具体怎么处理这个阴影贴图需要贴花的包围盒范围。
1.6 后处理
我看到,正常游玩模式下,天涯明月刀用到的后处理不是特别多,可能是我菜没发现。特定镜头或者情况下有很多,比如拉近镜头DOF,轻功的时候有运动模糊,下雨时候等。我这里分析的主要就三个 Bloom,SMAA和Tone Mapping。
- Bloom的模糊,是先1/8降采样,然后采用Box模糊。对比,原神,天刀的Bloom效果要差一些。
- SMAA是目前最好的后处理的抗锯齿,改进自FXAA和MLAA。它的原理是 先用Canny算子求边缘,然后再利用SMAA的LUT表求需要抗锯齿的边,最后应用。
- ToneMapping 和Bloom的最后一个阶段,是结合在一个Pass中的,这也是优化的常见手段。
二、总结
天涯明月刀大胆的在Android上使用了Vulkan,也使用了Virtual Texture技术,使用了GPU Driven,也就是drawindirect。 另外,天涯明月刀文字渲染采用了SDF做了UI文字的抗锯齿和字体描边,也是一个创新。
总体来说,天涯明月刀魔改了Unity不少东西,采用了一些之前在手机上没采用的先进技术,程序和TA的工作量肯定是非常大的。而且优化的也很好,帧率很高,是一款非常不错的手游。

