【Unity】GPU骨骼 GPU Spine动画 2D/3D渲染性能开挂 合批渲染 支持武器挂载 动画事件 动画融合 实时获取骨骼位置

本文主要是介绍【Unity】GPU骨骼 GPU Spine动画 2D/3D渲染性能开挂 合批渲染 支持武器挂载 动画事件 动画融合 实时获取骨骼位置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 GPU 3D骨骼动画和 GPU 2D Spine动画插件均包含在【万人同屏整合方案】中,老板们可在某宝搜:[游戏开发资源商店] 以获取全套方案的所有源码插件。

 

万人同屏渲染避障锁敌方案实现对抗战斗demo 展示GPU动画高级功能 动画事件 动画平滑过渡 融合

 

插件功能:

1. 支持3D动画转GPU动画 

2. 支持2D Spine动画转GPU动画

3. 支持挂点、支持挂载物、动态切换挂载物、实时获取挂点Transform信息

4. 支持实时获取gpu动画信息,如动画帧数、动画时长、动画是否循环

5. 支持动画事件

GPU骨骼动画视频介绍:

GPU顶点动画和GPU骨骼动画实现原理及优缺点对比 性能优化

2d spine动画帧数提升数十倍?spine转gpu动画 2d spine动画 10w单位

GPU动画是实现万人同屏的前置条件,在之前的文章中已介绍过GPU顶点动画的实现方法:【Unity】渲染性能开挂GPU Animation, 动画渲染合批GPU Instance_skinmeshrender合批-CSDN博客

GPU顶点动画的优缺点:

GPU顶点动画是将每一帧动画的Mesh顶点/法线存入贴图,在Shader中直接读取顶点/法线使用。

优点:由于没有过多的计算,因此性能较高;

缺点:如果一个模型有多个SkinnedMeshRenderer需要先合并Mesh; 生成的动画/法线贴图较大;不支持切换挂载武器;

GPU骨骼动画的优缺点:

GPU骨骼动画是将每一帧动画的所有骨骼的矩阵信息存入贴图,每一个顶点至多受4根骨骼影响,在Shader中用这4根骨骼的矩阵和4根骨骼对应的蒙皮权重对顶点位置和法线进行变换,得到受骨骼影响后的顶点/法线值。

优点:动画贴图很小;无需合并Mesh;支持挂载武器切换;可以实时获取到某个挂点位置

缺点:需要一定计算量,因此性能比顶点动画略低;

GPU骨骼动画实现:
一,读取骨骼数据,生成动画贴图,Mesh

 1. 获取蒙皮动画的骨骼信息:

可通过SkinnedMeshRenderer的rootBone查找到根骨骼,或者直接使用bones字段,该字段为SkinnedMeshRenderer关联的所有骨骼的Transform数组;

2. 从动画曲线获取每个动画帧记录的骨骼Transform数值:

以获取动画每帧的骨骼位置为例:

private Vector3 GetBonePositionAtTime(string bonePath, AnimationClip clip, float animTime)
{var localPosXCurve = EditorCurveBinding.FloatCurve(bonePath, typeof(Transform), "m_LocalPosition.x");var localPosYCurve = EditorCurveBinding.FloatCurve(bonePath, typeof(Transform), "m_LocalPosition.y");var localPosZCurve = EditorCurveBinding.FloatCurve(bonePath, typeof(Transform), "m_LocalPosition.z");Vector3 pos = Vector3.zero;pos.x = AnimationUtility.GetEditorCurve(clip, localPosXCurve).Evaluate(animTime);pos.y = AnimationUtility.GetEditorCurve(clip, localPosYCurve).Evaluate(animTime);pos.z = AnimationUtility.GetEditorCurve(clip, localPosZCurve).Evaluate(animTime);return pos;
}

3. 将骨骼矩阵写入动画贴图:

把矩阵的前3行数值,以骨骼个数为偏移量分别写入动画贴图:

for (int boneIdx = 0; boneIdx < bones.Length; boneIdx++){var bone = bones[boneIdx];bool noBone = bone.GetComponent<MeshRenderer>() != null;if (!noBone && bone.TryGetComponent<SkinnedMeshRenderer>(out var sMeshRender) && sMeshRender.rootBone == null){noBone = true;}var boneMatrix = bone.localToWorldMatrix;if (!noBone){boneMatrix *= bonesW2LMatrices[boneIdx];}animBoneTex.SetPixel(boneIdx, curFrameIndex, boneMatrix.GetRow(0));animBoneTex.SetPixel(bonesCount + boneIdx, curFrameIndex, boneMatrix.GetRow(1));animBoneTex.SetPixel(bonesCount * 2 + boneIdx, curFrameIndex, boneMatrix.GetRow(2));}

4. 将每个动画的开始帧/结束帧、动画时常、动画是否循环播放的信息写入动画贴图的最后一列像素 

生成的骨骼动画贴图

 5. 生成Mesh网格:

有了骨骼信息的动画贴图,还需要知道每个顶点受哪些骨骼影响,才能在Shader中取到对应的骨骼信息对顶点和法线进行变换;

为了节省资源和读取方便,我们可以直接把顶点关联的4根骨骼以及每根骨骼的权重分别塞到Mesh的UV2和UV3两个通道。

 二、GPU骨骼动画Shader实现:

 1. 从动画贴图中解析当前动画的起始/结束帧,根据是否Loop来计算出当前动画帧:

 2. 以当前帧为动画贴图采样的V坐标,采样获取所有骨骼矩阵每行数值,构建骨骼矩阵并计算顶点/法线:

