【Unity】GPU骨骼动画 渲染性能开挂 动画合批渲染 支持武器挂载
GPU骨骼动画视频介绍:
GPU顶点动画和GPU骨骼动画实现原理及优缺点对比 性能优化

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对顶点进行变换,自然而然武器就会跟着骨骼动。
相关文章:
【Unity】GPU骨骼动画 渲染性能开挂 动画合批渲染 支持武器挂载
GPU骨骼动画视频介绍: GPU顶点动画和GPU骨骼动画实现原理及优缺点对比 性能优化 GPU动画是实现万人同屏的前置条件,在之前的文章中已介绍过GPU顶点动画的实现方法:【Unity】渲染性能开挂GPU Animation, 动画渲染合批GPU Instance_skinmeshren…...
打开相机失败 出现错误的原因
如何解决? Debug中缺少DLL文件 以下参考周姐文档 相机调用步骤 学习相机第三方库的安装 https://blog.csdn.net/Qingshan_z/article/details/117257136书签:QT添加库(静态库和动态库)_Qingshan_z的博客-CSDN博客_qt添加库 添加文…...
什么是阿里云负载均衡SLB?
目录 硬件或软件负载均衡的区别是什么? 什么是阿里云负载均衡SLB? 阿里云传统型负载均衡CLB 硬件或软件负载均衡的区别是什么? 通过专用硬件实现负载均衡,那么整体成本会较高,而且设备容易出现单点故障,…...
Mybatis三 | 动态SQL
目录 if where set ctrl alt l格式化SQL语句 随着用户的输入或外部条件的变化而变化的SQL称为动态SQL if <if>用来判断条件是否成立,使用test属性进行条件判断,如果true,则拼接SQL where wehre元素只会在有条件成立的情况下才插入…...
信号与槽QT4和QT5的区别
信号与槽QT4和QT5的区别 Qt4 connect(btn, SIGNAL(clicked()), this, SLOT(close()));在 Qt 4 中,信号和槽的连接使用了一种不同的语法,这是 Qt 框架特有的,利用了 Qt 的元对象系统(Meta-Object System)。Qt 4 中连接…...
K8S 搜集java应用pod重启前现场 —— 筑梦之路
JAVA技术广泛用于各行各业,而云原生的流行,越来越多的企业将java应用搬进K8S中进行部署管理,OOM是java应用比较常出现的故障问题,对于容器环境的java应用搜集OOM等现场比较有难度,为了持续对应用的优化,搜集…...
php5.6安装mongo扩展
需要依赖 可以参考 php5.6安装openssl扩展 https://pecl.php.net/package/mongo 安装mongo扩展 wget https://pecl.php.net/get/mongo-1.6.16.tgz/Users/hina/Applications/php/5.6.40/bin/phpize./configure --with-php-config/Users/hina/Applications/php/5.6.40/bin/ph…...
简析SoBit 跨链桥图文教程
从BTC网络到Solana网络桥接BRC20 1.打开SoBit平台:在您的网络浏览器中启动SoBit Bridge应用程序。 2.连接您的钱包: 选择SoBit界面右上角的比特币网络来连接您的数字钱包。 3.选择源链、目标链和您想桥接的代币: 从下拉菜单中选择’BTC’作为…...
C#与php自定义数据流传输
C#与php自定义数据流传输 介绍一、客户端与服务器数据传输流程图客户端发送数据给服务器:服务器返回数据给客户端: 二、自定义数据流C#版本数据流PHP版本数据流 三、数据传输测试1.在Unity中创建一个C#脚本NetWorkManager.cs2.服务器www目录创建StreamTe…...
redis和数据库的同步问题
今天突然想起来这个,就是那么突然,上次项目上用过redis,是一个消息已读未读的问题,由于消息挺多的,如果每次都去查数据库,那岂不是裂开,所以就存缓存了。 现在想想,还是不大行&#…...
Flink系列之:深入理解ttl和checkpoint,Flink SQL应用ttl案例
Flink系列之:深入理解ttl和checkpoint,Flink SQL应用ttl案例 一、深入理解Flink TTL二、Flink SQL设置TTL三、Flink设置TTL四、深入理解checkpoint五、Flink设置Checkpoint六、Flink SQL关联多张表七、Flink SQL使用TTL关联多表 一、深入理解Flink TTL …...
Wails中js调用go函数(1种go写法,2种js调用方法)
官方js调用go方法文档:https://wails.io/zh-Hans/docs/howdoesitwork a)在app.go文件里写一个要js调用的go函数: func (a *App) JSCallGo(data1 string) string { return “test” } b)运行 wails dev 命令,…...
【我与java的成长记】之面向对象的初步认识
系列文章目录 能看懂文字就能明白系列 C语言笔记传送门 🌟 个人主页:古德猫宁- 🌈 信念如阳光,照亮前行的每一步 文章目录 系列文章目录🌈 *信念如阳光,照亮前行的每一步* 前言一、什么是面向对象面向过程…...
面试题之二HTTP和RPC的区别?
面试题之二 HTTP和RPC的区别? Ask范围:分布式和微服务 难度指数:4星 考察频率:70-80% 开发年限:3年左右 从三个方面来回答该问题: 一.功能特性 1)HTTP是属于应用层的协议:超文本传输协议…...
初试Kafka
Kafka 是一个分布式流处理平台,通常用作消息中间件,它可以处理大规模的实时数据流。以下是从零开始使用 Kafka 作为消息中间件的基本教程: 步骤 1: 下载和安装 Kafka 访问 Apache Kafka 官方网站:Apache Kafka下载最新的 Kafka …...
SuperMap Hi-Fi 3D SDK for Unity基础开发教程
作者:kele 一、背景 众所周知,游戏引擎(Unity)功能强大,可以做出很多炫酷的游戏和动画效果,这部分功能的实现往往不仅仅是靠可视化界面就能够实现的,还需要代码开发。SuperMap Hi-Fi SDKS for …...
Upload-lab(pass1~2)
Pass-1-js检查 这里检验 因为是前端js校验,所以只用绕过js前端校验 用burp抓包修改文件类型 写一个简易版本的php Pass-2-只验证Content-type 仅仅判断content-type类型 因此上传shell.php抓包修改content-type为图片类型:image/jpeg、image/png、image/gif...
Linux:查询当前进程或线程的资源使用情况
目录 一、/proc/[PID]/下的各个文件1、proc简介2、/proc/[PID]/详解 二、通过Linux API获取当前进程或线程的资源使用情况1、getrusage2、sysinfo3、times 在工作中,我们排除app出现的一些性能/资源问题时,通常要先知道当前app的资源使用情况,…...
unityc用vs2017介绍
21版unity能用17vs,只要在unity的Edit/Preferences/ExternalTools里面改既可。...
单元测试实战
文章目录 为什么要做单元测试?单元测试的几个核心要点是:单元测试目标单元测试框架JUnitTestNG 单元测试工具: 为什么要做单元测试? 测试代码:通过编写和运行单元测试,开发者能够快速验证代码的各个部分是否…...
告别SU冲突!雷电模拟器9.0.20+新版Magisk Delta(狐狸面具)保姆级安装避坑指南
雷电模拟器9.0.20Magisk Delta深度适配指南:从冲突根源到完美兼容 当你在雷电模拟器9.0.20及以上版本尝试安装Magisk Delta(狐狸面具)时,是否遇到过Root权限反复失效、SU冲突提示不断弹出的困境?这背后隐藏着新版模拟器…...
Ccursor安装使用
首先进入官文 https://cursor.com/下载,然后按照步骤进行安装,一般都是直接默认安装(修改软件位置的话可以修改下去,默认是在c盘,可能会后面用的多了造成卡顿),直到安装完成, 点击使…...
Spring Scheduling定时任务:从原理到实战的完整指南
1. 项目概述与核心价值在后台系统开发中,定时任务是一个绕不开的经典需求。无论是每天凌晨的数据报表生成、每隔几分钟的缓存刷新,还是每周一次的日志归档,都需要一个稳定、可靠的任务调度机制。早期,很多开发者会选择自己撸袖子干…...
工业物联网主板布局设计:从i.MX28x核心到无线模块的硬件规划
1. 项目概述:从一块板卡看工业物联网的“骨架”拿到一块名为“IoT-A28LI”的主板,标题里还带着“i.MX28x系列”和“无线工控板”这样的关键词,这立刻让我这个在工业控制和嵌入式领域摸爬滚打多年的老工程师来了兴致。这不仅仅是一块电路板&am…...
别再死记硬背了!用Python+SymPy玩转含参积分,从卷积到信号处理一次搞懂
用PythonSymPy玩转含参积分:从数学原理到信号处理实战 数学中的含参积分常常让学习者感到抽象难懂,尤其是当涉及到极限交换、求导与积分顺序交换等概念时。但如果我们换一种方式——用代码和可视化来探索这些数学概念,一切就会变得清晰起来。…...
Python连接Oracle报DPI-1047?别慌,手把手教你用Instant Client 11g/12c/19c搞定(附环境变量避坑指南)
Python连接Oracle报DPI-1047?手把手教你用Instant Client全版本配置指南 当你满怀期待地在Python中写下import cx_Oracle,准备连接公司数据库大展身手时,突然跳出的DPI-1047: Cannot locate a 64-bit Oracle Client library错误提示就像一盆冷…...
DeepSeek企业级部署GPU清单(2024Q3权威更新):仅3款消费级卡达标,87%私有云环境需重构PCIe拓扑
更多请点击: https://intelliparadigm.com 第一章:DeepSeek企业级GPU资源需求的演进逻辑与基准定义 随着DeepSeek系列大模型从开源轻量级版本(如DeepSeek-Coder-1.3B)向千亿参数级企业级推理与微调平台(如DeepSeek-VL…...
HTTPS握手失败?别慌!手把手教你用OpenSSL和Wireshark排查TLS与Cipher Suites问题
HTTPS握手失败?别慌!手把手教你用OpenSSL和Wireshark排查TLS与Cipher Suites问题 当你面对浏览器中那个刺眼的"SSL Handshake Failed"错误时,是否感到无从下手?作为经历过数百次HTTPS故障排查的老兵,我深知这…...
JiYuTrainer:在极域电子教室中重获电脑控制权的终极方案
JiYuTrainer:在极域电子教室中重获电脑控制权的终极方案 【免费下载链接】JiYuTrainer 极域电子教室防控制软件, StudenMain.exe 破解 项目地址: https://gitcode.com/gh_mirrors/ji/JiYuTrainer 你是否曾在机房上课时,被极域电子教室的全屏广播困…...
2026年5月19日:谷歌云误停账户致Railway全平台服务中断8小时
事件报告:2026年5月19日 - GCP账户暂停Chandrika Khanduri 与 Cody De Arkland于2026年5月20日发布此报告。据悉,本报告反映了发布时所掌握的信息,可能会根据谷歌云(Google Cloud)的内部审查结果进行更新。影响2026年5…...
