UNITY实战进阶-BatchRendererGroup+Jobs+Burst+RVO2+GPUAnimation 实现万人团战(一)

研究思路:GPUAnimation把动画放入GPU中处理,BatchRendererGroup进行动态批量渲染处理,Jobs+Burst进行多线程处理逻辑(移动、攻击等),RVO2采用Jobs的寻路导航。

准备工作:
Editor => Project Setting =>Package Manager => Enable Pre-release Package勾选
PackageManager安装以下:Jobs、Burs、Universal RP


URP渲染管线

Rendering=>Create “Universal Render Pipeline Asset”
Editor=>Project Setting=>Quality=>RenderPipelineAsset=>“Universal Render Pipeline Asset”
Editor=>Project Setting=>Graphics=>ScriptsableRenderPipelineSetting=>“Universal Render Pipeline Asset”


Job System C#任务系统

  1. 在Job System对外之前,Unity虽然内部是多线程处理,但是外部的代码都必须跑在主线程上。
  2. C#虽然支持Thread,但是在Unlty中只能处理数据,例如:网络消息、下载。如果想在Thread中调用Unity的API那是不行的。
  3. 有了Job System就可以充分利用CPU的多核,例如:在多线程中修改Transform旋转、缩放、平移
  4. 例如:MMO游戏判断碰撞、大量同步角色坐标、大量的血条飘字等都比较适合Job System
  5. Unity没有直接将Thread开放出来,可以有效避免Thread被滥用,开发者可放心使用Job而不用太多关心如线程安全、加锁这些问题。
  6. Job最好配合Burst编译器,这样能生成高效的本地代码(后面会细聊Burst)

job中只能使用值类型(float,int,uint,short,bool。。。),enums,structs和其他类型的指针。
job中不能使用引用类型,T[]数组属于引用类型,无法使用,使用NativeArray<T>[]替代。

所以:接口IJob是个开线程的操作,再job中按顺序执行,所以可以准确的保证值的准确性

    //在job中按顺序执行,所以可以准确的保证值的准确性struct MyStruct : IJob{public NativeArray<float> values;public float offset;public void Execute(){for (int i = 0; i < values.Length; i++){values[i] += offset;}}}void Update(){NativeArray<float> values = new NativeArray<float>(500, Allocator.Persistent);MyStruct myStruct = new MyStruct();myStruct.values = values;myStruct.offset = 10;for (int i = 0; i < 1000; i++){JobHandle jobHandle = myStruct.Schedule();jobHandle.Complete();}values.Dispose();}

接口IJobParallelFor,在job中按并行执行,内部会自动加锁

    //在job中按并行执行,内部会自动加锁struct MyStruct2 : IJobParallelFor{//声明数据是只读的,意味着copy这个数据不需要加锁[ReadOnly]public NativeArray<float> copy;//非声明ReadOnly,默认values为write/read,数据一旦改变,job会等待public NativeArray<float> values;public void Execute(int index){values[index] = copy[index];}}void Update(){NativeArray<float> values = new NativeArray<float>(500, Allocator.Persistent);NativeArray<float> copy = new NativeArray<float>(500, Allocator.Persistent);for (int i = 0; i < copy.Length; i++){copy[i] = Random.Range(0, int.MaxValue);}MyStruct2 myStruct = new MyStruct2();myStruct.values = values;myStruct.copy = copy;for (int i = 0; i < 1000; i++){JobHandle jobHandle = myStruct.Schedule(values.Length, 32);jobHandle.Complete();}values.Dispose();copy.Dispose();}


Burs编译器

  1. Burst编译器是以LLVM为基础的后端编译技术。
  2. 编译器的原理会分5个步骤;源代码—》前端—》优化器—》后端—》机器码。
  3. LLVM的定义了个抽象语言IR,前端负责将源代码(C#)编译成IR,优化器负责优化IR,后端负责将IR生成目标语言这里就是机器码。
  4. 正是因为抽象语言IR的存在,所以LLVM支持的语言很多,而且也方便扩展C#、ActionScript、Ada、D语言、Fortran、GLSL、Haskell、Java字节码、Objective-C、Swift、Python、Ruby、Rust、Scala等 语言。
  5. LLVM代码是开源了,所以Unlty很适合用它来做Burst的编译。
  6. 遗憾的是LLVM对C#的GC做的不好,所以burst只支持值类型数据编译,不支持引用类型数据编译

Unity.Mathematics数学库

  1. Unity.Mathematics提供矢量类型(float4,float3..)它可以直接映射到硬件SIMD寄存器。
  2. Unlty.Mathematics的Math类中也提供了直接映射到硬件SIMD寄存器。
  3. 这样原本CPU需要一个个计算的,有了SIMD可以一次性计算完毕。
  4. 需要注意的是unlty之前的Math类默认是不支持映射SIMD寄存器的。

        如何启动BursCompile,我们可以在C#代码中使用Burst编译器。在需要使用Burst编译器的方法或类上添加[BurstCompile]属性。

        我们需要在Unity3D项目的Player Settings中启用Burst编译器。在Unity3D编辑器中,选择Edit -> Project Settings -> Player,在Inspector窗口中找到Scripting Backend选项,选择IL2CPP,并勾选“Enable Burst Compilation”选项即可。

  1. Struct上添加BursCompile即可。
  2. Struct必须是继承IJob类,否则无效。
 //在job中按顺序执行,所以可以准确的保证值的准确性[BurstCompile]struct MyStruct : IJob{public NativeArray<float> values;public float offset;public void Execute(){for (int i = 0; i < values.Length; i++){values[i] += offset;}}}

设计模式-组合模式: 类似GameObject上绑定组件,组件化。


GPU Instancing Animation

我这里给大家提供个基础方案:https://github.com/piti6/UnityGpuInstancedAnimationicon-default.png?t=N7T8https://github.com/piti6/UnityGpuInstancedAnimation

这里要注意的是:不支持fbx里面有多个skinnedMeshRenderer,需要手动分离多个Prafabs,Editor中仅支持生成带Animator和Controller的Prefab。

With your custom FBX files

  1. Create prefab with target file.
  2. Make sure you have one SkinnedMeshRenderer on your prefab - (also counts children SkinnedMeshRenderer)
    I have no plan to support Nested SkinnedMeshRenderer.
  3. Make sure you referenced AnimatorController to your skinnedMeshRenderer`s Animator with setup-wanted animations.
  4. Click your prefab, then click top menu AnimatedMeshRendererGenerator -> MeshToAsset.
  5. Call AnimatedMeshAnimator::Play(string animationName, float offsetSeconds) on your script.
    (Warning - animationName goes to original Animator`s display name, not file name.)

