D-20261102-01|比賽視口固定算圖削減¶
背景與驅動力¶
issue 001173:賽中畫面「頓頓的、前進兩步退一步」在使用者筆電的 Chrome 走 AMD 內顯時,實測根因是 GPU
填充率——主執行緒每 0.5~0.7 秒被一個 300~740 ms 的長動畫幀卡住,幀內 JavaScript 只有 8 ms,其餘是
瀏覽器等 GPU;模擬 Worker 本身平滑。當時 race 視口以原生 DPR 1.5 全尺寸算圖(3457×1879,約 6.5M
pixels)、4× MSAA、透明 canvas。renderer 已要求 powerPreference: 'high-performance',但 Windows
雙顯卡筆電的 Chrome 不一定遵從,使用者得自己改系統顯示卡偏好;一般玩家與手機、平板不會這樣設。
考慮過的選項¶
- A(採納、第一階段):確定性的固定削減——比賽舞台的 drawing-buffer 像素預算由 8,000,000 降為 3,500,000(像素數約減 45%,上述視口落在約 DPR 1.38);比賽、組裝與場地預覽的 canvas 改不透明,省掉 每幀一次合成混色,只有展示車(background 為 null、CSS 背景透出)保留透明。可量化、不改玩法、不隨機器 浮動。
- B(第二階段、另裁決):依 GPU 幀時間自適應算圖倍率(0.6~1.0)作為未知硬體的保險;需定義 frame-time 穩定器與上下限,畫面清晰度會隨機器浮動。
- 其他看過但現況已是最省:後製 composer 只在主題啟用 outline 時才建、目前主題沒有 outline,因此 「composer 存在時 MSAA 不重當」與「沒有效果時繞過後製」兩項沒有可動之處;幀率上限 60 對內顯無助益, 不在本案。
決定¶
O4ThreeStage新增maxDrawingBufferPixels輸入(預設 8,000,000),stagePixelRatio以該預算截斷; viewport 依場景種類傳入:race為O4_RACE_MAX_DRAWING_BUFFER_PIXELS = 3,500,000,其餘沿用 8,000,000。- renderer 工廠的建構屬性改為純函式
rendererContextAttributes({ antialias, alpha });viewport 依場景種類 決定alpha:只有vehicle-showcase為 true。three r163+ 自己開 context 時一律要alpha: true(建構 選項的alpha只影響清除色),因此工廠以createStageWebGLContext用同一組屬性親自開 WebGL2 context 再交給 renderer,不透明才真的落到 context 層(getContextAttributes().alpha === false)。 renderScalePercent(50–100)與antialias設定不變、仍與預算正交;實際比例照舊由 stage 回報。- viewport 的 renderer 工廠只依賴
antialias與canvasAlpha兩個基本型別 signal:同種場景換內容 (組裝頁換零件、多回合換圈)不得重建 renderer,只有 alpha 真的翻轉(場景種類改變)才換工廠。工廠的 建構者走注入點STAGE_RENDERER_FACTORY_BUILDER(預設探測 WebGL 後建真工廠),測試注入假件讓 stage 真的走工廠路徑。 - 守門:
src/viewport/race-render-budget.spec.ts(預算、透明度依種類、工廠親自開 context)、src/viewport/viewport-renderer-factory.spec.ts(工廠穩定性)、ui-kit.spec.ts的stagePixelRatio預算案與 stage 案「像素預算改變即重算 ratio、不換 renderer」。
後果與影響¶
- 比賽畫面在高 DPR 裝置上最多約 DPR 1.38 的清晰度;HUD、文字與 hit target 不受影響(CSS 尺寸不變)。
- 內顯實測(AMD Radeon D3D11、DPR 1.5、track-02 本機測試各 40 秒):3.5M 預算下不透明與透明 context 的長幀 幾乎相同(每秒約 3 個 300 ms 長幀、rAF 約 18 fps、幀內 JavaScript ≤ 6 ms);再把算圖倍率降到 50% (1.6M pixels)長幀降到約 220 ms、rAF 25 fps,仍不流暢。固定削減只按比例縮短 GPU 等待,不能單獨救回內顯 機器的可玩幀率;第二階段(自適應倍率)與 GPU 端逐項成本(陰影、draw call、材質)的量測另案。
- 不改物理、共識、SavedState 或 replay hash。
- 現況規格:程式架構/ui-frontend.md renderer/context 預算段、 程式架構/settings.md 的 drawing-buffer ratio 說明。
- 與既有決策的關係:amends D-20261028-04 的呈現層成本面 (效能警告與分級不變)。
定案紀錄¶
2026-11-02 使用者裁決分兩階段,先做固定削減(「好」);第二階段自適應另裁。