以上!!!!
一、光与影
游戏中的影子大致可以区分为以下几类:
1.场景的静态烘焙阴影
游戏中的场景应该主要还是基于lightmap实现的静态阴影。对于植被并没有计算lightmap,其实我感觉可以在草等植被的下方利用AO去改善以下草等植被的光影效果的。
因为开放世界的超远视距,我猜测,游戏的lightmap是分3个级别的。近距离高精度的lightmap,中距离低精度lightmap,远距离烘焙顶点色lightmap。
诸如草这种植被,是不进行lightmap的烘焙的
近距离下,灌木丛还是有lightmap的
中距离下,灌木植被阴影消失
这种超远距离下的lightmap可能就直接烘焙到低模顶点色上了
这里顺便补充一点,因为时间有限,随便看了几个相关视频,所以并不清楚游戏中是不是有实时的场景光影,所以静态烘焙这部分也只是猜测。如果有实时的光影变化的话,我可以再提供几个思路,一个是distanceShadowMask的思路,就是远距离烘焙与近距离实时结合。另一个是预烘焙多角度lightmap思路,就是提前将阳光多个角度的lightmap进行预烘焙,通过插值进行过度。我记得哪个游戏好像用过,我有空找一下,后面补上。
2.静态物件模拟实时投影
因为草是不烘焙lightmap的,但阴影下的草又如何变暗呢?还有角色走到阴影下面,又是如何处理的呢?应该是使用的lightprobe,就是光照探针。
使用光照探针实现明暗处角色的区别,草也一样
光照探针沿着阴影边缘里外布置两排(保证暗部小球可以被阴影遮挡,有时候,可能会根据光照角度稍微倾斜,而不是上图的直上直下)即可实现这种效果
3.实时阴影
这部分主要用来实现可动物件对场景的实时投影。从我的观察来看,游戏中的可动物件的实时阴影是使用的ProjectShadow实现的。就是设置一个与光照角度一致的正交相机跟随角色进行拍摄,设定一定的拍摄范围,并在边缘进行阴影过度。然后使用Project将渲染的图投影到地面即可。好处是投影的距离可控,投影的物体和接收阴影的物体可控,阴影分辨率高,且不进行灯光深度绘制的草上也可以绘制阴影,一句话就是性能较好。
角色的阴影投影到草上(草是不会进行灯光深度绘制的,要实现阴影,只能如此)
缺点自然是无法实现真实的阴影投射和在阴影下会产生双重阴影的问题。
因为阴影接收体仅包含地面和部分地表物体,因此,可动物件之间是不会相互投影的
游戏对双阴影进行了修复(其实也简单,接收阴影体设置好阴影最低阈值即可),细看还是能看到角色投到墙体上的更深的阴影。
PS:却产生了一个意外效果,模拟了AO,哈哈
4.体积阴影——云影
目前游戏中我看到的相关的体积阴影只有云的影子。说体积阴影貌似也不确切,毕竟云也是粒子面片,不是体积模拟。做法倒是也简单,所有非特效物体的材质中内置一张明暗噪波图,然后以世界坐标的xz进行采样,并添加UV动画,来模拟云投射到地面的影子。就是说与天上的云其实没啥相关性。
诸如此类的图即可
嗯,对于室内呢,肯定是不会受云的影子影响的,所以还需要增加一个判断。例如跟随角色增加一个垂直照射的相机采样当前位置的深度,采样云影的时候,计算以下顶点距离垂直相机的距离与深度比较即可(诸如雨雪等的垂直遮挡也是这么做)。或者更简单粗暴点儿的话,就是无视就好了,毕竟就算是现实中,大片云飘过,屋里也是会暗一下的。
5.角色脸部卡通明暗
米哈游的卡通渲染,在国内一直是做的很牛逼的了。尤其是脸部非常舒服的明暗过度以及鼻翼、三角区的特殊阴影表现。这部分因为比较特殊,我这里就详细介绍一下其相关原理。
非常舒服亮眼的卡通阴影表现
这部分的实现,其实知道原理的话,也非常简单。
首先,卡通渲染的光照修正主要通过两种手段进行。
(1)
最早期的日本的模型法线修正法。在3dsmax或其他三维制作软件中,对模型的法线进行修正,例如将脸部按照球面将法线整平。这部分可以通过脚本进行自动实现,从而提高效率。
通过法线修正,让脸部的光照明暗更加“卡通”
(2)
从罪恶装备X开始兴起的AO图修正法,这方法,崩坏3也采用了。就是通过绘制AO图的方式,对光照的数值进行修正。
就是下面那张附到模型之后,看上去类似AO的贴图效果
这是我目前知道的主要的两种手段,一般来说,两种方法会混合使用。法线修正可以提供比较整体的卡通光照效果,而AO修正,则可以实现更加细节上的调整。
而诸如游戏中这种细节上的修正,更大的可能就是使用了AO图进行修正。将脸部三角区这种会更久的受光部分绘制浅色,将鼻翼这种更早进入暗部的部分绘制暗色,就能实现上图的效果。
顶上的暗部表示头发阴影,浅色是三角区,深色是鼻翼暗部
但是,但是这里产生了一个问题。因为鼻翼一旦绘制了深色,虽然从受光进入背光时,会更快的进入,是对的。但当从背光进入受光时,因为鼻翼的角度,应该更快的进入受光才对,但这里,仍然会因为AO的问题,延迟了变亮的时间。三角区的问题也一样。从背光进入受光时,提前受光是对的。但从受光进入背光时,因为角度,是应该提前背光的,但浅色却让三角区的变暗延后了。
光照从左往右,右侧的脸,背光部分是正确的,但受光部分的明暗明显不对
所以,这样简单的绘制一个颜色显然是不行的。道理这里也已经很明了了,光影的绘制,是需要基于受光和背光两种的。受光时,鼻翼更早进入亮部,背光时,鼻翼则首先变暗。三角区则相反。所以,可以绘制两张图,一张绘制受光情况,一张绘制背光情况,如下:
左侧背光时采样,右侧受光时采样
而判断是否受光,只需要判断相对于脸部的朝向,灯光的朝向向左还是向右即可来决定。
嗯,鉴于米哈游官方并没有进行相关解密,且我们项目也在使用我的方法实现该效果,所以这里就不进行更详细的说明了。
目前我本人实现的效果图
嗯,主要的光影部分就说到这里。下面说物理(模拟物理)。
二、物理的模拟
这里主要说一些类似物理相关的东西,例如:IK,水纹,地表属性
1.脚步IK(反向动力学)
最早知道IK这东西,还是我在昱泉国际的时候,有幸参与了流星和射雕三部曲的相关开发。之后很久,在国内游戏中就几乎再也没见过相关的效果,直到今天的原神。它的效果就是如下:
脚部位置会根据站位的高低差进行自动修正,避免脚部穿插进地面
这部分的实现,是通过检测玩家脚部的地面高度位置和法线,自动对脚部进行位置的修正。
通过默认站姿,获取脚步位置(射线检测)地面的法线,进行脚步角度调节。获取高度,进行大腿旋转角度、膝关节和脚步新位置的调节
据我所知,IK的调节是通过对新位置的多次迭代来进行修正的。
游戏貌似只对待机进行了修正,其他动作还是会穿
当然,游戏中,对地面的信息获取,可不止于高度和法线,还有其他东西,后面会说。
后来看到还有爬墙,还以为做了类似爬梯子的抓取位置定位功能呢。这样,手部,脚步IK就全了。不过结果并不是,只是墙面的UV进行了对齐。
手部位置对齐了墙的缝隙,脚步就差了点儿。调整一下UVScale会不会就能对齐了?项目组肯定试过,不过可能因为砖缝过密,就放弃了
当角色从水里移动时,水面产生的涟漪。不过游戏中只是播放了粒子动画,且涟漪也是正圆型的简单涟漪。
不论移动还是静止,都是圆形的涟漪
其实也可以试试,实现一下三角型的涟漪,不是更有感觉吗?
坦克世界中通过顶点运动和法线扰动产生的三角涟漪
美术绘制三角形涟漪纹理,做类似圆形涟漪相同的扩散粒子效果(或者用UV序列帧实现)。然后程序端,根据角色的移动与否,播放原型或三角形粒子特效。如果是移动的话,还得在播放三角涟漪效果时,根据上一帧的位置,对粒子特效进行一定角度的旋转,让三角涟漪的顶点一直朝向运动方向。
3.地表属性
游戏中,地面是分为很多种类的,且人在上面会有不同的属性或行为。例如水面会潮湿,湿地会有脚印,干地跑动会有尘土,草地会有碎草等。
潮湿地面的脚印,脚印本身,用粒子效果即可实现
这部分实现其实不难,主要在于工具流的实现。
这里说下我的方案:在刷地形纹理的时候,将地表的纹理属性绘制到纹理的A通道,例如:像素颜色0~10表示湿地,30~40表示干地。然后正常进行地表纹理的刷制。shader中使用开关进行地面A通道值的绘制,并根据混合纹理的权重,取最高权重的纹理A通道值作为地面A通道的主属性。并根据权重值,对属性值进行0~10的衰减。例如:该位置通过湿地和干地纹理进行混合,混合值为湿地0.8,干地0.2。则该位置的A通道主属性值就是0~10的湿地。再假设权重值从0~1对应属性值进行10~0的衰减。则这个位置的属性值就是8。
地表制作完成之后,就可以使用工具,将地表A通道的值烘焙到地表顶点色上了。
然后,游戏中就可以在修正IK的同时,返回角色位置的顶点颜色,来进行对应地面属性的表现了。
当然还有很多办法进行实现,例如摆放属性标识面片等。
下面说一下游戏中的植被——草。
游戏场景中是存在大面积,很密集的草地表现的。这部分如果使用通常的渲染方式,消耗是很大的。要实现甚至在手机上也能运行的效果,只可能使用ES3.2才可以使用的GPU实例化渲染了。
目前Unity一共支持三种GPU实例化渲染接口,