所以,我这里自己修改了以下步骤:

  1. 添加Editor编辑面板。
  2. 先根据Animator和Controller查找对应的Clips资源,若没有直接在FBX中查找Clips资源

上测试图,这是开启URP的效果:

接下来聊下如何适配URP:

Github的项目本身是2018年的产物,为什么选择这个项目是因为其他的烘焙动画项目的渲染图太大了,这个项目就比较友好,简单易懂易二次开发,渲染的动画图较小。

项目的Shader采用表面着色器,其实URP渲染管线支持几何、片段、顶点等等,但是这个项目的shader是不支持的,所以需要大家自行去修改支持URP的Shader或者Vertex的Shader,其实很简单,把表面着色器的代码修改为顶点着色器的代码,在修改为URP的代码。 

代码借鉴:

Unity 手把手教你从Built-in升级URP - 知乎一、前言URP正式发布已经很久了,现在是2023年,但是发现现在网上的一些Shader教程还是大多都是基于Built-in的,感觉对于新手同学们不是很友好,关于URP的教程又少之又少。 这里结合个人经验以及网络上的一些资料…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/604880712


未完待续。。。。

 有兴趣的小伙伴可以关注一波

 o(* ̄▽ ̄*)ブ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/797639.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware虚拟机(Rocky9.3)硬盘扩容详细图文教程

参考<<鸟哥的Linux>>以及VMware虚拟机硬盘扩容详细图文教程 原因: 用户空间不足,且系统是用LVM&#xff08;logical volume manager&#xff09;进行分区 df -h #查看/home目录下磁盘容量不足磁盘扩容步骤 关闭虚拟机,选择编辑虚拟机, 点击硬盘,再点击扩容 这个…

Redis安装说明

Redis安装说明 大多数企业都是基于Linux服务器来部署项目&#xff0c;而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址&#xff1a;https://redis.io/ 1.单机安装Redis 1.1.…

Mysql底层原理十一:Mvcc

为什么要mvcc&#xff1f; 提高并发度&#xff0c;如果读和写都是通过加锁的方式&#xff0c;并发肯定上不来&#xff0c;通过mvcc来实现写通过加锁&#xff0c;读通过mvcc readView机制 3.9.1 Undo版本链 再重复一遍&#xff0c;页面中的记录存放在用户表空间的数据页中&a…

VLAN 与 VXLAN:一个字母之差,到底两者有什么区别?

来源&#xff1a;网络技术联盟站 网络虚拟化技术在现代网络架构中扮演着至关重要的角色&#xff0c;而其中的两个重要代表——虚拟局域网&#xff08;VLAN&#xff09;和虚拟扩展局域网&#xff08;VXLAN&#xff09;——在网络管理和扩展性方面发挥着独特的作用。本文将深入研…

LeetCode-1483. 树节点的第 K 个祖先【树 深度优先搜索 广度优先搜索 设计 二分查找 动态规划】

LeetCode-1483. 树节点的第 K 个祖先【树 深度优先搜索 广度优先搜索 设计 二分查找 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;暴力解法会超时&#xff01;【一级一级往上跳&#xff0c;效率太低】解题思路二&#xff1a;倍增&#xff0c;利用二进制运算&#xf…

gin框架提高篇(三)

多服务器程序运行 package mainimport ("fmt""github.com/gin-gonic/gin""golang.org/x/sync/errgroup""net/http""time" )var g errgroup.Group // 使用 errgroup.Group 来并发启动这两个服务器func main() {// 服务器1se…

