> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XBOX Series X|S 光線追蹤最佳做法

> XBOX Series X|S 光線追蹤最佳做法

本主題說明在 XBOX Series X|S 上進行光線追蹤的最佳做法。

光線追蹤在 XBOX Series X|S 上已成為可行的轉譯技術超過一年，在利用 XBOX 硬體達到最高效能方面，我們也累積了許多經驗。本主題摘要說明我們所學到的重要事項，並提供在 XBOX Series X|S 上開發支援光線追蹤的高品質遊戲的提示、技巧與最佳做法。

<Note>
  此資訊截至 2022 年 4 月為最新狀態。自那時起，已有多項功能變更或更新。
</Note>

<a id="raytracing-on--term-scarlett" />

## XBOX Series X|S 上的光線追蹤

光線追蹤功能在 XBOX Series 主機上的採用情況相當熱烈。目前已有超過 20 款遊戲在 XBOX Series X 上推出時支援光線追蹤。其中有數款遊戲後續也在 XBOX Series S 上支援光線追蹤。陰影和環境光遮蔽等簡單效果很常見，有些遊戲也實作了反射和全域照明。

在 Xfest 2019 時，2019 年 11 月 GDK 才剛發行，還沒有任何遊戲使用光線追蹤執行。到了 2020 年底，只有三款遊戲在 2020 年 8 月 GDK 上執行。自那時起，執行階段已進行了多項改進。我們現在對於如何在主機上取得良好的光線追蹤效能有了更深入的了解。

<a id="runtime-bvh-builder" />

## 執行階段 BVH 建置器

*執行階段 BVH* (邊界體積階層) \_建置器\_會在 GPU 上執行，因此它會耗用原本可用於點陣化或光線追蹤的 GPU 時間。到目前為止，所有遊戲都使用執行階段 BVH 建置器來建置其頂層加速結構 (TLAS)。這些遊戲會在每個畫面進行完整重建，因此請勿嘗試更新 TLAS。對於底層加速結構 (BLAS)，大約一半的遊戲仍使用執行階段 BVH 建置器處理靜態幾何，另一半則使用離線 BVH 建置器。對於動態幾何，所有遊戲仍繼續使用執行階段 BVH 建置器，因為這是唯一的選項。

執行階段 BVH 建置器的建置時間效能在預設情況下就相當出色。它已在 PC 上與 NVIDIA 和 AMD GPU 進行基準測試，並展現出優異的效能。開發人員表示，他們希望有明確批次處理的建置 API，可同時建置多個加速結構，以獲得更好的 GPU 效能。開發人員的意見反應是，效能至少提升了 10 倍，甚至達到 20 倍。若要了解這些速度提升從何而來，了解執行階段 BVH 建置器的運作方式非常重要。

建置 BVH 並非單一分派，甚至不是兩個分派。它是一連串的許多分派，全部接連執行，中間穿插無序存取檢視 (UAV) 屏障。透過在單一 API 呼叫中提供所有底層建置，可以更有效率地排程這些建置，並減少該階段的 UAV 屏障數量。

**圖 1.  投影片 8。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S08.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=55edb4d4d06315379588d0f64caae956" alt="投影片 8" width="1160" height="651" data-path="images/gdk/features/graphics/GR09-S08.png" />

自 Xfest 2019 以來，我們變更了周遊的運作方式。四邊形是 BLAS 儲存幾何的基礎。在上一屆 Xfest 時，AMD 節點中的三角形 2 (Tri2) 和三角形 3 (Tri3) 仍在使用中，並如圖 1 所示由硬體提供。部分旁頻中繼資料儲存在 BVH 中，並在周遊期間明確載入。藉由捨棄使用 Tri2 和 Tri3，頂點 4 現在可以儲存幾何中繼資料。現在，當需要存取此資料時，它更有可能位於快取中，因而提供更好的效能。

這主要是效能最佳化，但代價是記憶體中的 BLAS 會比使用 Tri2 和 Tr3 時稍大。執行階段建置器會從清單中相鄰的三角形配對形成四邊形。第一個執行緒會檢查第一個和第二個三角形是否形成四邊形，第二個執行緒檢查第三個和第四個三角形，第三個執行緒檢查第五個和第六個三角形，依此類推。每個執行緒都會檢查第 \_N\_ 個和第 \_N\_+1 個三角形是否可以形成四邊形，從而在葉節點中使用 Tri0 和 Tri1。

**圖 2.  投影片 10。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S10.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=6ff1fabae442fe27d45fb10a21914702" alt="投影片 10" width="1159" height="650" data-path="images/gdk/features/graphics/GR09-S10.png" />

在圖 2 左側的圖表中，兩個三角形沒有共用邊，因此不會形成四邊形。中間有兩個形成四邊形的三角形，它們近似於矩形，是合適的四邊形。右側的兩個三角形形成了四邊形，但包含它們的 AABB 膨脹過於顯著。這會被拒絕作為四邊形，改為在每個節點中各放置一個三角形。

允許的方塊膨脹容許度由四邊形形成閾值控制。閾值越大，就會越積極地嘗試從這兩個三角形形成四邊形。這會產生較小的 BVH，因為三角形節點較少，但代價是周遊效能較低。相反地，如果將閾值設低，則只會將近似矩形或四邊形形狀的兩個三角形四邊形化，這會產生較大的 BVH，但可能會提升周遊效能。

