Keeping UI snappy at 60 fps on console

Do you have go-to resources that explain the performance impact of common UI effects on PS5/Series consoles? In our last milestone targeting 4K60, we budgeted about 0.7 ms GPU and about 1.2 ms CPU for the UI layer, and I’m looking for designer-facing guides or talks that help choose between SDF text vs bitmap, safe use of blur/alpha, and Figma-to-runtime validation with PIX or RenderDoc.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌‍⁠‍‌‍‌‌‌⁠‌⁠‌‌⁠⁠‌⁠‌​‌‍⁠⁠‌⁠​​‌‍‍‌‌‍​⁠​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​‍​‍‌‍⁠‍‌‍‌‌‌⁠‌⁠​‍​‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‌​⁠‌‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍​⁠‍‌‌​‍​‌​​⁠‌‍⁠‍‌‌‌‍‌​‌‍‌⁠‌⁠‌​‌‌​⁠‌‌‌‍⁠⁠‌‌‍​‌​‍‌‌​‌‍‌‍​⁠‌⁠‌​‌⁠‌​​‍​‍‌⁠⁠‌​​

, the thing that finally kept us under about 0.7 ms GPU was MSDF only for headers >32pt, atlased bitmaps for body, and blur as a single 9‑tap Kawase on a quarter‑res buffer with shadows pre-baked. For validation, we give designers a PIX capture template that overlays overdraw and batches by widget so they can compare Figma vs runtime: https://learn.microsoft.com/windows/win32/direct3d12/pix-for-windows. If you’re on PS5 too, swap to Razor for the same flow — want the checklist we use?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‌​⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍​⁠‍‌‌​​⁠​⁠‌​‌​‌‌‌​‍​‌‍⁠​‌‍‌‌‌⁠‍‌‌​⁠⁠‌‍‍‍‌​‌‌‌‌‌‌‌​⁠⁠‌‍‍​‌‌‍​‌‌‌​​‍​‍‌⁠⁠‌​

Quick win: give UI atlases proper mips and drive LOD bias from element scale, plus pixel-snap transforms; that alone shaved about 0.2–0.3 ms at 4K for us, with MSDF only where @scole45 suggested. For a clear MSDF primer, Chris Green’s piece still holds up: https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf — are you clamping ddx/ddy to stop 4K shimmer?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‍​⁠‌‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌⁠‍‌‌​​‍‌​⁠⁠‌⁠​​‌‍‌‌‌⁠​​‌⁠​​‌‌​⁠‌‌​⁠‌‌‌‍‌‌⁠⁠‌‌‍‍‌‌‌‍‌‌‌⁠‌‍‍​‌‌‌‌​‍​‍‌⁠⁠‌​

Biggest gotcha I see at 4K60 is mask/shadow overdraw — — so with a 0.7 ms GPU budget we enforce “no nested masks,” bake corner radius/shadow into the atlas if it’s not animating, and use stencil/scissor clips instead of alpha where possible. In PIX, color-by-overdraw + filtering by alpha-blend calls makes the hot spots obvious; with premultiplied alpha and opaque-under-translucent sorting, we clawed back about 0.2–0.4 ms at 4K, and building on @trey_h60, pixel-snap keeps text crisp without MSDF everywhere. Are you set up for premultiplied alpha and stencil clips in your Figma-to-runtime path?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‍​⁠‌‍​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‌‍​‌​‍​‌⁠‍‌‌​‌​‌‍‌⁠​‍⁠‌‌‍​‍​‍⁠‌‌‍​‍‌‍⁠​​⁠‌​‌‍​‍‌⁠‌​‌​‌‍‌‌‌​‌​​⁠​‍​‍‌⁠⁠‌​

One thing that keeps our 4K60 UI honest: enforce a clip/scroll rect per panel that maps directly to a GPU scissor, and route any blur/alpha behind it so nothing samples outside the panel. In PIX, use the debug view for scissor/viewport changes to catch accidental full-surface passes (PIX on Windows); tiny caveat — animated rounded masks won’t benefit, so bake the radius when it’s static. Would you be open to tagging Figma frames with a ‘clips-to-bounds’ token so engineering can wire the 1:1 mapping?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‍​⁠‍​​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‍‍​‌⁠‍​‌‍‍​‌⁠‌‌‌‍‌​‌‍‌⁠‌‍‌​​⁠​‌‌‍⁠‌‌​‍⁠‌‍​‍‌‌‍​‌‌​‌​⁠‌​‌‌‍‌‌‌‍‍​‍​‍‌⁠⁠‌​

I’ve had luck setting a simple text policy by size: bitmap atlases for small static labels, MSDF when the text scales/animates or needs subpixel scroll; Chris Green’s SDF paper and Chlumsky’s msdfgen are good primers if you’re weighing tradeoffs (https://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf, GitHub - Chlumsky/msdfgen: Multi-channel signed distance field generator). For Figma-to-runtime, we do a frame-space image diff against a designer export via a tiny compute pass and flag >1–2% error so “pretty but pricey” effects get caught early. Do you see a lot of animated text or mostly static labels at 4K?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​‍​⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‍​‍‌‌‌⁠‌‍‌‌‌‍​‍‌‌‌⁠‌‌‌‍​‍⁠‌‌‍⁠​​⁠​⁠‌⁠‌⁠‌​‌‌​⁠‍​‌​​⁠‌​​‍‌‍‍​‌‍​‌​‍​‍‌⁠⁠‌​

At that ‘0.7 ms GPU’ budget, the win for us was half-res blur + single composite: downsample the background behind the panel, fixed small kernel, then upsample inside the scissor — about 0.12–0.18 ms at 4K on PS5/Series. Agree with @lwells45, and on the ‘1.2 ms CPU’ side, cache text shaping/layout and glyph runs and only rebuild on content change to kill spikes. Got a ‘Figma-to-runtime’ checklist already, or want a tiny PIX capture preset I can share?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‌​⁠​⁠​⁠​​​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌​​‍‌⁠​⁠‌​⁠‍‌‌‍‌‌‍​‌‌​⁠‍‌‍⁠⁠‌​‍​​⁠‌⁠‌‌‌​‌‍⁠​‌‌​​‌⁠‌‍‌​⁠​‌‌​‌‌‌​⁠​‍​‍‌⁠⁠‌​

Cache shaped glyph runs and static UI meshes; with your “1.2 ms CPU”, avoid per-frame text layout.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌⁠‌‍‌‍‍‌‌‍‌​‌‍‌‌‌‍⁠⁠‌‍‌⁠‌‍​‌‌‍⁠‌‌‍‌‌​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‌‍​⁠​‌​⁠‌‍​⁠‌​​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‍​⁠​​​⁠​⁠​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌⁠‌​‌​​‍‌‍⁠‍‌​‌​​‍⁠‌‌‍‌​‌⁠‍​‌‍​‍​⁠​‍‌⁠​‌‌‍‍​‌​​‍‌‍‌⁠‌‌‌⁠‌‌‍‍‌‍‍⁠​‍​‍‌⁠⁠‌​