UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - live2d
type: channel
link: https://blog.uwa4d.com/tag/live2d/
items: ​Live2D 性能优化

​Live2D 性能优化
type: item
date: 2019-12-17T08:03:00+02:00
description: 随着Live2D在项目研发中被广泛使用，其性能优化的需求已经不容忽视。笔者通过模型资源、Mesh、RenderTexture、Material和CPU耗时这5个方面来阐述优化的过程，并且最终实现了低端机上6个模型30帧的效果，值得大家参考。 优化结果 测试机型：低端机——红米4X 测试样例：同样的6个模型（游戏中同屏最多6个模型） 版本：3.2.05 CPU优化主要在CubismModel.Update、CubismModel.OnRenderObject； 内存优化主要在Texture2D、Mesh、RenderTexture、Material以及Mono内存分配。 接下来介绍从模型资源、Mesh、RenderTexture、Material和CPU耗时5个方面来优化性能。 1、模型资源 项目前期没有制定Live2D美术规范，美术导出文件的时候，直接使用自动布局顶点的方式，而Live2D自动生成Mesh的时候对于每个部件的内外边界各生成一份顶点，发现如下问题： 1、模型Mesh数量太多 2、模型的总顶点数达到6K左右 后续跟美术沟通之后，对Live2D模型（后续的模型都指Live2D模型）的导出规定如下： 1、手动布局顶点 2、ArtMesh数量控制在100以内（之前的模型由于改动的工作量太大，暂时不做修改） 3、模型顶点数控制在2k面以内（游戏最多有6个模型） 4、Edit Texture Altas中贴图大小1024*1024，自动布局且Margin为5px 5、为了避免多贴图导致DrawCall升高，一个模型只使用一张贴图 2小时后，通过Live2D Cubism Editor->File->Model Statistics查看优化结果如下： 性能数据测试结果如下： 2、Mesh 测试发现游戏一个模型的Mesh数量在80-200之间，同屏最多有6个模型，通过UWA GOT测试发现Mesh峰值达到107MB（27380个），Material数量达到10.2MB（14968个），其中Unlit（Instance）数量14563个明显异常。 研究CubismRenderer.cs发现如下问题： 1、运行时创建了两份Mesh内存 2、Mesh资源未销毁，导致内存泄漏 3、顶点色每帧都会重新赋值 针对问题1，经测试发现，改成一份Mesh并没有明显的CPU变化，Mesh内存减少一半，由于每一帧都有顶点变化，_meshFilter.mesh = FrontMesh每帧700次的CPU消耗也可以省去。 针对问题2，可以在OnDestroy中调用Destroy接口销毁Mesh。 针对问题3，使用标记控制是否更新顶点色，减少顶点色赋值的0.5ms左右CPU消耗。 另外值得一提的是，Mesh中使用了顶点色处理透明和颜色变化，但是同一个Mesh的顶点色全部相同，可以想到在Shader中控制颜色，实际上为了动态合批不得不使用顶点色，合批之后控制在10个DrawCall左右，不合批每个模型DrawCall数量达到上百个。 3、RenderTexture CubismMaskTexture.cs中创建的RenderTexture大小默认为1024*1024，项目中遮罩效果大部分使用在眼睛，在实际测试之后有如下优化： 1、将GlobalMaskTexture.asset的Size改成128，实际数值可以根据项目需要修改。 2、CubismMaskTexture.cs中RemoveSource函数加上如下检查，在没有遮罩模型的时候可以释放RenderTexture。 if(Sources.Count == 0) { if(_renderTexture != null) { RenderTexture.ReleaseTemporary(_renderTexture); _renderTexture = null; } } 3、CubismMaskTexture.cs中OnDisable()和RefreshRenderTexture()函数中同样添加释放RT的接口。 4、CubismMaskController.cs做如下修改，避免RenderTexture无法释放，同时避免切换模型且未销毁时CubismMaskCommandBuffer.Lateupdate持续CPU消耗。 修改后： 4、Material 通过UWA GOT测试发现材质数量也达到1w多个，研究发现材质有明显的泄漏问题，解决方案如下： 1、CubismRenderer.cs中Material属性 public Material Material { get { return MeshRenderer.material; } set { MeshRenderer.material = val…