聊城手机网站建设软件,运动鞋建设网站前的市场分析,wordpress注册接口,购物网站htmlGPU骨骼动画视频介绍#xff1a; GPU顶点动画和GPU骨骼动画实现原理及优缺点对比 性能优化 GPU动画是实现万人同屏的前置条件#xff0c;在之前的文章中已介绍过GPU顶点动画的实现方法#xff1a;【Unity】渲染性能开挂GPU Animation, 动画渲染合批GPU Instance_skinmeshren…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.GetComponentMeshRenderer() ! null;if (!noBone bone.TryGetComponentSkinnedMeshRenderer(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对顶点进行变换自然而然武器就会跟着骨骼动。