《梦幻西游三维版》程序篇:捏脸、表情、体型综合编辑系统

信尧

2022-06-243807次浏览

1评论

7收藏

4点赞

分享

1.使用基础骨骼混合近似顶点Blendshapes的方案用于捏脸及表情的调整,一方面增加了捏脸调整维度,另一方面降低了美术制作成本;

2.开发了基于深度学习的实时表情推断及相机预览方案,将Caffe2集成入Messiah进行实时模型推断;

3.推导并实现了非均匀骨骼缩放技术,体型编辑后无须美术介入即可保证动画效果正确且身高自适应调整。

由于梦幻西游三维版的角色美术为卡通风格,五官、身材比例对比真人角色差异较大。因此需要设计一套合理的编辑系统,使得角色更改更加丰富灵活,在保留原有角色特点的基础上减少极端效果、尽可能平衡满足需求。最终我们选取了从捏脸、表情、体型三个维度的编辑进行开发。为了满足上述目标,在制作过程中我们遇到了如下问题:

1.由于卡通角色眼睛等部位非常大,捏脸若暴露给玩家,调整骨骼过多会导致操作繁琐且效果可控性减低的问题;

现有的解决方案是设置更多的约束,策划或美术调整极值范围,但这样工作量大且不直观。我们的解决方法,是对特定部位使用美术提供的两个基础极值捏脸效果进行差值混合。

2.如何实现角色表情变换增加可玩性,且需要确保和捏脸的兼容;

苹果有animoji进行表情迁移,但仅能在iPhoneX之后的机器使用,本项目开发阶段并无立即可用的内外部解决方案。所以我们从头开发了一整套的解决方案,包括训练模型、全平台集成推断引擎、开发相机UI预览等功能,不仅如此,我们还开发了极坐标圆盘混合表情动画的方案。

3.如何在更改高矮胖瘦等体型后保证美术已有动画效果的正确性;

公司内部有使用模型塌陷、去除缩放的换骨骼方案,但此方案无法开放给玩家动态调整角色体型。我们使用了非等比缩放父骨骼的同时对特定子骨骼进行递归反向缩放和位移的方案、自适应调整角色高度保证动画、相机、脚踏地等关键表现在无须美术干预情况下的正确性。

我们在一些特定部位采用了骨骼混合的方案。

传统上,基于骨骼的捏脸均为调整单一或某些骨骼的变换完成。如果某一调整类型涉及多根骨骼,通常需要美术提供约束关系,并且给定各骨骼的调整范围。如果涉及骨骼较少,此种方案可以通过填表完成,我们实现了此方案并提供指令让美术同学能够较为方便的完成工作。然而有些部位的调整,美术同学认为需要调整10余根骨骼来完成,这使得此种表格方案成本极高近乎不可能完成。

传统填表方案

我们针对此项需求,提出了在两极值捏脸部位之间进行差值调整的方案。

首先增加3ds Max动画插件导出两帧差值的功能。动作美术只需在3ds Max中制作两帧极值时的某部位捏脸效果,导出工具计算这两帧效果针对原始面部骨骼的差值并生成相应文件。捏脸系统则在运行时载入此差值文件,根据用户输入对骨骼变换进行插值,从而使得玩家可以方便的调控相对较少的参数、驱动较大的部位改变,且此种变更的效果可以在美术的掌控之下。

捏脸部位差值方案(图为美术上图效果自动生成的边界值)

我们实现了两个较为独立的调整方案,一种是用户使用手机摄像头实时表情迁移、捕捉的方案,另一种是圆盘混合表情动作的方案。

1.实时表情迁移、捕捉

对于实时表情迁移、捕捉,我们首先探讨其使用骨骼变换实现表情变换的可行性。

我们研究了苹果ARKit的Animoji实现,此方案制作了52个基础表情,并求出其与基础表情之间的空间顶点差值作为Blendshapes,并实时的提供这52个Blendshapes的权重参数,将之进行线性叠加后应用于基础表情之上。然而基于顶点的Blendshapes方案有如下缺点:

