【Unity】GPU骨骼动画 渲染性能开挂 动画合批渲染 支持武器挂载

news2025/2/3 23:53:10

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对顶点进行变换,自然而然武器就会跟着骨骼动。

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

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

相关文章

【数据结构】六、树和二叉树

目录 一、树的基本概念 二、二叉树 2.1二叉树的性质 2.2二叉树的存储结构 2.3遍历二叉树 先序遍历 中序遍历 后序遍历 层次遍历 2.4二叉树的应用 计算叶子数 前序遍历建树 根据序列恢复二叉树 计算树的深度 判断完全二叉树 三、线索二叉树 3.1线索化 四、树和森林…

中伟视界:燃气站的烟火、安全帽、抽烟、打电话检测等AI算法的工作原理详解

人工智能&#xff08;AI&#xff09;技术在各行各业中的应用越来越广泛&#xff0c;燃气站的安全管理也在逐步引入AI算法。本文将详细介绍AI算法在燃气站安全管理中的应用&#xff0c;包括烟火检测、安全帽识别、抽烟、打电话检测等方面的工作原理。 烟火检测是燃气站安全管理中…

盘古信息IMS-MOM制造运营管理系统,构建生产现场管理信息系统的最佳选择

在当今高度竞争的制造行业中&#xff0c;高效的生产管理是企业成功的关键。盘古信息IMS-MOM制造运营管理系统作为一款领先的管理系统其关键特性为制造企业构建生产现场管理信息系统提供了强大的优势。IMS-MOM不仅仅是一个软件系统&#xff0c;更是一种技术和管理手段的结合&…

OpenAI GPT 模型 API 接口新增参数 top_logprobs 和 logprobs

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 在最新的 OpenAI 官方 APIs 文档中&#xff0c;Create chat completion 中新增了 top_logprobs 和 logprobs 这两个关键参数。 官方文档地址&#xff…

Kubernetes的理论基础

k8s:kubernetes:8个字母省略&#xff0c;就是k8s。 自动部署&#xff0c;自动扩展和管理容器化部署的应用程序的一个开源系统。k8s是负责自动化运维管理多个容器化程序的集群&#xff0c;是一个功能强大的容器编排工具。分布式和集群化的方式进行容器管理。 1.15 1.18 1.20 1…

新版IDEA中Git的使用(二)

说明&#xff1a;前面介绍了在新版IDEA中Git的基本操作&#xff0c;本文介绍关于分支合并、拉取等操作&#xff1b; 例如&#xff0c;现在有一个项目&#xff0c;分支如下&#xff1a; main&#xff1a;主分支&#xff1b; dev&#xff1a;开发分支&#xff1b; test&#x…

Linux Fonts

/usr/share/fonts Windows Fonts-CSDN博客

【java爬虫】基于springboot+jdbcTemplate+sqlite+OkHttp获取个股的详细数据

注&#xff1a;本文所用技术栈为&#xff1a;springbootjdbcTemplatesqliteOkHttp 前面的文章我们获取过沪深300指数的成分股所属行业以及权重数据&#xff0c;本文我们来获取个股的详细数据。 我们的数据源是某狐财经&#xff0c;接口的详细信息在下面的文章中&#xff0c;本…

Stable Diffusion模型原理

1 Stable Diffusion概述 1.1 图像生成的发展 在Stable Diffusion诞生之前&#xff0c;计算机视觉和机器学习方面最重要的突破是 GAN&#xff08;Generative Adversarial Networks 生成对抗网络&#xff09;。GAN让超越训练数据已有内容成为可能&#xff0c;从而打开了一个全新…

侦探IP“去推理化”:《名侦探柯南》剧场版走过26年

2023年贺岁档&#xff0c;柯南剧场版的第26部《黑铁的鱼影》如期上映。 这部在日本狂卷票房128亿日元的作品&#xff0c;被誉为有史以来柯南剧场版在商业成绩上最好的一部。 但该作在4月份日本还未上映前&#xff0c;就于国内陷入了巨大的争议。 试映内容里&#xff0c;灰原…

