Re-sorts an already-built render list with §66's sort key 3 — pipeline and
material compatibility — inserted between key 2 and key 5, in place, and
returns it (R-10, 2026-08-09).
buildRenderList(scene, list); // keys 1, 2, 5 — the order every scene has groupRenderListByPipeline(list); // keys 1, 2, 3, 5 — draws grouped for §65
The point of key 3 is that a batcher can only merge draws that are already
adjacent: grouping is what turns an interleaved scene into runs
@fourjs/render-webgl's batcher can collapse (§65, R-9). A scene authored in
groups already — a thousand sprites parented to one node, sharing one atlas —
needs none of this, which is why the builders do not do it.
Why this is a second verb and not a parameter (decision, R-10)
Because the reordering is not always safe, and a default, a flag, or an
option would all put the unsafe case one keystroke from an author who never
read this paragraph:
§61 fixes the depth comparison at LEQUAL, so where two opaque surfaces
sit at the same depth the one drawn later wins. All of this engine's 2D
content sits at one depth. Grouping by material therefore changes the
picture of a 2D scene, rather than only changing the order of its GL
calls — a §58 fill and its stroke, two overlapping shapes, a sprite over a
background quad.
§66 lists key 3 for content whose overlap is resolved by the depth buffer.
That is true of the 3D half of this engine and false of the 2D half, and no
property of a render item distinguishes them.
So the caller who knows their content is depth-resolved (or who is drawing
one flat layer of same-depth-independent sprites) asks for the grouping, and
everybody else keeps the order they have had since 2026-08-06 — byte for
byte, since buildRenderList is untouched by this function's existence.
Stability
Array.prototype.sort is stable (ES2019), so items that compare equal keep
their relative order — which, after buildRenderList, is scene-graph
order. Two consequences: sorting a list that is already grouped changes
nothing at all, and a scene where every item shares one pipeline and one
material is left exactly as it was.
a list produced by buildRenderList or
buildInterpolatedRenderList; sorted in place and returned, so the
pooled items and the caller's array are the same objects afterwards.
Re-sorts an already-built render list with §66's sort key 3 — pipeline and material compatibility — inserted between key 2 and key 5, in place, and returns it (R-10, 2026-08-09).
The point of key 3 is that a batcher can only merge draws that are already adjacent: grouping is what turns an interleaved scene into runs
@fourjs/render-webgl's batcher can collapse (§65, R-9). A scene authored in groups already — a thousand sprites parented to one node, sharing one atlas — needs none of this, which is why the builders do not do it.Why this is a second verb and not a parameter (decision, R-10)
Because the reordering is not always safe, and a default, a flag, or an option would all put the unsafe case one keystroke from an author who never read this paragraph:
LEQUAL, so where two opaque surfaces sit at the same depth the one drawn later wins. All of this engine's 2D content sits at one depth. Grouping by material therefore changes the picture of a 2D scene, rather than only changing the order of its GL calls — a §58 fill and its stroke, two overlapping shapes, a sprite over a background quad.So the caller who knows their content is depth-resolved (or who is drawing one flat layer of same-depth-independent sprites) asks for the grouping, and everybody else keeps the order they have had since 2026-08-06 — byte for byte, since buildRenderList is untouched by this function's existence.
Stability
Array.prototype.sortis stable (ES2019), so items that compare equal keep their relative order — which, after buildRenderList, is scene-graph order. Two consequences: sorting a list that is already grouped changes nothing at all, and a scene where every item shares one pipeline and one material is left exactly as it was.