使用非同步計算來建置 BVH 並非必要，但能大幅提升效能。許多此類建置 (特別是頂層建置) 不會使用 GPU 的完整寬度，尤其是在具有 26 個 WGP/52 個 CU 的 XBOX Series X 上。透過執行批次建置 API 和非同步計算，您可以有效隱藏大部分 BVH 建置的成本。以某款遊戲為例，開發人員將 1.5 毫秒的 TLAS 建置移至非同步計算，幾乎沒有任何成本。如果可以在畫面中需要加速結構之前很早就開始建置，它們可能是非同步計算的理想候選項目。

頂層和底層建置有一系列旗標，您在 PC 上工作時應該已經很熟悉。在建置中，這些旗標控制兩個不同的系統。一個是在 BVH 中使用 FP16 AABB 的積極程度。第二個是對 BVH 執行稱為\_小樹重建\_ (treelet reconstruction) 之程序的程度。這兩項可透過使用批次 [BuildRaytracingAccelerationStructureBatched2X](/zh-TW/reference/graphics/d3d12_xs/interfaces/ID3D12GraphicsCommandList6/methods/id3d12graphicscommandlist6_buildraytracingaccelerationstructurebatched2x) API 進行設定。

請務必了解，AMD RDNA 2 GPU 同時支援 FP16 AABB 和 FP32 AABB。這並非全有或全無的決定。建置出的 BVH 可在單一 BVH 中同時包含 FP16 和 FP32 AABB。FP16 AABB 的大小是 FP32 AABB 的一半，可提高快取命中率。它們必須保守地膨脹，以確保包含其中的所有幾何。從 FP32 量化為 FP16 會根據數值讓這些方塊變大。這可透過使用 FP16 方塊膨脹閾值成員和 [FP16BoxInflationThreshold](/zh-TW/reference/graphics/d3d12_xs/structs/d3d12xbox_build_raytracing_acceleration_structure_params1) API 進行設定。此閾值設得越低，使用的 FP32 方塊就越多，這些 BVH 會使用更多記憶體，但較緊密的邊界可提供更快的周遊效能。相反地，如果將閾值設高，就會使用更多 FP16 AABB，使用較少記憶體，邊界較鬆散，周遊效能也較低。

### 小樹重建