穿越代码之海:探寻结构体深层逻辑,展望未来应用新天地

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 结构体作为一种数据结构&#xff0c;其定义和特点决定了它在各种应用中的广泛适用性。随着科技的进步和新兴行业的不断涌现&#xf…

HarmonyOS 应用开发之wrapBuilder:封装全局@Builder

全局Builder作为wrapBuilder的参数返回WrappedBuilder对象&#xff0c;实现 全局Builder 可以进行赋值和传递。 说明&#xff1a; 从API version 11开始使用。 接口说明 wrapBuilder是一个模板函数&#xff0c;返回一个WrappedBuilder对象。 declare function wrapBuilder<…

机器学习数据预处理—统计分析方法

数据预处理 1 数据规范化 量纲&#xff0c;指将一个物理导出量用若干基本量的乘方之积表示出来的表达式。数据的比较需要关注两点——绝对数值和量纲&#xff0c;而特征间因为量纲的存在导致无法直接通过绝对数值比较大小&#xff0c;也就无法判断特征间的重要性。例如若某个…

算法:树形dp(树状dp)

文章目录 一、树形DP的概念1.基本概念2.解题步骤3.树形DP数据结构 二、典型例题1.LeetCode&#xff1a;337. 打家劫舍 III1.1、定义状态转移方程1.2、参考代码 2.ACWing&#xff1a;285. 没有上司的舞会1.1、定义状态转移方程1.2、拓扑排序参考代码1.3、dfs后序遍历参考代码 一…

刷题之Leetcode209题(超级详细)

209.长度最小的子数组 力扣题目链接(opens new window)https://leetcode.cn/problems/minimum-size-subarray-sum/ 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条…

数据可视化高级技术Echarts(快速上手柱状图进阶操作)

目录 1.Echarts的配置 2.程序的编码 3.柱状图的实现&#xff08;入门实现&#xff09; 相关属性介绍&#xff08;进阶&#xff09;&#xff1a; 1.标记最大值/最小值 2.标记平均值 3.柱的宽度 4. 横向柱状图 5.colorBy series系列&#xff08;需要构造多组数据才能实现…

以动态库链接库 .dll 探索结构体参数

Dev c C语言实现第一个 dll 动态链接库 创建与调用-CSDN博客 在写dll 插件中发现的函数指针用途和 typedef 的定义指针的用法-CSDN博客 两步之后&#xff0c;尝试加入结构体实现整体数据使用。 注意结构体 Ak 是相同的 代码如下 DLL文件有两个&#xff0c;dll.dll是上面提到…

C-偶遇行军蚁(遇到过的题,做个笔记)

我的代码: 思路就是把每一行看成一个字符串&#xff0c;然后逐渐增加字符就行 #include <iostream> #include <vector> using namespace std; int main() {string s;int n;cin >> n; //读入行数cin >> s; //读入字符串vector<string>arr(n…

一点点金融

一点点金融 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多趋势分析 改进MACD策略&#xff0c;使用涨跌幅比值RSI计算MACD原始MACD计算改进思路&#xff1a;使用涨跌幅比值RSI计算MACD 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多…

[pyenv] 1. 安装与使用

在看了几个开源的python环境管理器的评论后, 我打算入手 pyenv, 该项目有以下几个优势: 该项目使用纯shell脚本语言实现, 天然亲和linux开发环境.通过设置的PATH环境变量和shims方法隔离的实现方案非常轻量化.子命令引入了compgen补全功能, 对命令输入操作友好.源码开源, 可扩展…

《pytorch深度学习实战》学习笔记第2章

第2章 预训练网络 讨论3种常用的预训练模型&#xff1a; 1、根据内容对图像进行标记&#xff08;识别&#xff09; 2、从真实图像中生成新图像&#xff08;GAN&#xff09; 3、使用正确的英语句子来描述图像内容&#xff08;自然语言&#xff09; 2.1 获取一个预训练好的网络…

通过 Cookie、Redis共享Session 和 Spring 拦截器技术,实现对用户登录状态的持有和清理(三)

本篇内容对应 “2.4 生成验证码” 小节 和 “4.7 优化登陆模块”小节 视频链接 1 Kaptcha介绍 Kaotcga是一个生成验证码的工具。 你的网站验证码是什么&#xff1f; 在我们这个牛客论坛项目&#xff0c;验证码分为两部分 给用户看的是图片&#xff0c;用户根据图片上显示的…

什么牌子开放式耳机好用?优选五大高分好物真诚分享

对于习惯长时间佩戴耳机的朋友来说&#xff0c;入耳式耳机固然能够提供较优质的音质体验。但是&#xff0c;由于其较为封闭的设计以及对耳洞的压迫&#xff0c;舒适感较差&#xff0c;长时间佩戴可能会对听力造成一定的影响。因此&#xff0c;开放式耳机的出现为音乐发烧友们提…

Leetcode 684. 冗余连接

心路历程&#xff1a; 这道题属于图论的经典连通问题&#xff0c;这道题翻译过来就是&#xff0c;找到破开图中环的一条边&#xff1b;再翻译过来就是&#xff0c;从后往前遍历edges&#xff0c;依次连接边&#xff0c;当发现新连接的边已经有相同父节点时&#xff08;已经马上…