Perf: transparent pass is 601 per-submesh draws and now the largest render cost
Part of #158.
Problem
After #162 and #161 (closed), the transparent pass is the largest remaining render cost in the frame — 2.47 ms, 44 % of render.scene's 5.62 ms, and larger than the opaque submission it sits inside.
From docs/decisions/bistro-perf-baseline.md:
| pass | CPU | draws | indirect |
|---|---|---|---|
| render.main (incl. transparent) | 3.93 ms | 194 | 3,271 |
| ├─ render.transparent | 2.47 ms | 601 | 0 |
| render.shadow | 0.96 ms | 776 | 13,084 |
| render.prepass | 0.38 ms | 194 | 3,271 |
| render.upload | 0.26 ms | 0 | 0 |
It is the one draw path that received neither of the two fixes above. 601 individual draws — one per transparent submesh — each doing its own reflection_probes.resolveForSubmesh, its own buildDrawParams, and a full uniform push and sampler bind, plus a back-to-front pdq sort over the whole set.
It cannot simply adopt the indirect path: correct alpha compositing needs per-submesh depth ordering, and an indirect multi-draw over a material group draws in buffer order.
Directions, roughly in order of effort
- Hoist the per-draw work out of the sort loop.
buildDrawParamsand the probe resolve run per transparent submesh every frame even though both are per material; the only thing that genuinely varies per submesh is the index range and the sort key. Group the resolve, keep the sort per submesh. - Sort material-group runs, not individual submeshes, where a group's submeshes don't overlap in depth. Falls back to per-submesh where they do.
- Sort on the GPU and drive an indirect draw from the sorted order — the general fix, and the largest.
- Order-independent transparency — changes the look, so out of scope unless the sort itself proves unfixable.
Bistro's transparent set is foliage and storefront glass, so this is not a corner case for the sample.
Acceptance
-
render.transparentCPU measurably reduced against the baseline (#159 (closed) harness) - Fixed-camera before/after at the terrace viewpoint: foliage and glass composite identically
- The interior stays visible through the storefront glass (the #156 acceptance shot)