diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 58b9c38c87..f63b22d0a5 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -133,28 +133,8 @@ namespace OpenRA.Graphics foreach (var e in World.ScreenMap.RenderableEffectsInBox(Viewport.TopLeft, Viewport.BottomRight)) renderablesBuffer.AddRange(e.Render(this)); - renderablesBuffer.Sort((a, b) => - { - // Sort is an unstable sort, so elements with the same Z position may get sorted differently each frame. - // This leads to flickering when rendering several frames as the elements get swapped at random. - // To combat this, use a series of arbitrary tie-breaks to determine the "top-most" element. - // This ensures a consistent decision for which one is on top, preventing flicker. - var compared = RenderableZPositionComparisonKey(a).CompareTo(RenderableZPositionComparisonKey(b)); - if (compared != 0) - return compared; - - compared = a.Pos.X.CompareTo(b.Pos.X); - if (compared != 0) - return compared; - - compared = a.Pos.Y.CompareTo(b.Pos.Y); - if (compared != 0) - return compared; - - return a.Pos.Z.CompareTo(b.Pos.Z); - }); - - foreach (var renderable in renderablesBuffer) + // Renderables must be ordered using a stable sorting algorithm to avoid flickering artefacts + foreach (var renderable in renderablesBuffer.OrderBy(RenderableZPositionComparisonKey)) preparedRenderables.Add(renderable.PrepareRender(this)); // PERF: Reuse collection to avoid allocations.