找回密码
 立即注册
查看: 427|回复: 3

UWA2020(八)_DOTS在Unity引擎不同模块中的应用

[复制链接]
发表于 2023-2-17 08:28 | 显示全部楼层 |阅读模式
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)



  • 对比

    • BatchRendererGroup  VS  DrawMeshInstanced

      • BatchRendererGroup有可以传入culling放
      • DrawMeshInstanced没有culling,需要自己culling完成把结果传入渲染





    • ECS  VS  GameObject(无Instance)

      • ECS 的 Set pass call 更少,因为GameObject的渲染时,材质被打乱,Shader切换导致
      • Batches 一样 , 因为大家都没有合批
      • ECS 的 CPU耗时更低 , FPS更高





    • ECS  VS  GameObject(有Instance)

      • Batches 减少,GameObject的渲染,材质球合批被打乱导致
      • ECS 的 CPU耗时更低 , FPS更高





    • ECS  VS  GameObject

      • 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)IJobParallelForTransform
20FPS25FPS30FPS33FPS



    • 如 35K Cubes , MI9 Pro

方式帧率备注
ECS + Job + Burst60FPSGO完全转换为ECS,并使用多线程更新属性
ECS + Job54FPS
ECS30FPS
IJobParallelForTransform11FPS无需ECS,针对Transform
ECS 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测试,所以就过了一遍不细写了.
发表于 2023-2-17 08:32 | 显示全部楼层
真复杂,,,内容真多,,,
发表于 2023-2-17 08:40 | 显示全部楼层
挺实在,有个小问题:目录的链接不对
发表于 2023-2-17 08:50 | 显示全部楼层
知乎BUG 没有办法  ....  正常排版要去GITHUB
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-12-22 10:26 , Processed in 0.094236 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表