UWA2020(八)_DOTS在Unity引擎不同模块中的应用
DOTS在Unity引擎不同模块中的应用emmmmmmmmmmmmmmm这个视频看完感觉像是DOTS的简介
推荐一手ECS大手子:https://www.zhihu.com/people/benzx-84/posts
(Github正常排版: DOTS在Unity引擎不同模块中的应用)
<hr/>1. 简介
2. 渲染
3. 转换
4. 蒙皮动画
5. 物理
6. 场景
7. UI
8. 建议
<hr/>1. 简介
[*]DOTS(Data Oriented Technology Stack)
[*]有啥?
[*]Entity Component System(ECS)
[*]C# Job System
[*]Burst Compiler
[*]做啥?
[*]解决大批数据计算性能的问题
[*] 要啥?
[*]关注性能
[*]面向数据思想
[*]硬件并行能力
[*]ECS
[*]简介
[*]面向数据
[*]组成:Entity(id) Component(数据) System(逻辑)
[*]World拥有n个Entity,Entity拥有n个Component,System处理Component
[*]面向对象(非ECS)
[*]数据散放于内存中.(减慢缓存写入速度)
[*]多余数据一起加载.(占用缓存空间)
[*]ECS
[*]Archetype:不同Components的特定组合
[*]相同的Archetype的数据,在内存中,会连续存放于固定大小(16k)的Chunk中.(相关Component数据可以快速写入缓存)
[*]Chunk中同类型的Component数据连续存放(SOA).(同类型的数据线性存储避免缓存行浪费)
[*] ECS优点
[*]Chunk数据连续存放布局,可以提升缓存命中
[*]内存管理不使用托管堆,避免GC
[*]快速查询entity以及获取component数组数据的效率大幅度提高,远大于GameObject.Find,GameObject.Getcomponents
[*]Job System
[*]CPU多线程实现方式
[*]把主线程的事情,分割成一个个Job,放入JobQueue,再由JobQueue分发到多线程上处理
[*] C# Job System
[*]使用C#调用,隐藏线程调度,资源竞争等处理方式
[*]数据类型的限制,struct/blittable/非托管内存容器
[*]Burst
[*]简介
[*]基于LLVM的编译器
[*]把逻辑语言转换成中间语言,再对中间语言进行优化,最后把中间语言生成目标平台的机器码
[*]如:Clang->LLVMIR->x86/ARM等
[*]Unity实现了C#->.NET assembly,即逻辑语言到中间语言
[*]使用限制
[*]用于Job System和Function Pointer(FunctionPointer)
[*]不能使用引用类型
[*]无法trycatch
[*]无法访问托管对象
[*]无法写入静态变量
[*]优点
[*]因为代码进行优化,所以更高效运行
[*]SIMD指令优化,让数据并行处理
[*]以往A1+B1=C1,A2+B2=C2 2个指令
[*]Burst 可以只用 1个指令并行
[*]运行效率比肩C++,比IL2CPP快
<hr/>2. 渲染
[*]ECS渲染
[*]数据准备:位置+模型信息(Mesh+Material)
[*]调用Draw API / Hybrid Render
[*]Hybrid Render
[*]通过Package Manager安装
[*]渲染System(勾选RenderMeshSystemV2):Culling,API调用
[*]Entity需要挂载LocaltoWorld和RenderMesh
[*]LocaltoWorld->ComponentData
[*]个体自己的数据
[*]非托管chunk内存布局
[*]IComponentData
[*]struct类型
[*]使用blittabl变量,不能引用托管类型
[*]Managed IComponentData(引用类型用)
[*]Class类型,不能使用Burst,Job
[*] RenderMesh->SharedComponentData
[*]同chunk的Entity共同关联数据
[*]chunk之外由SharedComponentManager进行管理
[*]可以使用引用类型
[*]数据可以共享,对entity进行chunk进行分组
[*]降低Set pass call,优化GPU Instancing
[*]Draw API
[*]DrawMesh
[*]DrawMeshInstanced
[*]移动平台大部分兼容
[*]DrawMeshInstanceIndirect
[*]功能完善,移动平台不一定兼容
[*] BatchRendererGroup
[*]https://zhuanlan.zhihu.com/p/105616808?utm_source=qq
[*]Unity2019新增
[*]通用渲染类,兼容ECS,Builtin,SRP , 当前版本的Hybrid Render也用这个API
[*]渲染API的高层封装
[*]方便用户使用自己的culling方法
[*]var xx = new BatchRendererGroup(MyCullingMethod)
[*]对比
[*]BatchRendererGroupVSDrawMeshInstanced
[*]BatchRendererGroup有可以传入culling放
[*]DrawMeshInstanced没有culling,需要自己culling完成把结果传入渲染
[*]ECSVSGameObject(无Instance)
[*]ECS 的 Set pass call 更少,因为GameObject的渲染时,材质被打乱,Shader切换导致
[*]Batches 一样 , 因为大家都没有合批
[*]ECS 的 CPU耗时更低 , FPS更高
[*]ECSVSGameObject(有Instance)
[*]Batches 减少,GameObject的渲染,材质球合批被打乱导致
[*]ECS 的 CPU耗时更低 , FPS更高
[*]ECSVSGameObject
[*]ECS提升渲染效率
[*]避免GameObject管理开销(场景管理,逐物体方法的调用)
[*]属性更新适合Job加速运算
[*]如:让一堆cube向上移动
[*]GameObject + 25k Cube > 10FPS
[*]ECS + 25k Cube > 30FPS
[*]ECS + Job + 50K Cube >= 50FPS
[*]ECS + Job + Burst + 50K Cube = 60 FPS
[*]主线程耗时大大减少了,因为位置更新时,主线程出现了计算瓶颈
<hr/>3. 转换
[*]问题
[*]GameObject全部转换ECS任务艰巨
[*]MonoBehaviour组件逻辑转换System繁琐
[*]使用了复杂的渲染管线
[*]使用了第三方插件难以转换
[*]自动转换
[*]目的
[*]设计阶段保留Unity传统模式
[*]Runtime阶段使用ECS高效处理方式
[*] 方法
[*]渲染可能需要Hybrid Renderer
[*]挂载自动转换脚本 ConvertToEntity
[*]Transform -> LocalToWorld
[*]MeshRender -> RenderMesh
[*]转换自定义MonoBehaviour组件
[*]转移逻辑到System
[*]自定义数据转换
[*]GameObjectConversionSystem
[*]IConverGameObjectToEntity
[*]IDeclareReferencedPrefabs
[*]DOTS+GameObject混合使用
[*]目的
[*]ECS/Job System负责部分逻辑运算,使用GameObject进行渲染
[*]可以继续使用原来的渲染管线
[*]之前的MonoBehaviour继续有效
[*]举个粒子:ECS更新GameObject位置信息
[*]挂载ConvertToEnity脚本->选择Coversion Mode->Convert And Inject GameObject让LocalToWorld和Transform同时拥有
[*]方式一 : 直接在System中获取Transform组件
[*]ForEach(Transform).WithoutBurst().Run()
[*]方式二 : Job中更新Entity位置数据后,同步至GameObject
[*]需要给entity添加CopyTransformToGameObject
[*]EntityManager.AddComponentData(entity,new CopyTransformGameObject())
[*]方式三 : 使用IJobSystem
[*]使用IJobParallelForTransform 和 TransformAccess,只针对Transform
[*]可以用BurstCompile
[*]可以多线程更新transform信息,相同Root共线程
[*]不需要ECS的概念,改造简便
[*]如 10K Cubes + 位移
[*]主要耗时都在主线程上,ECS+Job使用了多线程缓解了压力
老做法ECS Injection(main thread)ECS Injection(Job)IJobParallelForTransform20FPS25FPS30FPS33FPS
[*]如 35K Cubes , MI9 Pro
方式帧率备注ECS + Job + Burst60FPSGO完全转换为ECS,并使用多线程更新属性ECS + Job54FPSECS30FPSIJobParallelForTransform11FPS无需ECS,针对TransformECS Injection10FPSECS与GO混合使用,利用Job多线程更新属性Classic(老做法)<8FPS<hr/>4. 蒙皮动画
[*]问题
[*] Hybrid Render / API绘制 都 不支持Skinned mesh
[*]解决方案
[*]Unity Animations
[*]开发中(emmmmm Unity一堆TODO的)
[*]GameObject+DOTS混用
[*]ECS Injection
[*]IJobParallelForTransform
[*]渲染Mesh,GPU进行动画
[*]Vertex Animation
[*]Geometry Shader 传入VerticesBuffer(Unity的SKinedMesh和原神都这么干)(https://zhuanlan.zhihu.com/p/126294753)
[*]需要DX10(Stream Out)或OpenGL ES 3.0(Transform Feedback) (https://www.zhihu.com/question/67301295/answer/251750311)
[*]GPU Skinning
[*]GPU Skinning + Instancing
[*]将动画信息写入纹理
[*]运行时在Shader中采样纹理,进行GPU Skinning
[*] GPU Animation
[*]https://blog.uwa4d.com/archives/UWALab_GPUAnimation.html
[*]ECS + GPU Skinning + Instancing
[*]烘焙动画纹理
[*]运行时ECS多线程更新位置及其其他角色信息
[*]调用DrawMeshInstanced/DrawMeshInstancedIndirect进行渲染
[*] 渲染时候用GPU Animation完成动画播放
[*]混合使用方案
[*]子弹等->ECS
[*]玩家角色->GameObject+ECS Injection
[*]小兵->ECS+GPU Skinning+Instancing
<hr/>5. 物理
[*]Unity Physics/Havok Physics
[*]相同的数据协议,Editor设置,切换方便
[*]Unity Physics
[*]C#开源
[*]扩展性强
[*]不依赖缓存
[*]效率相对慢,但是比原生快
[*]Havok Physics
[*]运算精确
[*]缓存策略提升性能
[*]效率相对快
[*]UnityPro用户订阅收费,但是新版本PackageManager好像免费
[*]如 20K Cubes
[*]GameObject FPS:8
[*]Unity Physics FPS:50
[*]Havok Physics FPS:60
[*]物理动画
[*]头发布料适合ECS/Job加速
[*]Automatic Dynamic Bone
[*]https://github.com/OneYoungMean/Automatic-DynamicBone
[*]UWA Blog
[*]https://blog.uwa4d.com/archives/Sparkle_DynamicBone.html
<hr/>6. 场景
[*]SubScene
[*]https://zhuanlan.zhihu.com/p/109943463
[*]加载/卸载效率高:SubScene -> RAM
[*]二进制存储,加载直接进入内存,不需要序列化
[*]多线程加载
[*]避免同一帧内大量GameObejct的active的调用
[*]限制
[*]本地存储,不能用到AssetBundle一些地方
[*]ECS,Prefab需要完全转换到ECS
[*]如 10k Trees (PC) 实例化
[*]GameObject Prefab 1518ms
[*]ECS Prefab 262ms
[*]如 1k Trees (Mi9 Pro) 实例化
[*]GameObject Prefab 97ms
[*]ECS 15ms
<hr/>7. UI
[*]DOTS UI
[*]DOTS UI
[*]https://github.com/supron54321/DotsUI
[*]DOTS UGUI
[*]https://github.com/initialPrefabs/UGUIDOTS
[*]ECS+Job+Burst加速网格重建
<hr/>8. 建议
[*]项目中使用DOTS建议
[*]交互简单,数量多的物体尝试ECS化
[*]植物,副本建筑等静态环境物体
[*]加载/实例化
[*]batch/instancing
[*]降低场景开销
[*]子弹,物理道具等交互简单的物体
[*]属性多线程更新
[*]DOTS Physics
[*]instancing
[*]快速查询
[*]小怪等重复动画
[*]GPU Skinning + Instancing
[*]属性多线程更新
<hr/>Emmmm,差不多都看完了,应该更新完了.
剩下的一些视频一些不方便总结(<<手中的银河>>,<<轻量级Web3D引擎关键技术及移动网页在线可视化示范应用>>).
还有一些视频可能不感兴趣,偏美术向,偏立项和项目管理,偏项目QA测试,所以就过了一遍不细写了. 真复杂,,,内容真多,,, 挺实在,有个小问题:目录的链接不对 知乎BUG 没有办法....正常排版要去GITHUB
页:
[1]