執行階段建置器使用線性 BVH (LBVH)。它很容易平行化，是在 GPU 上實作的良好候選項目。在其原始形式中，LBVH 的品質可能不佳。為了提升這些 BVH 的品質，會執行後續的小樹重建程序。如果您對詳細資料有興趣，請參閱 [Fast Parallel Construction of High-Quality Bounding Volume Hierarchies](https://research.nvidia.com/sites/default/files/pubs/2013-07_Fast-Parallel-Construction/karras2013hpg_paper.pdf)。此程序會排列 BVH 的子樹以改善表面積啟發式，進而提升周遊效能。

### 頂層加速結構上提 (TAPU)

執行階段 BVH 與 TLAS 相關的另一個選項是\_頂層加速結構上提 (TAPU)\_。在 TLAS 中，執行個體邊界大且互相重疊。相機經常位於執行個體內部，因此光線原點位於執行個體邊界內。因此，周遊程式碼在進行周遊時很難沿著 BVH 中的最佳路徑前進。硬體會同時針對四個方塊測試光線，並依距離排序傳回這四個命中結果。如果光線位於全部四個方塊內，則在所有情況下到交點的距離都是零。傳回的順序是未知的，但您需要與幾何緊密貼合的執行個體邊界。這就是 TAPU 最佳化發揮作用並改善情況之處。

**圖 3.  投影片 17。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S17.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=1f2439a599c101afd034eb5cd1642202" alt="投影片 17" width="1157" height="651" data-path="images/gdk/features/graphics/GR09-S17.png" />

圖 3 顯示一系列交通號誌的結構，這些號誌安裝在懸掛於水平桿上的垂直桿上。左側的藍色虛線方塊是執行個體邊界。整個結構是一個 BLAS，而這些是執行個體邊界。光線有空間可以從底部的空白處穿過。右側則沒有。

**圖 4.  投影片 18。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S18.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=e884b01a655d2df833cd2fe4ff27cf85" alt="投影片 18" width="1159" height="651" data-path="images/gdk/features/graphics/GR09-S18.png" />

在圖 4 中，頂端的執行個體包含在單一方塊中。這會進入 BLAS 的第一層。您也可以往下兩層，查看如下方圖例所示的前 16 個方塊。這些方塊會被取出，然後上提至 TLAS 中，因此稱為 TAPU。這表示從交通號誌下方通過的光線 (先前會與執行個體邊界相交) 不再與之相交。原本在從 TLAS 轉換到 BLAS 時會執行的任何程式碼，都不再需要執行。

<a id="offline-bvh-builder" />

## 離線 BVH 建置器

XBOX Series X|S 推出時並沒有\_離線 BVH 建置器\_，而是在 2020 年新增的。如果您在 PC 上發行遊戲，您會使用標準 API 來建置 BVH。BVH 的格式對身為開發人員的您來說是完全不透明的。您無法離線建置 BVH、將其放在光碟或數位下載內容中，然後讓客戶下載預先建置的 BVH。PC 上有一個 API，可讓您在執行階段建置 BVH、將其快取至硬碟，然後再重新載入。由於硬碟速度可能很慢，而且這些 BVH 可能會因驅動程式更新而失效，因此這樣做的價值相當低。

由於 XBOX Series 主機是固定平台，並具有高速 SSD 儲存體，我們可以離線建置 BVH，然後將其放在 SSD 上發行。就像我們可以為 XBOX Series X|S 發行預先混排的紋理一樣，我們也可以預先建置 BVH。

2020 年 5 月 GDK 新增了離線 BVH 建置器的支援。這是在 CPU 而非 GPU 上執行的程序，而且是在 Windows PC 而非主機上執行。離線 BVH 建置器是建構在 Intel Embree 業界領先技術之上的世界級建置器。我們運用這項技術，可將 Intel Embree 建置的 BVH 轉換為 XBOX Series X|S 硬體可直接使用的 BVH。載入此 BVH 後，在執行階段使用它不需要任何額外處理。目前它僅用於 BLAS。尚未有開發人員要求離線建置 TLAS，進行此類建置的價值不大。

當我們在 2020 年 5 月首次發行離線 BVH 建置器時，並不支援 `BUILD_FLAG_ALLOW_UPDATE` 建置。這表示任何經過蒙皮的內容 (例如角色、樹木和草) 都無法離線建置，因為無法在執行階段重新調整。基於您的意見反應，此旗標已新增至 2021 年 4 月 GDK。離線 BVH 建置器現在適用於任何非程序性內容，例如您在離線時就已經知道外觀的幾何。如果玩家可以塑造或雕刻新內容，此旗標可能就不適用，因為開發人員在離線時無法得知其外觀。這是目前唯一不適合使用離線 BVH 建置器的情況。

請使用此選項，因為它不會像執行階段 BVH 建置器那樣耗用您的 GPU 畫面預算。離線 BVH 建置器不僅能節省 GPU 時間，與執行階段 BVH 建置器相比，它還能產生品質高得多的 BVH。離線 BVH 建置器也會產生近乎完美的四邊形配對。不同於執行階段 BVH 建置器由單一執行緒分析兩個相鄰三角形，離線 BVH 建置器會進行完整搜尋。如果三角形 7 需要與三角形 12 配對才能建置最佳四邊形，它就會這麼做。此外，離線 BVH 建置器不需要暫存記憶體。您只需從磁碟載入即可，不需要在執行階段為建置在主機上配置額外的暫存記憶體。

離線 BVH 建置器只會耗用部分 GPU 畫面預算。在執行階段，請使用新的 [D3D12\_RAYTRACING\_ACCELERATION\_STRUCTURE\_COPY\_MODE\_DESERIALIZE](/zh-TW/reference/graphics/d3d12/enums/d3d12_raytracing_acceleration_structure_copy_mode_public) 旗標呼叫 [CopyRaytracingAccelerationStructure](/zh-TW/reference/graphics/d3d12/interfaces/id3d12graphicscommandlist4/methods/id3d12graphicscommandlist4_copyraytracingaccelerationstructure_public)。還原序列化 (僅是 [memcpy](https://learn.microsoft.com/cpp/c-runtime-library/reference/memcpy-wmemcpy)) 會在 GPU 時間軸上進行，比實際建置快得多。未來，如果您發現此成本過高，可以新增 CPU 還原序列化程序，其中包括移除部分標頭並進行一些變更。如果您需要此功能，請告訴我們。

由於三角形分割，離線 BVH 建置器產生的 BVH 品質高於執行階段 BVH 建置器。BVH 經常包含形狀不規則且角度特殊的三角形。我們可以在部分三角形周圍新增額外的 AABB 來提升效能。這可降低表面積啟發式以獲得更快的周遊，但會增加記憶體耗用量。在決定要多積極地套用此最佳化時，請將這一點納入考量。

**圖 5.  投影片 26。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S26.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=ec8ebb4b43e8e5c2f2b048b4353f0515" alt="投影片 26" width="1155" height="651" data-path="images/gdk/features/graphics/GR09-S26.png" />

為了說明三角形分割是什麼以及其運作方式，圖 5 左側的三角形標示為一般三角形。如果光線穿過紅色虛線方塊，該光線大約有 50% 的機率會命中三角形。相反地，在圖 5 右側，有另一個三角形佔用相同的 AABB。不過，光線命中此三角形的機率大約只有 5%。

**圖 6.  投影片 27。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S27.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=a3223127bddd5816c97cd9c30347c10d" alt="投影片 27" width="1157" height="649" data-path="images/gdk/features/graphics/GR09-S27.png" />

在圖 6 中間，我們進行了\_一次分割\_。三角形不是以單一 AABB 為邊界，而是以兩個 AABB 為邊界，且不對三角形幾何做任何變更。如果光線穿過同一個紅色虛線方塊，大約有 40% 的機率會在不受任何三角形測試阻礙的情況下穿過。可以再次分割三角形來改善此情況，最多可進行兩次分割，以三個方塊作為三角形的邊界。新增的方塊越多，光線穿過紅色虛線方塊時，不需要將該三角形視為候選項目的機率就越高。

**圖 7.  投影片 28。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S28.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=92a5f78ed81cf15656c00f4f72177fa4" alt="投影片 28" width="1159" height="651" data-path="images/gdk/features/graphics/GR09-S28.png" />

如果分割越多越好，那麼可以進行無限次分割，以無限多個 AABB 近似此三角形的形狀。最終，圖 7 中三角形的表面積會接近三角形本身的表面積，不會被包含它的 AABB 人為膨脹。

雖然分割越多越好，但 AABB 會使用記憶體，而且耗用量會大幅增加。光線/AABB 測試也有其成本。如果有無限多個方塊作為每個三角形的邊界，您就需要進行無限次光線/AABB 測試。然而，硬體只能進行有限次數的此類測試。Intel Embree 套用此最佳化時，只會在必要時進行分割。如果遇到一般三角形，它不會進行分割，因為沒有必要。Intel Embree 會判斷位於離軸位置的細長三角形是否適合進行三次、四次、五次或更多次分割。您可以使用 [TriangleSplitFactor](/zh-TW/reference/graphics/d3d12_xs/structs/d3d12xbox_build_raytracing_acceleration_structure_params2) 來控制三角形分割的次數以及所使用的額外記憶體量。

XBOX Series X|S 的 BVH 大約是每個三角形 120 到 140 位元組。離線 BVH 和壓縮後的執行階段建置 BVH 都是如此。將三角形分割係數提高到較高的值，會讓 BVH 的大小再增加 10% 到 20%。遺憾的是，這兩個數字都比 PC 上的 NVIDIA BVH 大三倍。不過，在這一代主機上對此無能為力，因為 XBOX Series X|S 硬體是固定平台，具有交集指令所需的固定記憶體層。

如果您有一款大型遊戲，在開放世界中有十億個唯一三角形，您可能會有大約 140 GB 的離線 BVH。傳統壓縮或許能減少一半，但若要發行遊戲，您仍需要 70 GB，也就是一整張額外的 Blu-ray 光碟 (BD)。若要解決此壓縮問題，您可以使用 *BVH 壓縮*。

<a id="bvh-compression" />

## BVH 壓縮

開發人員要求我們檢討 BVH 的大小。我們在 2022 年 3 月 GDK 中提供了壓縮解決方案。\_BVH 壓縮\_可讓光碟上的 BVH 大小減少為四分之一到六分之一。您想要在開放世界遊戲中發行的那十億個三角形，現在只需要 25 GB，而不是 140 GB。在 GPU 能夠存取三角形之前，必須先將壓縮的 BVH 解壓縮。這是需要 CPU 參與的程序。BVH 壓縮不會在執行階段節省主機上的記憶體，而是讓您能夠以較小的安裝大小發行較小的遊戲。

在建置離線 BVH 之後，會在 Windows PC 上的建置電腦上離線執行以 CPU 為基礎的壓縮步驟。在執行階段，會在主機上執行以 CPU 為基礎的解壓縮步驟，使其可供 GPU 使用。如果您在 Windows PC 上使用 XBOX Series X|S PC 驅動程式，`CopyRaytracingAccelerationStructure` API 已新增 [D3D12XBOX\_RAYTRACING\_ACCELERATION\_STRUCTURE\_COPY\_MODE\_SERIALIZE\_AND\_COMPRESS](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-compression) 旗標，可在單一步驟中要求序列化與壓縮。若要在主機上於執行階段進行解壓縮，請使用 XG 程式庫和新的 [XGBVHComputer::DecompressBVH](/zh-TW/reference/graphics/xg_xs/interfaces/XGBVHComputer/methods/xgbvhcomputer_decompressbvh_xs) 函式。您可能已經在紋理方面使用此程式庫。

目前，執行階段解壓縮僅限 CPU，而且是單一執行緒，因為開發人員通常不希望我們自行進行多執行緒處理。假設平均壓縮比為 5:1，每秒從 SSD 讀取 250 到 360 MB 的輸入，會產生每秒 1.2 到 1.8 GB 的輸出。由於 SSD 每秒最多可讀取 2 GB 的資料，單一執行緒無法達到所需的解壓縮速率。如果在 CPU 上解壓縮 BVH 成為載入的瓶頸，請考慮使用更多執行緒。您可以輕鬆地同時在 1、2、3 或 4 個執行緒上解壓縮 BVH，以加快載入時間。

<a id="dxr-10--extensions" />

## DXR 1.0 + 擴充功能

在 XBOX Series X|S 上，支援與 PC 相容的 DXR 1.0 (DirectX Raytracing)，與數年前發行時相同。唯一重大的遺漏是可呼叫著色器 API。開發人員對此 API 的要求很少。DXR 1.0 通常由已在 Windows PC 上建置光線追蹤遊戲的開發人員使用，在 PC 上光線追蹤已能運作，現在他們也希望它能在 XBOX Series X|S 上運作。雖然 XBOX Series X|S 推出時並非如此，但許多開發人員回饋表示此選項直接就能運作。他們按下 F7，再按下 F5，遊戲就執行了，而且有光線追蹤。

雖然在 XBOX Series 主機上執行 DXR 1.0 遊戲是可行的 (而且已經可行一段時間)，但這並不是達到最佳效能的途徑。如果您想在遊戲中發行 DXR 1.0，可能需要花費額外時間嘗試針對 XBOX Series X|S 進行最佳化。圖 8 所示的擴充功能可讓這項工作更容易。

**圖 8.  投影片 39。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S39.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=9dfc7798de6022b42d3fc31128dde257" alt="投影片 39" width="1157" height="642" data-path="images/gdk/features/graphics/GR09-S39.png" />

這些擴充功能分為數個類別。

若要在 [TraceRay](https://learn.microsoft.com/windows/win32/direct3d12/traceray-function) 完成後查詢光線長度，請使用：

* [XDXR\_RayTCurrent()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_RayTMin()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)

若要針對已認可或擱置中的交集，傳回所命中三角形的頂點位置，請使用：

* [XDXR\_GetHitTriangleVertexPositions()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_GetCommittedHitTriangleVertexPositions()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_GetPendingHitTriangleVertexPositions()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)

若要取得光線所命中的執行個體/葉節點指標，請使用：

* [XDXR\_GetPendingBlasLeafNodePtr()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_GetPendingInstanceNodePtr()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_GetCommittedBlasLeafNodePtr()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)
* [XDXR\_GetCommittedInstanceNodePtr()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)

若要立即在三角形/執行個體上叫用最接近命中著色器，請使用：

* [XDXR\_SetShortCircuitIntersectNodes()](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr)

在 XBOX 上的 DXR 1.0 中，`TraceRay` 呼叫完成後會回報各種資訊。您不需要使用未命中著色器或最接近命中著色器，將該資訊放回光線承載中。對於陰影或環境光遮蔽之類的效果，您需要知道是否有命中。您不需要知道漫射資訊或重心座標，只需要一個二元的是或否。不需要為了得出原本只需一個位元的結果，而執行未命中著色器或最接近命中著色器並使用 4 位元組的承載。其中兩個擴充功能可以在 `TraceRay` 之後呼叫。您可以取得光線的最終長度，並與原始長度比較，以查看是否有命中。您也可以讀取已認可命中的三個頂點位置。這些頂點位置會直接從 BVH 傳回，而不需要將包含位置的頂點緩衝區繫結至 DispatchRays 呼叫，再從您自己的資料結構讀取。這可以節省記憶體，您可以捨棄頂點緩衝區的複本。

**圖 9.  投影片 41。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S41.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=055de27a76db01b5ad71e14963f981c6" alt="投影片 41" width="1158" height="651" data-path="images/gdk/features/graphics/GR09-S41.png" />

圖 9 中的程式碼範例示範 `XDXR_RayTCurrent` 和 `XDXR_GetCommittedHitTriangleVertexPositions` 擴充功能的使用方式。首先將 [maxT](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-xdxr) 初始化為光線的最大長度，然後呼叫 `TraceRay`。在 `TraceRay` 呼叫完成並返回光線產生著色器後，比較 `XDXR_RayTCurrent`。如果其值小於原本設定的值，就表示有命中。如果有命中，而您想知道那些頂點位置，請呼叫 `XDXR_GetCommittedHitTriangleVertexPositions`。您會直接從 BVH 記憶體取得三個頂點位置。

<a id="inline-raytracing" />

## 內嵌光線追蹤

雖然有些遊戲仍使用 DXR 1.0，但我們建議開發人員使用 DXR 1.1 和內嵌光線追蹤。DXR 1.1 存在於 PC 上，並引入了稱為 [RayQuery](https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#rayquery) 的內嵌光線追蹤版本。這可讓您從傳統著色器階段 (例如計算著色器或像素著色器) 追蹤光線。`RayQuery` 無法呼叫其他著色器。例如，您無法透過呼叫命中著色器來處理 Alpha 測試的透明度。所有工作都必須在該著色器中完成，無法使用函式呼叫。XBOX 不支援 DXR 1.1 `RayQuery` API。不過，還有另一個選項。

DXR 1.0 在主機上仍是黑箱，與在 PC 上相同。執行階段 BVH 建置器並未提供原始程式碼，而周遊程式碼則隱藏在驅動程式中的 DispatchRays 呼叫之後。光線周遊程式碼已使用 HLSL ([高階著色器語言](https://learn.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl)) 實作。您可以檢視該程式碼，並直接將其包含在您自己的著色器中。周遊程式碼以 HLSL 形式隨附於 GDK 的標頭檔中。您可以在著色器中 `hash #include` 它，並依需要使用。

您可以使用 GDK 安裝目錄中所包含的 [XDXRStandaloneTraverseShortStack.hlsli](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-standalone) 檔案呼叫 `hash #include`。它可用於任何可以配置 LDS 或群組共用記憶體的著色器階段。目前包括計算著色器和像素著色器。由於已提供原始程式碼，您可以修改著色器。如果有您不需要的功能 (或您正為其付出成本)，而您想要移除它，請刪除該程式碼。

如果您想要在著色器中新增程式碼以自訂您的遊戲，請直接將該程式碼新增至標頭，並繼續包含它。您的著色器沒有必須與驅動程式中任何內容相符的二進位需求，它也沒有任何形式的版本控制。它就是讓您包含在著色器中使用的。

**重要**：我們保留在任何 GDK 更新中隨時變更 BVH 格式的權利。這些著色器可能會在不同 GDK 版本之間變更。如果您進行了修改，請準備好在每次 GDK 更新時合併您的自訂變更。

**圖 10.  投影片 46。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S46.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=9cfdf36f94b1d1cf2f957d681306638a" alt="投影片 46" width="1159" height="648" data-path="images/gdk/features/graphics/GR09-S46.png" />

圖 10 中獨立標頭的介面與 DXR 1.1 `RayQuery` 類似。它稱為 [XboxRayQuery](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-standalone)，接受許多相同的旗標和許多相同的輸入。事實上，它看起來很相似，這也是我們沒有在 DXR 1.1 上投入時間的原因。

如果您使用內嵌光線追蹤方法，可能會想要處理 Alpha 測試。這可以透過下列兩種方式之一完成。

* 每次找到非不透明命中時，[Proceed](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-standalone) 函式都會返回，並詢問是否要認可該命中。您可以使用候選內建函式取得重心座標的相關資訊，進行紋理查詢，然後檢查 Alpha 通道，以判斷是否要接受該命中。
* 將您的 Alpha 測試命中函式直接插入周遊迴圈中。效能上的好處是，您不需要跳出周遊迴圈來執行程式碼，然後再從頂端重新進入周遊迴圈。在周遊迴圈內執行您的測試函式，可節省向量一般用途暫存器 (VGPR)、提高佔用率，並執行較少的指令。基於這些好處，我們建議您使用此選項。

與 DXR 1.0 相比，內嵌光線追蹤方法有數項好處。由於編譯器可以看到整個著色器 (包括周遊)，因此可以消除與您的遊戲無關的未使用周遊程式碼，例如 AABB 程序性基本型別的處理。VGPR 需求通常比 DXR 1.0 低約 10 個 VGPR。這可提供更好的佔用率和更佳的效能。它可以根據您遊戲的需求進行自訂，因此是比 DXR 1.0 更好的選項。

內嵌光線追蹤也有缺點，而且有些缺點比其他缺點更嚴重。如果您需要處理大量的材質變化，可能很難在單一著色器中完成。您或許可以使用 `switch` 陳述式或 `if` 陳述式處理一兩種材質。然而，當您需要呼叫 1,000 個不同的函式來處理 1,000 個不同的最接近命中著色器，或是處理不同材質的程式碼時，著色器的樣貌與編譯方式都會承受相當大的負擔。

PIX 無法辨識您正在進行光線追蹤。對它來說，這只是另一個呼叫標頭檔中所提供程式碼的計算著色器。由於它不會被辨識為光線追蹤，因此對其進行效能分析與偵錯相當棘手。此外，如果您已有正在執行的 DXR 1.0 實作，要讓此方法運作，需要在原本已可運作的解決方案之外進行額外的步驟。

<a id="occupancy" />

## 佔用率

佔用率對於在光線追蹤中取得良好效能非常重要。

低佔用率是最常見的遊戲效能問題。開發人員已實作光線追蹤，但效能不佳。遊戲中經常有使用超過 160 個 VGPR 的光線追蹤管線狀態物件 (RTPSO)。以 Wave32 執行時，這只有六個 Wave 的佔用率。如果以 Wave64 執行光線追蹤，佔用率將只有三。這實在太低了。最佳做法是讓遊戲達到高佔用率，同時執行 12 個以上的 Wave32。

**圖 11.  投影片 52。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S52.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=3a2202ee9c1c9432db70c62dcb351f9a" alt="投影片 52" width="1155" height="647" data-path="images/gdk/features/graphics/GR09-S52.png" />

圖 11 顯示一個簡化的周遊迴圈。這是一個 `while` 迴圈，意思是「當 BVH 中仍有區域尚待探索時，就進行光線交集測試」。圖 11 顯示 [\_XB\_BvhIntersectRay](/zh-TW/tools/tools-console/shadercompiler/dxc-xbox-intrinsics) 內建函式。此時 Wave 已無其他工作可做，它正在等待「這條光線命中了什麼，命中距離是多少？」的答案，因而停滯。GPU 必須排程另一個 Wave 來取代此 Wave，這一點至關重要。如果佔用率為一，在等待此 Wave 的交集要求返回時，除了讓整個 SIMD 停滯之外別無選擇。佔用率越高，GPU 排程新 Wave 的選擇就越多。這就是為什麼同時執行 12、13、14、15 或 16 個 Wave 非常重要。

由於我們的周遊程式碼每個 Wave32 會使用 2 KB 的 LDS 或群組共用記憶體，因此佔用率無法超過 16。即使硬體可以達到佔用率 20，這仍是上限。由於著色器使用的 LDS 量，您無法達到該值。佔用率 16 無法超越，因此嘗試將 VGPR 數量降到 64 以下沒有任何價值。

啟動 RTPSO 時，需要配置與整個 RTPSO 中成本最高的著色器一樣多的 VGPR。由於無法得知您正在呼叫哪些著色器，因此會假設任何著色器都可能被呼叫。因此，您必須依照這些著色器中的最高層級來配置 VGPR。

任何命中著色器會在周遊所使用的 VGPR 之外，額外使用自己的 VGPR。不要在每次呼叫任何命中著色器時，將 VGPR 儲存至記憶體再還原。讓任何命中著色器中的 VGPR 數量保持在低水準非常重要。最接近命中著色器通常是 VGPR 需求最高的著色器。這些著色器近似於一般點陣化階段中的像素著色器。它們通常會評估材質、評估光源、BRDF 等，因此在所有 VGPR 數量中最高。檢視整個 RTPSO 的 VGPR 數量時，請注意這一點。

我們建議您針對每種用途建立一個 RTPSO。例如，這表示要有陰影 RTPSO、環境光遮蔽 RTPSO 或反射 RTPSO。

舉例來說，陰影的 VGPR 需求通常低於反射。在光線追蹤中進行陰影轉譯時，陰影可以獲得比反射更高的佔用率。如果您為反射和陰影建立單一 RTPSO，其上限將取決於反射的 VGPR 需求。陰影 RTPSO 則可以以更高的佔用率和更好的效能執行。

讓任何命中著色器盡可能保持簡單至關重要。它們會與周遊一起內嵌呼叫。每當單一光線評估任何命中著色器時，都會延遲所有其他不需要執行任何命中著色器的執行緒。建議您讓著色器盡可能精簡。不要嘗試在其中評估光源並將其儲存在承載中。只做最少量的工作：決定是否要接受命中，然後返回周遊。

DXR 1.0 會在建立裝置時配置 32 MB 的堆疊，以支援儲存、還原暫存器以及遞迴。2019 年的建議是不要使用遞迴，這點至今仍然適用。這是一個很難擺脫的效能問題。

對於 32 MB 的堆疊配置，「*堆疊*」一詞有點被過度使用。實際上有兩個堆疊。一個是每個 Wave 在 LDS 中配置的堆疊，用於追蹤其在 BVH 中的路徑以及應返回的節點。另一個是存在於全域記憶體中的堆疊，用於儲存和還原暫存器。

對於第二種堆疊，如果單一 Wave 有大量暫存器需要溢出，而必須將大量暫存器寫入記憶體，32 MB 可能很快就會用完。在極端情況下，此 32 MB 堆疊可能會成為佔用率的限制。截至 2022 年 3 月 GDK，XBOX Series X 和 XBOX Series S 主機上都會配置 32 MB。在 2022 年 6 月 GDK 中，XBOX Series S 配置的堆疊小得多，因為它的工作群組處理器比 XBOX Series X 少。如果您不使用此堆疊，可以在建立裝置時停用它。例如，如果您完全使用 DXR 1.1 和內嵌光線追蹤途徑，就不會為任何目的溢出暫存器。

<a id="offline-rtpso" />

## 離線 RTPSO

XBOX 一律可以將著色器編譯為 DXBC 或 DirectX 中繼語言 (DXIL)，就像在 Windows PC 上一樣。但作為固定平台，XBOX 也可以將著色器一路預先編譯成 AMD 微碼，無需進一步編譯即可直接執行。如果您提供根簽章，處理頂點著色器、像素著色器和計算著色器並不困難。計算著色器、頂點著色器和像素著色器是獨立編譯且自成一體的程式碼片段。它們不會對其他程式碼進行函式呼叫，進行呼叫時也沒有需要處理的 ABI。它們很容易編譯成微碼。

遺憾的是，光線追蹤著色器複雜得多。它們對編譯器看不到的程式碼有外部相依性。周遊程式碼存在於驅動程式中，但不存在於編譯器中。編譯光線追蹤著色器時，無法將整個著色器編譯成 AMD 微碼，只能編譯到 DXIL 為止。

編譯 DXR 著色器時，請使用目標 lib\_6\_3 (程式庫著色器模型 6.3)。這些著色器會編譯成 DXIL，運作方式與在 PC 上相同。只有在執行階段呼叫 [CreateStateObject](/zh-TW/reference/graphics/d3d12/interfaces/id3d12device5/methods/id3d12device5_createstateobject_public) 時，才會產生 AMD 微碼。在某些情況下，包含數百或數千個著色器的 RTPSO 可能需要數秒而非數毫秒。數秒的 `CreateStateObject` 呼叫是可預期的。兩秒的編譯時間或許可以隱藏在載入畫面後面。如果您的開放世界遊戲中玩家會高速移動，而您無法將繪製物件延遲兩秒來編譯新的 RTPSO，這就會成為問題。由於 XBOX 目前不支援 DXR 1.1，將著色器新增至 RTPSO 的 `AddToStateObject` API 也幫不上忙。

您可以改為離線完整預先編譯 RTPSO。這比呼叫 DXC 更複雜。使用 XBOX Series X|S PC 驅動程式 (與使用離線 BVH 建置器時所用的驅動程式相同)，將 RTPSO 一路編譯成 AMD 微碼。呼叫 `CreateStateObject`，這與在主機上於執行階段呼叫的 API 相同。使用 [SerializeStateObjectX](/zh-TW/reference/graphics/d3d12_xs/interfaces/ID3D12Device8/methods/id3d12device8_serializestateobjectx) API 將 RTPSO 序列化至 SSD。寫入 SSD 時，此 Blob 的大小只有個位數 MB，視您擁有的著色器數量而定。您可以在執行階段從 SSD 載入該區塊，並使用 [DeserializeStateObjectX](/zh-TW/reference/graphics/d3d12_xs/interfaces/ID3D12Device8/methods/id3d12device8_deserializestateobjectx) API 取得已預先編譯、可載入的 RTPSO，而不需要編譯步驟。

這些 DXIL 程式庫可以透過兩種有細微差異的方式編譯成 RTPSO。

第一個選項是完全自成一體的 RTPSO。這是已可繫結至管線並在 DispatchRays 呼叫中使用的 RTPSO。

第二個選項 (我們稱之為 RTPSO) 也是一個集合。它是一組著色器，具有共同用途，或與特定物件或關卡有共同關聯。這些著色器可以編譯為單一 Blob 或單一實體，然後在執行階段於多個 RTPSO 之間共用。使用此選項，您可以在執行階段從多個預先編譯的離線集合建置 RTPSO。這些預先編譯的集合會連結至驅動程式，而不是在執行階段編譯成 AMD 微碼。此程序通常需要大約 10 毫秒。此離線預先編譯步驟會移除所有 DXIL 和中繼資料，以縮小大小。如果您正在進行執行階段子物件關聯 (這是 DXR API 的功能)，則無法使用此選項。

使用第二個選項時，您會從 RTPSO 取得著色器識別碼。著色器繫結資料表中每筆記錄的開頭都需要這些識別碼。這一點以及 BVH 壓縮，都示範於 [OfflineRT ATG 範例](https://github.com/microsoft/Xbox-ATG-Samples)中。

<a id="pix" />

## PIX

PIX 在 DXR 支援方面投入了大量心力。加速結構檢視器以及管線檢視中的資源顯示也都有所改進。目前有兩個仍待加強、但正積極投入大量工作的領域：目前尚未支援的光線追蹤著色器 PDB，以及在 DispatchRays 呼叫中偵錯光線或偵錯執行緒的功能。如果您對改進 PIX、DXR 支援有任何建議，或有其他意見反應，請選取 PIX 右上角的 **Feedback** 按鈕，並針對 DXR 支援或您希望我們知道的其他領域提供任何意見反應。

**圖 12.  投影片 65。**

<img src="https://mintlify.s3.us-west-1.amazonaws.com/microsoft-4404708b/images/gdk/features/graphics/GR09-S65.png" alt="投影片 65" />

下列影像顯示加速結構檢視器的外觀。

圖 12 顯示一個分派呼叫。在左側選取加速結構，即可取得可飛行的相機，以環繞方式檢視加速結構的世界視圖。您可以看到組成整個 TLAS 的個別三角形、個別執行個體和 BLAS。

**圖 13.  投影片 66。**

<img src="https://mintlify.s3.us-west-1.amazonaws.com/microsoft-4404708b/images/gdk/features/graphics/GR09-S66.png" alt="投影片 66" />

圖 13 顯示熱度圖。您可以使用它來查看場景中的效能熱點位置。這會將內嵌光線追蹤著色器變成與 PC 相容。您的主機電腦現在會在 PIX 內執行周遊程式碼。由於這是經過檢測的版本，因此可以擷取該光線在周遊迴圈中需要多少次反覆運算的相關資訊，並以色彩形式在螢幕上視覺化呈現。

**圖 14.  投影片 67。**

<img src="https://mintlify.s3.us-west-1.amazonaws.com/microsoft-4404708b/images/gdk/features/graphics/GR09-S67.png" alt="投影片 67" />

圖 14 示範物件 (例如場景前方這個醒目提示的垃圾桶) 是可以選取的。您可以確認它並未與地面融合。如果融合了，就會產生很大的執行個體邊界。選取物件並查看它們在場景中的位置非常重要。

**圖 15.  投影片 68。**

<img src="https://mintlify.s3.us-west-1.amazonaws.com/microsoft-4404708b/images/gdk/features/graphics/GR09-S68.png" alt="投影片 68" />

在圖 15 中，選取了一棵樹。加速結構檢視器也會顯示這棵樹的所有其他複本。此圖中大約有 10 棵樹的複本。選取一棵樹時，其他九棵也會醒目提示。這顯示使用了執行個體化，而不是為這些樹使用 10 個不同的 BLAS。

**圖 16.  投影片 69。**

<img src="https://mintcdn.com/microsoft-4404708b/EHFikhsC0GyEu9Ca/images/gdk/features/graphics/GR09-S69.png?fit=max&auto=format&n=EHFikhsC0GyEu9Ca&q=85&s=29500e70a21109920ea2202ec564c856" alt="投影片 69" width="1159" height="653" data-path="images/gdk/features/graphics/GR09-S69.png" />

圖 16 顯示最近新增的功能，可直接在加速結構檢視器中將光線視覺化。由於這是周遊的檢測版本，您可以取出光線原點、光線方向和光線範圍，並以線框線條直接繪製到場景中。

在圖 16 中，螢幕左側的一條光線似乎穿透建築物並從另一側穿出。起初，這看起來像是 PIX 中的錯誤。實際上，該建築物有一道細微的裂縫。一條光線穿過建築物，然後從背面穿出，而背面剔除已停用。希望這類視覺化功能能在您調查效能問題時對您有所幫助。

<a id="summary" />

## 摘要

總結來說：

* XBOX Series X|S 主機上可以使用光線追蹤。
* 您必須密切注意效能。
* 在建置美術資產時就要將其納入考量。這包括您撰寫的著色器、您使用的建置旗標、您是否使用 XBOX 特定的 API，或是否使用非同步計算。
* 記憶體可能是重要的考量。特別是在 XBOX Series S 主機上，您的 BLAS 或 TLAS 需要大約 500 MB 的記憶體。

在為遊戲開發光線追蹤時，所有這些領域都需要及早考量。

PIX 小組正努力改進 PIX。我們希望讓 PIX 的功能足以讓您自行處理所有 GPU 光線追蹤、偵錯和效能問題，而不需要先聯絡 ATG 尋求特定協助。

<a id="next-steps" />

## 後續步驟

如果您想要檢閱與本概觀相關的簡報資料，請從 [XBOX Developer Download Secure Data Storage (SDS)](https://www.microsoft.com/en-us/software-download/gdk) 下載下列檔案。

* 投影片：Xfest 2022 Graphics Track PowerPoints (Xfest2022GfxPPTs.ZIP) 中的 GR09\_Best Practices for Raytracing on XBOX Series X|S.pptx
* 影片簡報：Xfest 2022 Graphics Track Videos (Xfest2022GfxVids.ZIP) 中的 GR09.mp4

### 下載 Microsoft PowerPoint 簡報與影片

1. 前往 [Game Development Kit (GDK) 下載](https://www.microsoft.com/en-us/software-download/gdk)。
2. 在 <b>Select file type</b> 下，選取 **Conference Materials**，然後選取 **Confirm**。
3. 在 <b>Select build/version number</b> 下，選擇下列其中一個圖形簡報。
   * Xfest 2022 Graphics Track PowerPoints
   * Xfest 2022 Graphics Track Videos
4. 選取 <b>Download Now</b>，然後等待 .zip 檔案下載完成。
5. 前往您的本機 Downloads 資料夾，然後從壓縮資料夾中解壓縮 (擷取) 檔案。

<a id="see-also" />

## 另請參閱

[光線追蹤簡介](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-overview)


## Related topics

- [NDA 主題目錄 - Microsoft Learn 線上連結](/zh-TW/nda/nda-topic-directory.md)
- [RTA 服务的最佳做法](/zh-CN/services/xbox-services/fundamentals/rta/concepts/live-rta-best-practices.md)
- [PlayFab 消费最佳做法](/zh-CN/services/playfab/pricing/consumption-best-practices.md)
- [GDK 範例](/zh-TW/home/setup-install/samples.md)
- [XR-115 在游戏过程中添加和移除用户或控制器](/zh-CN/publishing/certification/xr/xr-115.md)