3.  通过自定义函数得到转换后的顶点坐标和法线并应用到GPU骨骼动画shader:

 这样就完成了GPU骨骼动画功能,切换动画时传入动画Index和当前时间Time.time,动画片段将自动从起始帧开始播放,并且完美支持动画是否循环。对于在骨骼上挂载的武器,无论是MeshRenderer还是SkinnedMeshRenderer都完美支持,因为挂载武器的节点Transform本身也作为骨骼写入到了动画贴图,Shader中会自动通过骨骼的Local2WorldMatrix对顶点进行变换,自然而然武器就会跟着骨骼动。

三,获取挂点位置 

例如GPU动画人物手里拿着一把枪,发射子弹时就需要在枪口的位置创建并发射子弹,由于GPU动画已经没有了骨骼Transform,枪口的位置怎么获取呢?

GPU动画因为是纯Shader实现,所以切换动画只需要修改材质的ClipId属性即可,其中x作为动画索引,y作为动画播放的开始时间,即Time.time。

有了动画索引和播放的开始时间,我们就可以得到当前动画已经播放了多久,根据已经播放时长就可以算出动画播到了第几帧,通过第几帧就可以从动画贴图读出任意骨骼的矩阵,这样就实现了随用随取的高性能获取挂载点位置、旋转、缩放。

四,GPU动画帧事件: 

GPU动画转换工具会自动把Animation Clip中包含的事件数据保存到文件里,无需手动处理。并且支持随意增删事件。

GPU动画事件同时支持 Mesh Renderer渲染和BRG渲染。

两种渲染模式触发逻辑不同:

1. 使用MeshRenderer渲染只需挂载一个事件脚本,然后就像为Button添加/移除监听事件一样简单。

2. 使用BRG渲染, BRG提供了获取触发事件的接口,接口使用Jobs检测当前帧触发的事件,并将事件列表返回,由用户在主线程自行调用触发。大大提升了海量GPU动画单位事件触发性能。

同时GPU动画事件处理时会进行插帧计算,不会因为卡顿问题导致跳过动画事件的触发。

例如:一个弓箭手射箭动画,动画前大部分是搭箭、拉弓,动画最后一帧才松手,为了显示效果同步,就需要在最后一帧弓箭手松手时让箭发射出去,而不是在搭箭/拉弓的时候就发射箭。通过使用帧事件就能完美卡点解决这个问题。

五,GPU动画过渡/融合: 

 目前市面上的GPU动画插件要么是没有动画融合,要么就是使用脚本计算融合,会导致性能大打折扣。为了保证性能优先、兼容性高,最佳方案还是纯shader处理。

如何用最小的代价实现GPU动画平滑过渡呢?GPU动画切换动画时需要修改material上的shader参数clipId(Vector4),其中x为动画clip的索引,y为动画切换时间,zw是预留属性,暂未用到。

已知clip索引和切换动画的时间就可以轻易计算出动画已经播了多久,进而计算出播到第几帧,然后通过帧数就可以从动画贴图中读取到当前帧所有骨骼的Transform信息,然后所有骨骼从当前的Transform数值平滑过渡到下一动画clip索引的第一帧骨骼Transform不就能实现骨骼平滑过渡了吗?我们还需要指导上一个动画索引和上一个动画开始播放的时间,正好存入预留的zw中。

GPU 2d Spine动画实现:

有多个网友反馈有2D GPU动画的需求,不过我们通常会认为2D很难存在渲染瓶颈,然而并非如此。经过实际测试同屏显示相同的动画人物,1W个Spine动画 vs 1W个Animator动画。测试结果令人大跌眼镜!Spine动画和Animator动画性能接近,1W单位下都只有8帧左右。要知道,我们之前测试的五百多顶点的3D人物,同数量级下能达到近9帧左右。Spine动画性能竟然如此之差!

看来对于数量级超过百、千单位的项目,非常有必要使用GPU Spine动画。

2d spine动画帧数提升30倍 spine转gpu动画 2d spine动画 10w单位

 实现原理其实就是把Spine动画转换为Animator动画,由于2D动画都是有面片Mesh组成,z轴全为0. 因此必须解决渲染层级的问题,这一转换过程需对Mesh进行修改以使得渲染层级正确。转换为Animator动画后就可以使用我们的GPU动画转换工具直接进行转换,同样支持顶点动画/骨骼动画两种模式。

同屏1W个单位测试环境下,Spine动画转换为GPU 2D动画后帧数直接提升10倍以上,使用万人同屏方案合批渲染功能后,相比Spine动画提升接近恐怖的40倍,对于2D割草游戏绝对是最佳方案。

这篇关于【Unity】GPU骨骼 GPU Spine动画 2D/3D渲染性能开挂 合批渲染 支持武器挂载 动画事件 动画融合 实时获取骨骼位置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807159

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

如何用GPU算力卡P100玩黑神话悟空?

精力有限,只记录关键信息,希望未来能够有助于其他人。 文章目录 综述背景评估游戏性能需求显卡需求CPU和内存系统需求主机需求显式需求 实操硬件安装安装操作系统Win11安装驱动修改注册表选择程序使用什么GPU 安装黑神话悟空其他 综述 用P100 + PCIe Gen3.0 + Dell720服务器(32C64G),运行黑神话悟空画质中等流畅运行。 背景 假设有一张P100-