March 12, 2020

矩阵 decompose 的一点优化

我们的游戏引擎中,有个重要的功能是将一个矩阵分解成 S 缩放,R 旋转,T 位移三个分量。这里 T 直接取矩阵的第四行即可,代价比较高的是 S 和 R 的分解,其中 R 又取决于 S 的提取。

但是,游戏中大量的矩阵中是不包含缩放的,即 S 分量大多是 (1,1,1) 。一旦不用缩放,又可以简化 R 提取的操作。所以我打算对传统算法做一点优化。在提取 S 的时候多加一次判断,看值是否接近 1 。

计算 S 的方法是将矩阵的前三行当作三个 vector 3 分别取 length 。length 其实是取 dot 然后计算 sqrt。由于大多数情况预测 dot 值很可能为 1 ,那么当 dot 接近 1 的时候,就不必再开方了。

阅读全文 "矩阵 decompose 的一点优化" »

March 11, 2020

不变量及运算优化

去年的时候,我们对正在开发中的游戏引擎做了一点 profile 工作。后来发现,在场景中对象很多的时候,有一处运算占据了 10% 以上的 cpu 时间。当时我的判断是,这处地方值得优化,但并不是工作重点,所以就搁置了。

问题的具体描述是这样的:

我们的引擎每帧会将场景中的对象依次提交到一个渲染队列中,每个可渲染物件,除了自身的网格、材质外,还有它自身的包围盒(通常是 AABB),以及它在世界空间中的矩阵。

我们有一套资源系统,场景中的对象会引用资源系统中的对象,这些资源对象是一个不变量,会被多个场景对象所引用。而资源对象又可以是一个树结构,比如一个模型就可以由若干子模型所构成。提交到最终渲染队列中的是不可再拆分的子模型的信息。

也就是说,在场景管理的层次,对象的数量是远少于提交到渲染队列中的对象数量的。这就是为什么我们渲染每次重建渲染队列,而没有将每帧提交给渲染队列的列表持久化为一个链表并作增减维护的原因。

问题出在提交给渲染队列的每个物件的包围盒上。

阅读全文 "不变量及运算优化" »

February 12, 2020

git shallow clone 的一个问题

最近在家办公,遇到的第一个问题就是家里网络极不稳定,无法 git clone 那些庞大的仓库。我知道 git 现在支持浅拷贝,用 --depth 1 就可以取出某个分支的 HEAD 指向的拷贝所依赖的所有文件。

但是,光用 git clone url --depth 1 还不能解决我的所有问题。因为需要传输的文件还是太大,不稳定的网络无法坚持到我顺利下载完成就断开了。而 git clone 得下载过程似乎不能续传,我只好另辟蹊径。

过去翻 git 文档时,曾经了解过有一个 git bundle 这个指令可以对需要传输的内容打包,然后大多数依赖接受数据的 git 指令都可以直接接收用 git bundle 打好的包,而不必通过网络传输。事实上,git clone 的过程就是在远程打好包,然后传输到本地,再解开的。

阅读全文 "git shallow clone 的一个问题" »

February 05, 2020

skynet 版的 cache server 改进

去年我实现的 Unity cache server 的替代品 已经逐渐在公司内部取代 Unity 官方的版本。反应还不错,性能,可维护性以及稳定性都超过官方版本。

最近疫情严重,公司安排所有人员在家办公,今天是开工第三天。前两天比较混乱,毕竟在家办公的决定是在假期中间做出的,并没有预先准备,我们的这个 cacheserver 也在第一天受到了极大的考验,暴露出一个问题,好在只是内存用量预警,并没有出任何差错。我花了一天多的时间排查和解决问题,感觉这是一个极好的案例,值得记录一下。

阅读全文 "skynet 版的 cache server 改进" »

January 19, 2020

不适合采用 System 的一种情况

ECS 框架中,System 通常是对某种 Component 的集中处理。大部分情况下,一次性对大量对象中的简单的数据结构做简单的处理,比每次对一个对象的复杂数据结构(通常是简单数据结构的组合)做复杂处理,依次处理所有的对象要更好。

凡事总有例外。我们最近就发现有一类情况不适合这样做。那就是骨骼动画的骨骼计算。

骨骼计算会分为若干步骤,有骨骼数据的展开,骨骼姿态的混合,IK 计算等等。一开始,我们遵循着 ECS 的设计原则,把这些步骤分到不同 System 种。例如并非所有的对象都需要做 IK 计算,这样 IK System 就只用遍历一个子集;同样,也并非所有的动画都需要做多个姿态的混合,等等。

阅读全文 "不适合采用 System 的一种情况" »

January 13, 2020

ECS 中的概念缺失

经过长时间的思考和实践,最近一个多月,我们的 ECS 框架做了较大的调整。其中一部分工作已经在前一篇消息发布订阅机制中介绍,另一部分工作其实开展的更早,但因为我想多沉淀一段时间再写。到本周基本基本改动完毕,可以总结一下了。

ECS 框架几乎只在游戏开发领域提出,我认为这主要是因为目前只有在游戏领域,周期性的大量对象的状态变换才是主流行为。而在其它人机交互领域,响应外部事件才是主流。这是为何 System 在游戏领域如此重要的原因。

但另一方面,ECS 框架对过去流行的面向对象框架的反思,主要集中在面向数据/数据驱动。这是 Component 概念被如此看重的原因。Component 是行为被拆分出来的对象,重要的是数据本身。对于框架来说,要解决的是更方便的组合、有完善的自省机制,这才能针对数据集本身来编程。因为游戏开发,程序员的工作仅占很少的部分,大部分的工作是策划和美术围绕开发工具给数据添砖加瓦的。

阅读全文 "ECS 中的概念缺失" »

December 24, 2019

ECS 中的消息发布订阅机制

我们在实践 ECS 框架时发现,之所以 ECS 的概念诞生于游戏领域,是因为游戏程序往往都在周期性的处理一批对象,进行运算,根据上个周期的状态得到下个周期的状态。而传统人机交互的应用则是响应型的:即一个外部请求触发一系列的业务运作。

如果你把游戏业务塞到响应型框架中,就会发现,不得不用时间去触发,业务响应的是 timer 。但这种情况下,timer 几乎没有携带任何状态,对单个 timer 的响应,是不可能做成无状态的:它本身就是整个游戏世界对上个状态的迭代。

这种情况下,响应式框架就很低效。

阅读全文 "ECS 中的消息发布订阅机制" »

Misc

Categories

Archives

Recent Comments