allenchou.net
遊戲程式:時間切割 | Ming-Lun "Allen" Chou | 周明倫
[latexpage] Here is the original English post.本文之英文原文在此 前備教學 延遲蒐集運算結果 簡介 於上一個教學中,我以曝光迴避作為範例來示範如何使用延遲蒐集運算結果的優化技巧。基本概念就是在工作執行緒(worker threads)上開始運算工作,然後等一會兒之後才蒐集運算結果,如此可以避免佔據主執行緒。 如果遊戲可以負擔一禎的延遲,那就可以等到下一禎才蒐集工作運算結果。如果遊戲無法負擔一禎的延遲,仍然可以嘗試在同一禎等待到稍後再蒐集結果。 但如果有工作無法在一禎之內運算完畢,又或有工作需要的運算時間比我們希望的還要長時,該怎麼辦?這時我們可以把工作量分配給多禎,這正是時間切割的核心概念,這是另外一個我從工作中學到且最喜歡的優化技巧之一。 仔細想想,其實時間切割隨處可見。材質串流、無接縫載入等,這些不會拖垮遊戲禎率的"背景運算"都可歸類為時間切割。沒有辦法在一禎之內完成運算,那就多用幾禎來算吧,這是個很單純卻非常有效的做法。 回顧曝光地圖範例 回想上個教學中的曝光地圖範例。有設置射線投射的工作、實際計算射線投射的工作、和蒐集計算結果的工作。曝光地圖的更新函式啟動這些工作,然後於下一禎蒐集計算結果。 以下是各工作的結構: struct RaycastSetupJob : IJobParallelFor { public Vector3 EyePos; [ReadOnly] public NativeArray Grid; [WriteOnly] public NativeArray Commands; public void Execute(int index) { Vector3 cellCenter = Grid[index]; Vector3 vec = cellCenter - EyePos; Commands[index] = new RaycastCommand(EyePos, vec.normalized, vec.magnitude); }