1.美术不熟悉其制作工具链且不能很好的区分角色、动画美术的工作职责;

2.效率较低,顶点混合通常在CPU完成,而骨骼蒙皮则可以在GPU完成,这样限制了我们在大世界中应用此种玩法;

3.和动画系统的兼容性问题,捏脸且改完表情后再叠加面部动画效果很可能会有意料之外的变化。

Blendshapes公式
Messiah采用的谷歌LIinear Blending Skinning(LBS)公式

因而我们决定尝试使用骨骼蒙皮的方案。

由上述公式可知,Blendshapes是对顶点的线性组合,而LBS系统中顶点又是对骨骼的线性组合产生,因而我们可以将表情的改变转换为骨骼变换的线性组合。通过这个理论基础和若干实验,我们实现了使用骨骼差值实现顶点差值Blendshapes的方案。

首先美术通过上一节捏脸方案提及的骨骼差值导出工具,生成52个基础表情与原始表情之间的骨骼差异,我们就可以通过提供52个维度的参数来控制表情的变化。开发此功能的同时,我们在UE中对准基于MorphTarget的效果,保证骨骼方案驱动表情实现的基础正确性。

在保证表情驱动的实现正确性后,我们着手研发如何通过图片或视频获得表情参数从而驱动上述基础表情生成整体表情效果。

我们尝试了传统的Gauss-Newton迭代优化方案,虽然收敛速度较快可以满足实时性要求,但是数值稳定性不够,Landmarks的结果会大幅影响表情效果,因而我们转向深度学习的方案。

训练调参的过程较不展开描述,但是确定以下优化是有帮助的:L1损失的效果强于L2、特征融合对整体结果提升较大、使用人脸识别做参数初始化、多目标学习(即使最终结果不用在预测上)对结果提升有帮助。最终我们使用了ShuffleNetV2的0.5X作为整个网络的基础,在此之上应用上述经验做了较大幅度的改进,即使为了满足实时性要求降低网络参数数量,结果也通过特征混合等方式得到了弥补。

ShuffleNetV2的一些参数, 本工作使用了0.5x的网络作为基础网络
Multi-task feature-fusion networks, 本工作应用了其部分思想对ShuffleNetV2进行改造

基础表情、参数推断实现之后,我们考虑如何在多平台进行实时运行。我们在Messiah引擎的Windows、iOS、Android平台分别集成了Caffe2、OpenCV的运行时,然后首先将PyTorch模型导出为ONNX,再将ONNX格式转换为Caffe2支持的init.pb、predict.pb模型。同时我们在引擎中以插件的方式将一部分推断代码用C++驱动Caffe2来实现,最终使得整个流程可以在Messiah引擎中正常工作起来。

之后我们实现了获取底层相机数据流用以推断和UI界面预览。iOS上主要使用了AVCaptureVideoDataOutput进行视频流截取、Android平台上主要使用了CameraCaptureSession进行此项操作。二者均有大量平台相关细节需要处理,如权限、尺寸、贴图生命周期、压缩格式等等。至于预览方面,本工作均使用平台的Native贴图交由引擎ITexture进行管理,提升了效率,最终由Shader将实时视频图像绘制在UI上。

Android平台相机硬件I420/NV21压缩算法转换实例

2.圆盘混合表情动作

除此之外,我们还开发了圆盘混合表情动作的方案。我们将角色表情归为喜怒哀三类,每一类提供三个混合位、总共提供6-8个美术制作的表情供玩家混合替换。此处我们选择使用动画驱动的方式来完成此种表情方案。我们制作了如下图的Graph,将用户的圆盘调整通过极坐标表示驱动Graph生成玩家的表情。这种方案不仅给了玩家更多的操控选择,也使得和捏脸、动画系统兼容性更方便。

圆盘混合的表情Graph

不需要重新做骨骼!不需要重新蒙皮!不需要美术!体型直接交给玩家自己编辑!编辑后适应所有时装和动作!

