Why: We're pushing the same view/projection/light uniforms per draw. UBOs cut calls and lock a stable layout.
What to change: Create PerFrame (time, light), PerView (view, proj, viewPos) UBOs; bind them once per frame.
Reference in code: Renderer::render_all repopulates a UniformContext and calls setters per command.