问题描述
尝试优化落沙模拟,我正在实施 noita 开发人员在其 GDC talk 中谈到的优化。在 10:45 左右,他们讨论了他们如何使用脏矩形。我已经开始尝试实施类似的系统。
目前,我能够创建一个覆盖需要更新的粒子的脏矩形。每次在块内设置有效粒子(粒子不是空气或固体,如墙)时,我都会这样做,我调用一个函数来更新脏矩形,将放置的粒子位置作为参数。从那里,我可以轻松地从这个位置计算矩形的新最小值/最大值。
这里是更新矩形的代码:
public void UpdateDirtyRect(int2 newPos)
{
minX = Math.Min(minX,newPos.x);
minY = Math.Min(minY,newPos.y);
maxX = Math.Max(maxX,newPos.x);
maxY = Math.Max(maxY,newPos.y);
dirtyrect = .(.(minX,minY),.(maxX,maxY));
//Inflate by two pixels. Not doing this will cause the rect to not change size as particles update
dirtyrect=dirtyrect.Inflate(2);
}
从 gif 图中可以看出,问题在于我目前无法缩小脏矩形。我可以做一些事情,例如检测粒子何时在脏矩形的边界边缘被擦除/替换为空气/固体粒子,但我不确定从那里开始做什么。
解决方法
这是一种可能适合您的方法。
-
保持脏矩形由前一帧更新。
-
计算仅更新一帧的脏矩形。
-
将这两个矩形合并为一个包含它们的单个矩形。
-
使用第 3 步中的矩形更新屏幕。
-
用您在第 2 步计算的矩形替换前一帧矩形。不是您在第 3 步计算的组合矩形,这样做会导致您描述的相同问题。