« Lua binding 中正确的 callback | 返回首页 | 游戏数据的展示 »

蒙皮数据的压缩

传统的蒙皮数据需要在模型顶点上存两组数据,其一为该顶点受哪些骨头的影响,其二为受这些骨头影响的权重。因为 GPU 的对齐影响,通常游戏中会将同一顶点受影响的骨头数量上限设为 4 。如果不做任何优化,骨头总数在 256 以下时,每个顶点需要 4 个字节保存骨头编号,再用 4 个 float 表示分别的权重。

因为权重之和总是为 1 ,所以,只用 3 个 float 也是可以的(第四个权重通过简单的计算就可以得到)。

因为权重总是 0-1 之间的数字,所以 32bits float 的精度远超所需,我们也并不需要浮点数。所以用 16bits [0,65535) 甚至 8bits (0,255] 来表示 0-1 的权重也够了。

所以,蒙皮一般至少占用 64bit 的定点数据 (4+4 bytes) 。

如果想进一步压缩,就需要一些复杂的技巧了。这两天读了几篇关于动画蒙皮数据压缩的 paper ,挺受启发的。

首先是这一篇 Vertex-Blend Attribute Compression

它给我最大的启发是:其实,每个顶点所受骨头影响的组合是很有限的。这也非常符合自觉,因为,顶点总是受空间位置上附近一些骨头的影响。空间位置相近的顶点,所受骨头影响的组合几乎是相同的,不同的只是权重比。

我们完全可以预处理一张表,记录该模型所有顶点的骨头索引组合,然后,在顶点上只需要保存表的序号,这样就可以大大压缩索引组合的数据。按论文中的数据看,一个一万多顶点的模型,组合数只有一千左右。也就是用 10bits 左右就能完整保存骨头组合信息。

我们可以创建固定大小的表,如果模型使用的组合数量超过了表的固定尺寸,就可以把一些不重要的组合去掉,归到最接近的表项上即可。

对于权重信息,也有压缩的余地。因为,骨头是次序无关的。如果我们总是按次序排列骨头,让权重从小到大,那么就有可能进一步的压缩数据。

以四根骨头为例,因为只需要实际储存三根骨头的权重,扔掉权重最大的那个,剩下三个量的范围分别是 (0,1/2], (0,1/3] , (0, 1/4] 。如果权重一定是从小到大排列,这三个两实际上可以看成四面体上的一个点。对将所有可能的点都排列在数轴上一一对应起来,就可以在限定位数内实现最大的精度。

如果我们用 10bits 保存索引,22bits 保存三个权重分量,就可以用 32bits 保存完整的顶点蒙皮信息了。


Permutation Coding for Vertex-Blend Attribute Compression 这篇 paper 进一步扩展了上面的方法。

允许每个顶点上的骨头数量是不定的。如果使用 64bits 数据,最多可以支持到 13 根骨头。骨头数量越多,就牺牲越多的精度;反之,如果骨头只有一两根的话,就最大限度的提高精度。

作者在 github 上公开的代码 ,写的清晰易懂。

Comments

怎么说呢,程序员,尤其是优秀的程序员在国内得不到足够的尊重和重视,大多数不学无识的谄媚之人招摇过市,真正搞技术的被死死的压在底层,所有,能出国就出国吧,去欧美,程序员跟外国人沟通起来还是比较容易的,计算机的概念,那本《编译原理》(龙书英文版)的内容就足够用了。
我是最近组建了一个游戏开发公司,需要找一些资源,所以最近才来到你的博客看了看,大家好运吧,也没啥其他可说的了。
GPU在CUDA出现以前,就是使用超长指令字(VLIW)来替代DirectX或者OpenGL的一些API和标准函数(对象),超长指令字(VLIM)在90%的时间里是做一件事,那就是计算近似曲面,就如同你说的蒙皮的顶点,一个曲面是有成千上万个多边形构成的,如果没有时间限制,一个复杂的曲面,CPU慢慢计算,也是可以得到显卡的计算结果的,但是CPU太慢了,DirectX或者OpenGL类似算法库,其中有些非常耗时的算法,可以使用显卡来加速得到计算结果。至于你说的顶点和骨骼之间的逻辑关系,这个部分内容跟3D模型的原理有关系,骨骼和顶点之间的逻辑关系就是矩阵计算,矩阵计算其实就是两个或者多个线程方程的乘法,现在的显卡的超长指令字是可以直接支持复杂的矩阵计算加速的。 尤其是CUDA完全可以取代系统的API,比如以太坊挖矿,就是直接使用CUDA编程,一般的挖矿软件,可以把整个区块链加载到显存中,然后使用GPU简历128个线程,来进行HASH计算,速度相当的快,因为显存至少是DDR5,频率高达8GHz以上。
疫情了,云风blog开始高产起来
这两天下载了Unity3D,研究了一下,怎么说呢,这个软件吸收了大量原来引擎(Ue2~Ue4)的技术,有加入了3Dmax和maya的一些技术,这个东西,介于openGL(directx)和Maya(3Dmax)之间的一个产品,功能跟强大。很多原来使用3Dmax来做的事,现在事实上可使用这个替代,并且,这个东西使用C#脚本来解决当年Lua做的事,这个东西的唯一缺憾是不如OpenGL和directx这样贴近硬件,内部很多驱动层的事,还要依靠OpenGL来解决。实际上,这个类似3D领域的操作系统,而OpenGL和directx类似C++模板库(比如当年的MFC基础类库和STL标准库),而CUDA属于显卡芯片的汇编和C语言工具链,这三者都有重叠的部分。
其实德国的大学还是可以的,而且德国的大学已经向国际学生免费了

Post a comment

非这个主题相关的留言请到:留言本