遊戲 Lag 白皮書 › L1 用戶端遊戲程式
垂直同步(V-Sync)與渲染佇列 V-Sync, render queue
原因 ID cg-vsync · 主要負責 遊戲開發團隊(用戶端開發) · 協同 外部(外部)
在含圖解與實驗的完整版中開啟卡片 →
GPU 畫好的畫格會先在佇列裡堆上幾張,再配合螢幕的更新週期送出,這段期間輸入就被延遲。
為什麼 顯示卡驅動程式預先在佇列中堆積 1~3 張畫格 → 於是 輸入反映到畫面上也要多花這麼多時間 → 畫面上 ping 很低,操作卻沉重遲鈍
- 症狀
- 輸入延遲, 卡頓
- 因素
- 延遲
- 誰會遇到
- 只有我
- 何時
- 一直都有
- 負責單位
- 主要負責 遊戲開發團隊(用戶端開發) · 協同 外部(外部)
- 遊戲開發團隊要做的事
- 支援低延遲模式、縮短畫格佇列、提供略低於更新率的畫格上限選項、手機開啟 frame pacing 功能。
- 外部要做的事
- 引導玩家搭配可變更新率螢幕,把畫格上限設得略低於更新率,並開啟顯示卡驅動程式的低延遲模式。
- 數值參考
- 60Hz 下每張 16.7ms。CPU 比 GPU 或螢幕週期快、佇列的三張(DirectX 11 預設值)全部塞滿時,會多出 50ms。在雙緩衝 V-Sync 下,花了 17ms 的畫格要等到下一次畫面更新的時間點(33.3ms),這段期間上一個畫格會再顯示一次。
- 圖表上
- 一開始就一直偏高 · 從輸入到畫面的延遲
- 查看位置
- 切換 V-Sync、低延遲模式、畫格上限,比較 PresentMon 的 MsClickToPhotonLatency、MsAllInputToPhotonLatency(從滑鼠、鍵盤輸入到送出至螢幕)與 DisplayLatency。MsPCLatency(電腦收到輸入後到送往螢幕)只有在遊戲送出 PC Latency 事件時才會記錄
- 符合的跡象
- 開啟 V-Sync 或沒有畫格上限時,這段延遲增加一兩個畫格(數十 ms),在低延遲模式或略低於更新率的畫格上限下減少。ping 沒有變化
- 不符合的跡象
- 電腦內部的延遲很低、操作仍慢半拍時,是「顯示器、輸入裝置與畫格生成的延遲」;ping 很高時,屬於網路端
- 確認方式
- 在玩家端環境確認
- 深入了解
- 垂直同步(V-Sync)是只在螢幕更新畫面的瞬間才送出新畫格的設定。畫面撕裂會消失,但等待那個瞬間會讓輸入延遲,而且 FPS 掉到 60 以下時,會在 60 與 30 之間來回切換而出現卡頓。可變更新率(VRR)螢幕會配合畫格完成的時機更新畫面,縮短這段等待。手機也會發生同樣的情況。30FPS 的遊戲如果無法把畫格平均地配合 60Hz 螢幕送出,雖然平均是 30FPS,每張畫格停留的時間卻像 49、16、33ms 這樣忽長忽短,造成卡頓(Android 開發文件的例子)。可以用 Android 的 Frame Pacing 程式庫(讓畫格輸出間隔保持均勻)或引擎中的同類選項來改善。
出處
- IDXGIDevice1::SetMaximumFrameLatency Microsoft
驅動程式可在佇列中堆積的畫格數,預設值 3(1~16) - Reduce latency with DXGI 1.3 swap chains Microsoft
Present 會被阻塞直到佇列空出位置,畫好後到顯示前幾乎要多等一個畫格;可用 waitable swap chain 縮短 - Frame Pacing library Android (Google)
60Hz 螢幕沒有新畫格時會再顯示上一個畫格;以 30FPS 遊戲的畫格時間變成 49、16、33ms 這樣忽長忽短為例 - PresentMon Capture Application (README-CaptureApplication.md) Intel
MsPCLatency(電腦收到輸入到送往螢幕)、MsClickToPhotonLatency(滑鼠點擊到畫面)、MsAllInputToPhotonLatency(鍵盤、滑鼠輸入到畫面)、DisplayLatency(提交畫格到送往螢幕) - PresentMon Console Application (README-ConsoleApplication.md) Intel
MsPCLatency 要應用程式送出 PC Latency 事件才會記錄(--track_pc_latency),MsAllInputToPhotonLatency 以鍵盤、滑鼠輸入為準
相關原因
同一層:L1 用戶端遊戲程式
同一症狀(輸入延遲)在其他層的原因
查看含圖解與實驗的完整版卡片