杂乱工作笔记

上周回总部跟同事吃饭的时候,跟一些老外大牛们聊了一些公司用到的各种技术。很多问题当时没有做笔录, 所以趁现在还记得,记录一下。

1.动画压缩

数据格式:使用quaternion保存旋转,这一点相信很多引擎都这么做了。 格式使用R10G10B10A2来提高精度, 只保存xyz,对于normalized quaternion, w可以根据xyz实时计算。

关键帧采样: 核心思想是,去掉无用的关键帧。根据相邻三个key的数据,计算两端两个key的插值,与中间一个key比较, 如果他们两个的差值在一定的threshold范围,就去掉中间一个key,这个很容易理解。印象千里马肝大大也有提到骨骼动画的精简和压缩,可能有类似的方法。

由此顺便提到tangent space的压缩,使用quaterion保存。公司里面的大神说我们现在还没有用,而是用的2个向量。他提到一点,quaternion只能保存正交的三个轴,实际的tangent space的tangent和bitangent并不一定正交(个人理解即uv的分布会有拉伸,尤其像面部,u和v并不一定垂直,导致tangent和bitangnet不正交,最后得到的是一个”扭曲“的空间)。所以将其正交化以后, 会有些许不精确,但是通常可以接受和忽略。

 

2.FX编译器

公司使用的是类似D3D的FX格式,加了各种semantics和annotation,有自己的编译器。

最为诡异的是,使用了annoation来区分是否为骨骼动画。 对于骨骼动画的fx,仍然只使用常规的一个worldmatrix,而编译器将bone matrices、blendindices、blendweight,这些细节通通隐藏,只会在最终的shader/asm里面嵌入这些代码。 所以骨骼动画的VS代码表面上看起来跟常规VS一样,只用了一个matrix,没有用bone matrices,也没有blendindices,blendweight这两个input stream,编译器最后会把这些信息加进去,并用混合后的matrix代替参数中的world matrix uniform。这么做的好处是不用在重复写一模一样的骨骼动画shader了, 缺点是容易让人迷惑(semantic confusion),特别是刚接触的时候。

 

自定义的FX/shader编译器确实有很多好处,比如可以做很多跨VS&FS的优化,个人不确定openGL的linking phase会不会做这些。

又比如可以保持前端代码不变,而可以生成不同API对应shader代码(DX、OpenGL、GLES)。

 

这些常规性的知识都可以贴出来,另外还有一些牵扯到项目的data pipeline, 我不确定是否会有技术保密问题,所以不多说了。

 


 

更新: 3.模型压缩

公司的模型, 顶点格式使用的是INT16Nx4. 这个是我第一次见到的, 感觉很有意思. 不过目前暂时不会效仿公司的做法.
首先计算出模型的AABB,
然后对每个顶点, V' = (V - AABB.center) / AABB.size. 得到单位化的顶点坐标. 再转成SHORT.

这种方式以16位表示的数字, 与Float16表示的数字范围更小(16bit表示整个包围盒的范围), 所以精度比float16更高. 在shader里面需要用逆向运算把单位化坐标转到模型空间.
由于精度更高, 所以在做变形动画的时候, 不会产生累积误差. 确实不错的想法. 据说shader x2里面介绍了这个方法.

 

同时, 公司的模型也支持大骨骼数量的动画, 即bone matrices太多, constant registers不够用时,常规的模型拆分. 把bone matrices分到多个draw call的constant registers里面.

你可能感兴趣的:(工作)