Unity引擎源码札记(二):GPUSkinning
1. 概述
本文档结合Unity引擎源码(基于Unity 4.6),研究Unity 的GPUSkinning特性,结合实例进行性能分析。
2. GPUSkinning
1)GPU Skinning设置
Unity支持GPU Skining,构建时开启PlayerSetting.gpuSkinning 将允许符合条件平台使用GPU Skinning
(官方文档:DX11, OpenGL ES 3.0 and Xbox 360 can do mesh skinning on the GPU)。
BuildSetting(IOS/Android)
Android下需要额外设置(如果选择“Force Open GL ES 2.0”,在支持ES 3.0的设备上依然不会生效GPU Skinning,原因见下文源码分析):
2)适用设备(IOS/Android)
对于手机平台,IOS/Android,Opengl ES支持版本及设备如下(From: https://en.wikipedia.org/wiki/OpenGL_ES):
OpenGL ES 2.0
Supported by:
l The Android platform since Android 2.0 through NDK and Android 2.2 through Java
l Apple iOS 5 or later in iPad, iPad Mini, iPhone 3GS or later, and iPod Touch 3rd generation or later
OpenGL ES 3.0
Supported by:
l Android since version 4.3, on devices with appropriate hardware and drivers, including:
Samsung Galaxy S4 (Snapdragon version)
Samsung Galaxy Note 10.1 (2014 Edition)
l iOS since version 7, on devices including:
l Supported by some recent versions of these GPUs:
Adreno 300 and 400 series (Android, BlackBerry 10, Windows Phone 8, Windows RT)
Mali T600 series onwards (Android, Linux, Windows 7)
Vivante (Android, OS X 10.8.3, Windows 7)
Nvidia (Android, Linux, Windows 7)
Intel (Linux)
IOS设备详细的兼容性列表可参考苹果官方文档:
3)引擎源码分析
SkinnedMeshRenderer::AwakeFromLoad会创建当前平台的GPUSkinningInfo
GLES 2.0将返回NULL,因此,若在BuildSetting时Graphic level选择“Froce Open GL 2.0”,GPUSkinningInfo为空,即使在支持 GLES 3.0的设备上,也不进行GPUSkinning.
SkinnedMeshRenderer::SkinMesh根据条件进行CPU 或 GPU Skinning计算,
而skin.memExport条件取决于:
l PlayerSetting.gpuSkinning是否开启
l 当前初始创建的GPUSkinningInfo是否为NULL( 即m_MemExportInfo)
l 是否Cloth及是否具有skin信息、骨骼权重等
源码小结
从源码上看,如前文1)中的构建设置选项,构建时打开PlayerSetting.gpuSkinning (Andorid平台Graphic level: Automatic )在GLES 2.0设备上应会自动选择CPU Skinning,在GLES 3.0设备会使用GPU Skinning,实际情况需要进行目标机型的兼容性测试。
3. 性能测试分析
使用不同数目的角色skinned mesh 测试CPU 负载情况:
测试场景1:
测试设备
测试数据(单机,不限帧,忽略流量,测试60s)
Skinning/人数 | 平均CPU(%) | 平均内存(MB) | 平均FPS(帧/秒) |
CPUSkinning_50人 | 26.62 | 53.015 | 58 |
GPUSkinning_50人 | 23.57 | 50.340 | 59 |
CPUSkinning_75人 | 29.06 | 65.957 | 43 |
GPUSkinning_75人 | 29.93 | 64.50 | 56 |
CPUSkinning_100人 | 28.56 | 81.616 | 32 |
GPUSkinning_100人 | 28.37 | 77.324 | 45 |
CPUSkinning_200人 | 30.61 | 176.989 | 13 |
GPUSkinning_200人 | 30.60 | 170.747 | 18 |
l 随人数增加,两者CPU负载趋一致,GPU Skinning比CPU Skinning内存稍低;
l 随人数增加,GPU Skinning比CPU Skinning FPS高30%左右;
l 75人以下,GPU Skinning 比 CPU Skinning的CPU负载稍低,内存较低,FPS相近(此时非GPU瓶颈);
4. 小结
是否使用GPUSkinning策略,也取决于CPU或GPU的负载情况。如果当前的CPU负载瓶颈,GPU较轻,可使用GPUSkinning;反之,则建议使用默认的CPUSkinning。
值得注意的是,在项目中开启GPUSkinning后,部分机型会出现蒙皮错误,存在兼容性问题,但是使用CPUSkinning正常。因此,慎用Unity 4.6中的GPUSkinning(Unity 5没做测试未知),需要进行更多的兼容性测试和验证。