当前位置:网站首页>[Unity] GPU动画实现(四)——生成动画数据
[Unity] GPU动画实现(四)——生成动画数据
2022-08-08 06:25:00 【Zhidai_】
目前使用的方法有一个很大缺陷在于基于顶点生成的动画占用的空间很大,一个理想的情况是基于骨骼数据,本文权当抛砖引玉,后续有时间考虑尝试一下基于骨骼数据生成动画。
本文内容大量参考自白菊花瓣丶的视频,感谢!
生成动画数据需要用到ComputeShader来提高运行的效率,首先在Resources下创建这样一个compute shader,在这里我将其命名为"AnimVertices"。
#pragma kernel CSMain
RWTexture2D<float4> Result;
StructuredBuffer<float3> vertices;
int time;
[numthreads(8,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
Result[uint2(id.x, time)]= float4(vertices[id.x], 1.0);
}在前面的介绍里提到该方法对顶点和动画帧数有要求,是因为顶点和动画帧数实实在在的影响了生成的动画数据大小,首先使用顶点数作为宽,动画帧数作为高,可以确定所需的图片大小为顶点数*动画帧数*16,16是因为这里使用的颜色格式为ARGBHalf。
int animLength = (int)(60 * animation.length);
//animLength = Mathf.NextPowerOfTwo(animLength);
int texwidth = mesh.sharedMesh.vertexCount;
texwidth = Mathf.NextPowerOfTwo(texwidth);
Texture2D tex = new Texture2D(texwidth, animLength, TextureFormat.RGBAHalf, false);
RenderTexture rt = new RenderTexture(texwidth, animLength, 0, RenderTextureFormat.ARGBHalf);动画帧数直接使用动画长度*运行帧数来获得,同时直接通过Mesh获取顶点数(Mathf.NextPowerOfTwo可以获得大于等于传入参数的2的幂的数,据说利于压缩,这里未做求证),格式使用ARGBHalf是因为顶点位置可正可负,实际使用中精度可能不足,可视情况调整。
cs.SetTexture(0, "Result", rt);
for (int i = 0; i < animLength; i++)
{
float time = i / 60f;
animation.SampleAnimation(gameObject, time);
Mesh bakeMesh = Instantiate<Mesh>(mesh.sharedMesh);
mesh.BakeMesh(bakeMesh);
Vector3[] vertices = bakeMesh.vertices;
int size = sizeof(int) * 3;
//Debug.LogError(i + " " + size + " " + time);
ComputeBuffer cb = new ComputeBuffer(vertices.Length, 12);
cb.SetData(vertices);
cs.SetInt("time", i);
cs.SetBuffer(0, "vertices", cb);
cs.Dispatch(0, Mathf.CeilToInt(vertices.Length / 8.0f), 1, 1);
cb.Release();
}创建render texture之后,赋值给到compute shader的Result属性,每帧动画就是图片数据里的一行,采样动画数据,烘焙获得Mesh之后,将烘焙后的顶点直接传入cs。
RenderTexture.active = rt;
tex.ReadPixels(new Rect(0, 0, texwidth, animLength), 0, 0);
tex.Apply();
AssetDatabase.CreateAsset(tex, $"Assets/Resources/{AnimTexName}.asset");最后同样使用AssetDatabase.CreateAsset将动画数据保存下来,这里我们拿到如下的一个数据。

边栏推荐
猜你喜欢
随机推荐
Vivado安装—Xilinx design tool already exists for 2019.1,specify a different program program group entr
ESP32 温湿度和气体传感器驱动
Mac下按装php的MongoDB扩展
二叉树的创建及遍历方法
ResNet网络结构详解、完整代码实现
ResNet 原理与代码复现
虚拟机克隆 快照 迁移 删除
firefly rk3399 硬件解码,多通道解码
【Web】标准文档流
5.多线程常用操作-命名和获取
TPLinker: Single-stage Joint Extraction of Entities and Relations Through Token Pair Linking
Yii2使用composer安装MongoDB扩展
[WUSTCTF2020]CV Maker1
如何使用conda,pip安装、更新、查看和卸载重装Pytorch?
PyTorch向量变换基本操作
P02 线程的用途
Bugku faster
ACM latex
MongoDB3.x创建用户与用户角色
传统图像特征提取方法:边缘与角点