1.背景知识

这是某角色的骨骼文件,表示T-Pose状态下各骨骼的从属关系以及骨骼空间矩阵,这里的矩阵代表该骨骼在它父骨骼空间所在的位置、大小和方向。

举个例子,我们看到Bip001 Spine是Bip001 Pelvis的子骨骼,Bip001 Spine的矩阵代表这个骨骼相对于父骨骼Bip001 Pelvis空间的方向、位置和大小。

①所有骨骼的矩阵都是相对于父骨骼坐标,如果想知道某子骨骼在整个模型空间的位置,需要相乘它以上的所有父骨骼,逐层递进;

②根骨骼的坐标系就是模型空间的坐标系;

③每个骨骼都是有方向的,骨骼编辑器里点击某个骨骼显示的三个轴是该骨骼自己的方向,该骨骼所在的骨骼空间的XYZ方向要点击它父骨骼;

2.实现原理

假如要对某骨骼进行平移t和缩放s,我们需要用一个矩阵Modifier表示我们的t和s,用这个modifier乘以该骨骼T-Pose骨骼矩阵。

Modifier乘以Bip001 Spine的T-Pose,实时渲染改变后的状态

①所有骨骼的变化都是通过编辑modifier来改变,而不是直接编辑骨骼矩阵。因为对于引擎来说,它不记录骨骼编辑后的状态,而是每帧计算modifier乘以T-Pose;

②Modifier左乘和右乘T-Pose是有本质区别:上面提到,骨骼自身是有XYZ方向的,它所在的坐标系是父骨骼的XYZ方向。左乘是以骨骼自身XYZ轴为参考,右乘是以父骨骼XYZ方向为参考。举个例子,骨骼A是骨骼B的子骨骼,对骨骼A进行位移t=[t1, t2, t3],如果左乘,那么骨骼A沿自身XYZ位移t,如果是右乘,那么骨骼A沿B的XYZ方向位移t;

③改变体型某个部位往往需要同时编辑多个骨骼,每根骨骼需要同时缩放和位移。而且重点是,我们要非等比缩放,比如想要脖子变细长,就需要脖子骨骼X轴缩小的同时Y/Z轴扩大,而且幅度各不相同;

思缩放方向和幅度、位移范围和幅度、旋转等等都可以通过配表设置,让策划和美术决定每个部位控制哪些骨骼和变化的尺度;

3.遇到的难点和解决思路

(1)缩放具有传递性

问题:父骨骼缩放会导致子骨骼也缩放,下面这个图看着怪怪的

解决方法:要对子骨骼进行反向缩放。例如父骨骼scale 3倍,它所有子骨骼都要scale 1/3倍。假设父骨骼A,子骨骼B/C/D,孙骨骼E/F/G,只需要对子骨骼B/C/D这层反向缩放,不需要处理再下层的骨骼E/F/G;

但有个情况要注意,当玩家需要对子骨骼缩放,切记要在考虑所有父骨骼对该子骨骼的叠加影响。

(2)父骨骼缩放会影响子骨骼位移

问题:可以看到缩放脖子,会影响头、肩膀骨骼的位移,因为脖子是它们的父骨骼。如下图:

解决方法1:一开始我们的解决方式是,缩放父骨骼的同时,对指定部分子骨骼反向位移。如下图:

解决方法2:后来直接通过位移头部,来达到缩放的效果。从这里可以总结出,很多缩放问题,其实可以通过位移来代替。如下图:

(3)缩放身高(腿长)时脚下穿帮

问题:因为缩放身高但模型高度不变,所以脚下会穿帮。

解决方法:我们在初始化时记录根骨骼与脚趾骨骼之间的高度差,之后调整任何部位都实时运算根骨骼与脚趾骨骼之间的高度差,跟初始值作对比,然后对根骨骼进行位移调整。

评论 (1)

0/1000
网易游学APP
为热爱赋能
扫描二维码下载APP