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

Javascript-优化3D动画的节点层次更新,javascript,webgl,hierarchical-data,skeletal-animation,Javascript,Webgl,Hierarchical Data,Skeletal Animation,我使用WebGL进行硬件蒙皮,但是更新模型节点层次结构会对性能造成巨大影响 每个节点都需要查询其当前位置/旋转/缩放关键帧,用它们构造局部矩阵,如果有父节点,则将其与父节点的世界矩阵相乘 矩阵数学本身经过优化(基于gl矩阵的矩阵构造的特殊变体) 不过,如果我更新了很多模型,每个模型都有几十个节点(遗憾的是,有些甚至有几百个节点),这会占用浏览器的所有执行时间 我曾尝试在节点实际上不需要更新时使用脏状态,但只是检查它们的本地数据是否发生了更改(主要是检查位置或旋转是否发生了更改)实际上会导致与计算

我使用WebGL进行硬件蒙皮,但是更新模型节点层次结构会对性能造成巨大影响

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

矩阵数学本身经过优化(基于gl矩阵的矩阵构造的特殊变体)

不过,如果我更新了很多模型,每个模型都有几十个节点(遗憾的是,有些甚至有几百个节点),这会占用浏览器的所有执行时间

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

WebCL本来是理想的,但自2014年以来,这一点似乎没有实现

我开始考虑在着色器中运行它,但我不能完全理解如何设计它(例如,存储关键帧,即帧->数据的贴图,或者如何写回数据)

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


有人有什么想法吗?

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

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

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

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


最后,这可能根本不适用于Javascript,所以我(现在)没有这样做,即您应该以缓存一致的方式存储和访问数据。看见性能可能会提高10倍。但同样,Javascript可能不起作用,因为Javascript数组不能保证按顺序打包数据。

我的模拟已经以30FPS的速度运行。你链接的幻灯片很好,但是我真的很想知道它们与JS有多相关。事实上,我的节点已经在一个共享类型数组中(尽管所有成员都是按顺序存储的,即
[local\u matrix1,world\u matrix1,local\u location1,…,local\u matrix2,…]
,不确定这是否重要),我想我从来没有注意到这会加速任何事情——实际上我做了这个改变只是为了能够在web工作者周围移动数组。剔除和LOD可能会起作用,但我更喜欢先对最大的N个可见对象尽可能快地进行处理。