使用Clion配置Qt开发过程中的很多坑

如果你想使用Clion开发Qt软件 如果你想在Windows上使用Clion开发Qt 如果你还想使用MSVC编译器开发Qt 但是却遇到了各种各种编译报错&#xff0c;那么恭喜你这些坑都有人帮你踩过了 报错一 CMake Error at CMakeLists.txt:25 (find_package):Could not find a package config…

基于深度学习的垃圾检测与分类系统(含UI界面,yolov8、Python代码,数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 添加注意力机制&#xff08;SE、CBAM等&#xff09;         2. 修改可变形卷积&#xff08;DySnake-主干c…

【树莓派4b的uboot编译移植】

树莓派4b的uboot编译移植 引言 0.1、什么是uboot OS跑起来前&#xff0c;需要的一段引导程序负责部署整个计算机系统&#xff0c;引导操作系统内核启动并给内核传参提供一个命令行界面供人操作是一个开源项目&#xff0c;uboot就是universal bootloader&#xff08;通用的启…

【基础篇】四、类加载器ClassLoader

文章目录 1、类加载器2、分类3、启动类加载器4、手动扩展启动类加载器5、扩展类加载器6、应用程序类加载器 1、类加载器 类加载器ClassLoader&#xff0c;是JVM提供给应用程序去获取类和接口的字节码数据的。 上面的类加载器对JVM进行了本地接口调用。本地接口即JNI&#xff0…

MySQL 中 blob 和 text 数据类型

应用场景 日志表中请求参数用的text&#xff0c;公告表中内容详情用的mediumblob。 1. blob 类型 blob(binary large object) 是一个可以存储二进制文件的容器&#xff0c;主要用于存储二进制大对象&#xff0c;例如可以存储图片&#xff0c;音视频等文件。按照可存储容量大小…

redis 从0到1完整学习 (七):ZipList 数据结构

文章目录 1. 引言2. redis 源码下载3. zipList 数据结构3.1 整体3.2 entry 数据结构分析3.3 连锁更新 4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&am…

Python(五)—— 闭包装饰器

13. 闭包 13.1 闭包的案例 给大家提个需求&#xff0c;然后用函数去实现&#xff1a;完成一个计算不断增加的系列值的平均值的需求 例如&#xff1a;整个历史中的某个商品的平均收盘价。就是从这个商品一出现开始&#xff0c;每天记录当天价格&#xff0c;然后计算他的平均值…

SpringBoot源码搭建

文章目录 源码下载搭建项目构建学习博客 源码下载 需要环境 &#xff1a; JDK 1.8Maven 3.5Spring Boot 1.x.x: Gradle 版本建议为2.9或更高版本。Spring Boot 2.x.x: Gradle 版本建议为4.x.x或更高版本。 GitHub 从v2.3.x开始&#xff0c;SpringBoot开始强制用Gradle构建项…

深度解析:CRM、ERP之间的关联和区别以及双系统的联系与集成(附系统架构图)

目录 一、系统简介 1.1 CRM是什么 1.2 ERP是什么 二、发展阶段 2.1 CRM发展阶段 2.2 ERP发展阶段 三、系统架构 3.1 CRM系统架构 3.2 ERP系统架构 四、CRM与ERP的区别 4.1 目标不同 4.2 不同阶段的发展中不同的适用性 4.2.1 刚起步的小公司 4.2.2 对于更大、更成…

数字电子技术 一天速成

文章目录 一、数制与编码1. 数制转换2. BCD编码 二、逻辑代数1. 常见逻辑运算及逻辑门 三、化简逻辑表达式1. 卡诺图 求 表达式2. 表达式 画 卡诺图3. 卡诺图 化简 表达式4. 公式法 化简 表达式 ⭐⭐5. 表达式 求 反函数6. 卡诺图 求 反函数 四、组合逻辑电路的分析和设计1. 逻…