Javascript - 优化3D动画的节点层次结构更新

时间:2015-08-15 01:18:24

标签: javascript webgl hierarchical-data skeletal-animation

我使用WebGL进行硬件换肤,但是更新我的模型节点层次结构会对性能造成巨大冲击。

每个节点都需要查询其当前位置/旋转/缩放关键帧,使用它们构造局部矩阵,并且如果它具有父级,则将其与其父级矩阵相乘。

矩阵数学本身就是最优化的(基于gl矩阵的矩阵构造的特殊变体)。

尽管如此,如果我更新了许多模型,每个模型有几十个节点(有些甚至有数百个,遗憾的是),这会占用浏览器的所有执行时间。

我尝试使用脏状态,因为当节点实际上不需要更新时,只需检查它们的本地数据是否发生变化(主要是检查位置或旋转是否发生变化)实际上导致的处理量与刚刚相同计算矩阵。

WebCL本来是理想的,但自2014年以来似乎无处可去。

我开始考虑在着色器中运行它,但我不能完全理解如何设计它(例如存储关键帧,这是一个框架 - >数据的映射,或者如何写回数据。)

另一种方法是在纹理中缓存所有动画转换,但这并不能很好地扩展。对于具有足够低关键帧数量的模型,这是可以的,但对于具有长动画的模型,这会非常快地变为数百兆字节。 这主要是因为我无法想出任何存储稀疏数据的方法。如果可能的话,那么我可以存储与关键帧相同数量的转换,这不会占用大量内存(现在,我存储每个帧的转换)。 当然,这需要进行矩阵插值,我不确定它是多么可靠。

有没有人有任何想法?

1 个答案:

答案 0 :(得分:0)

我认为将整个节点层次结构计算卸载到GPU是不切实际的。您可以做的最好的事情是将2个绝对世界变换关键帧上传到GPU并让GPU进行插值。但我不确定插值的世界变换是否与您通过节点层次结构实际计算的相同。如果可能,那将是一个可行的解决方案。请注意,您也无法在矩阵之间进行插值。您需要以支持插值的形式转换它,例如使用四元数+附加数据。

我实际上也遇到过这个问题。我发现更新转换计算是最耗时的操作,尽管还有完整的碰撞系统+响应。

我通过减少需要调用此更新转换的次数来解决问题。例如,如果您可以断定整个模型不在视锥体之外,那么您根本不需要计算变换。这可能会将您需要做的计算量减少到~1 / 6到~1 / 4之间。

其次,对于远处的物体,你不需要每帧更新它们的变换。只需每隔几帧左右更新一次变换。请记住,这些游戏只附带30FPS,因此远程对象的一些跳帧可能不明显。

最后,这可能根本不适用于Javascript,所以我还没做(还),你应该以缓存一致的方式存储和访问数据。见these slides。可以提高10倍的性能。但同样,可能不适用于Javascript,因为Javascript数组不能保证按顺序打包它们的数据。