在没有屏幕撕裂的情况下实现较低的帧速率
Achieving lower frame rates without screen tearing
我想在游戏中达到 24fps。我可以使用以下代码执行此操作:
IsFixedTimeStep = info.fixedTimeStep;
TargetElapsedTime = TimeSpan.FromSeconds(1f / 24f);
然而,这会产生卡顿帧率或屏幕撕裂,具体取决于是否启用垂直同步。我预计会出现这种情况,因为显示器的 24fps 和 60fps 不匹配。
我决定改为尝试达到 30fps:
IsFixedTimeStep = info.fixedTimeStep;
TargetElapsedTime = TimeSpan.FromSeconds(1f / 30f);
然而,此 也 会产生图像卡顿或屏幕撕裂。我不明白为什么当 30fps 是 60fp 显示器刷新的一半时会发生这种情况。可能是涉及到的帧率不准确?
谷歌搜索让我发现我可以通过让 Monogame 同步每隔一次屏幕刷新来获得更好的结果:
graphics = new GraphicsDeviceManager(game);
graphics.PreparingDeviceSettings += (sender, e) =>
{
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.Two;
};
[编辑 1:我注意到这是一个坏主意,因为它假设显示器刷新率为 60,所以我更需要一个更好的方法!]
[编辑 1.1:我发现此行指定 60fps 作为基础,然后使用上述达到 30fps 的技术:
game.TargetElapsedTime = TimeSpan.FromTicks(166666);
]
这给了我大约 30fps 的速度,但结果很流畅。这对我来说是一个可以接受的结果,但我想知道是否有人知道有什么方法可以达到接近 24fps 的水平?或者如果没有 jittering/tearing 是不可能的?
非常感谢!
[编辑 2:无论是在独家全屏还是无边框 window 模式下,我得到的结果都是一样的。]
好吧,我想出了我认为最好的解决方案。这给了我 24fps 的结果,结果非常流畅(可能会达到 24fps 的流畅度)。
IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromTicks(208333); // 48fps (will be halved to 24fps).
// The following effectively halves the frame rate to 24fps by syncing every other refresh.
graphics.PreparingDeviceSettings += (sender, e) =>
{
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.Two;
};
它比仅使用 TimeSpan.FromTicks(416666) 将其设置为 24fps 提供更好的结果。我不确定这是为什么。
30fps 可以通过将 FromTicks 值调整为 60fps 来实现,然后减半为 30fps。同样,它为我带来了比一开始只瞄准 30fps 更好的结果。
我想在游戏中达到 24fps。我可以使用以下代码执行此操作:
IsFixedTimeStep = info.fixedTimeStep;
TargetElapsedTime = TimeSpan.FromSeconds(1f / 24f);
然而,这会产生卡顿帧率或屏幕撕裂,具体取决于是否启用垂直同步。我预计会出现这种情况,因为显示器的 24fps 和 60fps 不匹配。
我决定改为尝试达到 30fps:
IsFixedTimeStep = info.fixedTimeStep;
TargetElapsedTime = TimeSpan.FromSeconds(1f / 30f);
然而,此 也 会产生图像卡顿或屏幕撕裂。我不明白为什么当 30fps 是 60fp 显示器刷新的一半时会发生这种情况。可能是涉及到的帧率不准确?
谷歌搜索让我发现我可以通过让 Monogame 同步每隔一次屏幕刷新来获得更好的结果:
graphics = new GraphicsDeviceManager(game);
graphics.PreparingDeviceSettings += (sender, e) =>
{
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.Two;
};
[编辑 1:我注意到这是一个坏主意,因为它假设显示器刷新率为 60,所以我更需要一个更好的方法!]
[编辑 1.1:我发现此行指定 60fps 作为基础,然后使用上述达到 30fps 的技术:
game.TargetElapsedTime = TimeSpan.FromTicks(166666);
]
这给了我大约 30fps 的速度,但结果很流畅。这对我来说是一个可以接受的结果,但我想知道是否有人知道有什么方法可以达到接近 24fps 的水平?或者如果没有 jittering/tearing 是不可能的?
非常感谢!
[编辑 2:无论是在独家全屏还是无边框 window 模式下,我得到的结果都是一样的。]
好吧,我想出了我认为最好的解决方案。这给了我 24fps 的结果,结果非常流畅(可能会达到 24fps 的流畅度)。
IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromTicks(208333); // 48fps (will be halved to 24fps).
// The following effectively halves the frame rate to 24fps by syncing every other refresh.
graphics.PreparingDeviceSettings += (sender, e) =>
{
e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.Two;
};
它比仅使用 TimeSpan.FromTicks(416666) 将其设置为 24fps 提供更好的结果。我不确定这是为什么。
30fps 可以通过将 FromTicks 值调整为 60fps 来实现,然后减半为 30fps。同样,它为我带来了比一开始只瞄准 30fps 更好的结果。