> ## 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 主機上的每個工作群組處理器 (WGP) 都直接內建強大的固定功能硬體，設計用來加速透過週框體積階層 (BVH) 加速結構執行光線周遊的程序。

每個紋理資料區塊 (TD) 每個時脈可以執行四次光線/軸對齊週框方塊 (AABB) 交集測試，或每個時脈執行一次光線/三角形交集測試。XBOX Series 主機的 TD 區塊數量為 20 個 (XBOX Series S) 和 56 個 (XBOX Series X)。這對應到下列表格中所示的交集測試「峰值」速率。

| 主機 | 光線/AABB 交集測試峰值速率 |
| - | - |
| XBOX Series S | 1563 MHz × 10 個 WGP × 每個 WGP 2 個 TD × 每次查詢 4 個 AABB = *每秒 1250 億次光線/AABB 測試* |
| XBOX Series X | 1825MHz × 26 個 WGP × 每個 WGP 2 個 TD × 每次查詢 4 個 AABB = *每秒 3796 億次光線/AABB 測試* |

| 主機 | 光線/三角形交集測試峰值速率 |
| - | - |
| XBOX Series S | 1563 MHz × 10 個 WGP × 每個 WGP 2 個 TD × 每次查詢 1 個三角形 = *每秒 312.6 億次光線/三角形測試* |
| XBOX Series X | 1825 MHz × 26 個 WGP × 每個 WGP 2 個 TD × 每次查詢 1 個三角形 = *每秒 949 億次光線/三角形測試* |

存取 TD 光線追蹤功能的方式，與目前執行紋理取樣和篩選的方式非常相似。

GPU 的指令集中新增了兩個新指令。

1. image\_bvh\_intersect\_ray
2. image\_bvh64\_intersect\_ray

這兩個指令的差異只在於作為輸入的位址寬度：image\_bvh\_intersect\_ray 為 32 位元，image\_bvh64\_intersect\_ray 為 64 位元。32 位元版本的指令可定址最大 32 GB 的 BVH，因此在大多數情況下，不太可能需要使用「bvh64」版本。

image\_bvh\_intersect\_ray 指令的輸入如下：image\_bvh\_intersect\_ray vgpr\_output\[4]、vgpr\_input\[11] 和 sgpr\_resource\[4]。

作為輸入的 11 個向量一般用途暫存器 (VGPR) 如下表所示。

\| VGPR 索引 | 資料 | 描述 | |---|---| | 0 | node\_pointer (u32) | 位元 2:0 指定所要求的光線交集測試類型 (請參閱下文)。位元 31:3 是 29 位元的位址，以 64 位元組對齊；例如，相對於 BVH 基底位址，0 = 0x0、1 = 0x40、2 = 0x80。 | | 1 | ray\_extent (f32) | 允許發生命中的最大距離 (通常稱為「t」)。距離大於 ray\_extent 的任何潛在交集都不會視為命中，而是傳回「未命中」。 | | 2 | ray\_origin.x (f32) | 光線起始位置的 x 座標。 | | 3 | ray\_origin.y (f32) | 光線起始位置的 y 座標。 | | 4 | ray\_origin.z (f32) | 光線起始位置的 z 座標。 | | 5 | ray\_direction.x (f32) | 光線方向的 x 分量。 | | 6 | ray\_direction.y (f32) | 光線方向的 y 分量。 | | 7 | ray\_direction.z (f32) | 光線方向的 z 分量。 | | 8 | ray\_inverse\_direction.x (f32) | 光線方向 x 分量的倒數。如果該軸的方向分量為 0.0f，則無限大是有效值。 | | 9 | ray\_inverse\_direction.y (f32) | 光線方向 y 分量的倒數。如果該軸的方向分量為 0.0f，則無限大是有效值。 | | 10 | ray\_inverse\_direction.z (f32) | 光線方向 z 分量的倒數。如果該軸的方向分量為 0.0f，則無限大是有效值。 |

由於 node\_pointer 中的 29 位元位址實際上是以 64 位元組的倍數表示，因此 32 位元版本的 image\_bvh\_intersect\_ray 可以定址最大 32 GB 的 BVH。

另外也提供替代的「A16」編碼，其中 ray\_direction 和 ray\_inverse\_direction 會編碼為 float16。只要將 ray\_direction 和 ray\_inverse\_direction 以 float16\_t3 傳遞給 image\_bvh\_intersect\_ray 或 image\_bvh64\_intersect\_ray 內建函式，即可使用此編碼。在我們的周遊實作中，我們並未發現這能改善效能。

四個輸出 VGPR 的用途如下文所述，並會因所查詢的節點類型而異。

### BVH 描述元

BVH 紋理描述元為 128 位元，其配置如下表所示。

\| 欄位 | 位元 | 大小 | 資料 | |---|---| | BVH 基底位址 | 39:0 | 40 | BVH 的基底位址：以 256 位元組對齊。例如，0 = 0x0、1 = 0x100、2 = 0x200。 | | 未使用 | 54:40 | 15 | 必須為零。 | | 方塊擴大量 | 62:55 | 8 | 在光線-方塊測試期間要加入的 ULP 數量，以不帶正負號的整數編碼。 | | 已啟用方塊排序 | 63 | 1 | 光線/AABB 測試結果是否需要排序。 | | 大小 | 105:64 | 42 | BVH 中的 BVH 節點數量減 1。在存取時強制執行界限檢查。 | | 未使用 | 119:106 | 17 | 必須為零。 | | 三角形傳回模式 | 120 | 1 | 0：三角形傳回模式 0。1：三角形傳回模式 1。詳細資訊請見後面章節。 | | 未使用 | 122:121 | 2 | 必須為零。 | | 大型頁面 | 123 | 1 | 表示所有使用的記憶體頁面都小於或等於 64 KB。由於 XBOX 驅動程式不支援小於 64 KB 的頁面大小供 GPU 存取，因此此值必須一律為 1。 | | 類型 | 127:124 | 4 | 必須設定為 0x8。 |

## BVH 節點類型

先前所述的光線交集指令不會透過 VGPR 接受幾何 (AABB 或三角形) 作為輸入。而是由 32 位元位址 (「node\_pointer」) 指定要針對 BVH 中的哪個節點執行交集測試。此方法的好處是，TD 可以將記憶體作業和交集測試融合成一項作業。由於最大的節點大小為 128 位元組，替代方法將必須載入、儲存和傳輸額外 32 個 VGPR 的「幾何」承載資料，再加上已用於光線資料的 11 個 VGPR。若 image\_bvh\_intersect\_ray 指令需要最多 43 個 VGPR 的輸入，佔用率將會受到嚴重影響。

因此，硬體原生理解三種規定格式的 BVH 節點。

1. FP16 AABB 節點 (儲存 4 個 AABB)：64 位元組
2. FP32 AABB 節點 (儲存 4 個 AABB)：128 位元組
3. 三角形節點 (儲存最多 4 個三角形)：64 位元組

這三種節點類型都必須以 64 位元組對齊。

### 三角形節點格式 (節點類型 0、1、2 和 3)

<Note>
  下列章節與硬體支援相符，不過 XDXR 決定每個分葉節點只使用兩個三角形，並將中繼資料儲存在其餘項目中。\_
</Note>

三角形節點格式儲存五個頂點，這些頂點以隱含方式連接，最多可形成 4 個三角形。V0、V1、V2、V3 和 V4 之間的隱含連接無法設定，如下所示。

1. 三角形 0：{ V0, V1, V2 }
2. 三角形 1：{ V1, V3, V2 }
3. 三角形 2：{ V2, V3, V4 }
4. 三角形 3：{ V2, V4, V0 }

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/rt-trianglenode.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=e7e8db72abe9215d85d31dde74702abe" alt="三角形節點的圖表，顯示五個頂點以隱含方式連接，形成四個三角形。" width="1051" height="912" data-path="images/gdk/features/graphics/rt-trianglenode.png" />

| 位元組 | 資料 |
| - | - |
| 11:0 | V0.xyz (3xfloat32) |
| 23:12 | V1.xyz (3xfloat32) |
| 35:24 | V2.xyz (3xfloat32) |
| 47:36 | V3.xyz (3xfloat32) |
| 59:48 | V4.xyz (3xfloat32) |
| 63:60 | 三角形識別碼 (u32) |

TD 只會針對節點內儲存的四個三角形之一執行光線/三角形交集測試，這與光線/AABB 測試會測試全部四個 AABB 的行為不同。要針對四個三角形中的哪一個進行交集測試，是在叫用 image\_bvh\_intersect\_ray 時由「node\_pointer」的最低 3 個位元指定。這些值如下表所示。

| 值 | 節點類型 |
| - | - |
| 0 | 針對三角形 0 的光線/三角形交集測試 |
| 1 | 針對三角形 1 的光線/三角形交集測試 |
| 2 | 針對三角形 2 的光線/三角形交集測試 |
| 3 | 針對三角形 3 的光線/三角形交集測試 |
| 4 | 針對四個 FP16 AABB 的光線/AABB 交集測試 |
| 5 | 針對四個 FP32 AABB 的光線/AABB 交集測試 |
| 6 | 保留 |
| 7 | 保留 |

#### 交集傳回資料

當 BVH 描述元中的「三角形傳回模式」設定為 0 時，傳回的四個 VGPR 包含下表所示的資料。

| VGPR | 資料 | 描述 |
| - | - | - |
| 0 | t\_num (f32) | 至交集之「t」距離的分子。 |
| 1 | t\_denom (f32) | 至交集之「t」距離的分母。命中距離的計算方式為 t\_num/t\_denom。 |
| 2 | triangle\_id (u32) | 傳回節點中的三角形識別碼 (63:60) 加上所測試三角形的索引 (0-3)。 |
| 3 | hit\_status (u32) | 傳回布林值，表示光線是否命中三角形。0 = 未命中，1 = 命中。 |

當 BVH 描述元中的「三角形傳回模式」設定為 1 時，傳回的四個 VGPR 包含下表所示的資料。

| VGPR | 資料 | 描述 |
| - | - | - |
| 0 | t\_num (f32) | 至交集之「t」距離的分子。 |
| 1 | t\_denom (f32) | 至交集之「t」距離的分母。命中距離的計算方式為 t\_num/t\_denom。 |
| 2 | i\_num (u32) | 重心內插所需之「I」值的分子。必須除以 t\_denom 才能計算實際的「I」值。 |
| 3 | j\_num (u32) | 重心內插所需之「J」值的分子。必須除以 t\_denom 才能計算實際的「J」值。 |

命中狀態可以透過計算 (t\_num/t\_denom) 是否小於 ray\_extent 來推斷。

在三角形傳回模式 1 中，BVH 節點的「triangle\_id」欄位會用來重新對應頂點在三角形節點中儲存的順序與提供給 BVH 建置器的順序。例如，給定下列索引緩衝區，這個四個三角形/五個頂點的序列可以儲存在單一三角形節點中 (其中 0 = V0、1 = V1、2 = V2、3 = V3、4 = V4)。

{ 0, 1, 2 }, { 3, 2, 1 }, { 4, 2, 3 }, { 2, 4, 0 },

不過，第二個和第三個三角形是硬體所定義之隱含順序的旋轉。共同頂點 (V2) 在硬體所定義的三角形 1 (V1,V3,V2) 中是第 3 個頂點，但在輸入索引緩衝區中是第二個指定的。結果是「I」和「J」重心座標必須相對於索引緩衝區中的輸入 {3, 2, 1}，而不是硬體中三角形 1 的隱含順序 {1, 3, 2}。

為了減輕此問題，三角形節點中的位元組 63:60 改為定義 4 組「重新對應」位元，告訴硬體 I 和 J 重心座標應該相對於三角形中 3 個頂點中的哪一個。為此目的對位元組 63:60 的解譯如下表所示。

\| 欄位 | 位元 | 大小 | 資料 | |---|---| | 三角形 0，「I」來源頂點 | 1:0 | 2 | 0：「I」是 *V0* 的重心權重。1：「I」是 *V1* 的重心權重。2：「I」是 *V2* 的重心權重。3：未使用。 | | 三角形 0，「J」來源頂點 | 3:2 | 2 | 0：「J」是 *V0* 的重心權重。1：「J」是 *V1* 的重心權重。2：「J」是 *V2* 的重心權重。3：未使用。 | | 未使用 | 7:4 | 4 | 4 個位元的可用空間。可用於任何用途，不需要任何特定值。 | | 三角形 1，「I」來源頂點 | 9:8 | 2 | 0：「I」是 *V1* 的重心權重。1：「I」是 *V3* 的重心權重。2：「I」是 *V2* 的重心權重。3：未使用。 | | 三角形 1，「J」來源頂點 | 11:10 | 2 | 0：「J」是 *V1* 的重心權重。1：「J」是 *V3* 的重心權重。2：「J」是 *V2* 的重心權重。3：未使用。 | | 未使用 | 15:12 | 4 | 4 個位元的可用空間。可用於任何用途，不需要任何特定值。 | | 三角形 2，「I」來源頂點 | 17:16 | 2 | 0：「I」是 *V2* 的重心權重。1：「I」是 *V3* 的重心權重。2：「I」是 *V4* 的重心權重。3：未使用。 | | 三角形 2，「J」來源頂點 | 19:18 | 2 | 0：「J」是 *V2* 的重心權重。1：「J」是 *V3* 的重心權重。2：「J」是 *V4* 的重心權重。3：未使用。 | | 未使用 | 23:20 | 4 | 4 個位元的可用空間。可用於任何用途，不需要任何特定值。 | | 三角形 3，「I」來源頂點 | 25:24 | 2 | 0：「I」是 *V2* 的重心權重。1：「I」是 *V4* 的重心權重。2：「I」是 *V0* 的重心權重。3：未使用。 | | 三角形 3，「J」來源頂點 | 27:26 | 2 | 0：「J」是 *V2* 的重心權重。1：「J」是 *V4* 的重心權重。2：「J」是 *V0* 的重心權重。3：未使用。 | | 未使用 | 31:28 | 4 | 4 個位元的可用空間。可用於任何用途，不需要任何特定值。 |

由於 triangle\_id 位元用於將重心座標重新對應到所需的頂點，因此 triangle\_id 位元無法再用來儲存基底三角形識別碼。由於後續的著色計算通常需要可用的三角形識別碼 (例如，擷取紋理座標 (UV) 和法線等頂點/基本型別資料)，因此這項資料必須儲存在個別的結構中並手動擷取。

### FP16 AABB 節點格式 (節點類型 4)

| 位元組 | 資料 |
| - | - |
| 3:0 | 子節點指標 0 (u32) |
| 7:4 | 子節點指標 1 (u32) |
| 11:8 | 子節點指標 2 (u32) |
| 15:12 | 子節點指標 3 (u32) |
| 21:16 | 週框方塊 0 - 最小 xyz (3xfloat16) |
| 27:22 | 週框方塊 0 - 最大 xyz (3xfloat16) |
| 33:28 | 週框方塊 1 - 最小 xyz (3xfloat16) |
| 39:34 | 週框方塊 1 - 最大 xyz (3xfloat16) |
| 45:40 | 週框方塊 2 - 最小 xyz (3xfloat16) |
| 51:46 | 週框方塊 2 - 最大 xyz (3xfloat16) |
| 57:52 | 週框方塊 3 - 最小 xyz (3xfloat16) |
| 63:58 | 週框方塊 3 - 最大 xyz (3xfloat16) |

### FP32 AABB 節點格式 (節點類型 5)

| 位元組 | 資料 |
| - | - |
| 3:0 | 子節點指標 0 (u32) |
| 7:4 | 子節點指標 1 (u32) |
| 11:8 | 子節點指標 2 (u32) |
| 15:12 | 子節點指標 3 (u32) |
| 27:16 | 週框方塊 0 - 最小 xyz (3xfloat32) |
| 39:28 | 週框方塊 0 - 最大 xyz (3xfloat32) |
| 51:40 | 週框方塊 1 - 最小 xyz (3xfloat32) |
| 63:52 | 週框方塊 1 - 最大 xyz (3xfloat32) |
| 75:64 | 週框方塊 2 - 最小 xyz (3xfloat32) |
| 87:76 | 週框方塊 2 - 最大 xyz (3xfloat32) |
| 99:88 | 週框方塊 3 - 最小 xyz (3xfloat32) |
| 111:100 | 週框方塊 3 - 最大 xyz (3xfloat32) |
| 127:112 | 16 個位元組的可用空間。可用於任何用途，不需要任何特定值。 |
|  | |

#### FP16 和 FP32 AABB 交集傳回資料

如果 BVH 描述元中的「已啟用方塊排序」設定為 0，下表描述傳回的 4 個 VGPR 及其用途。

| VGPR | 資料 | 描述 |
| - | - | - |
| 0 | 子節點指標 0 (u32) | 如果命中，則傳回子節點指標 0。如果未命中，則傳回 0xFFFFFFFF。 |
| 1 | 子節點指標 1 (u32) | 如果命中，則傳回子節點指標 1。如果未命中，則傳回 0xFFFFFFFF。 |
| 2 | 子節點指標 2 (u32) | 如果命中，則傳回子節點指標 2。如果未命中，則傳回 0xFFFFFFFF。 |
| 3 | 子節點指標 3 (u32) | 如果命中，則傳回子節點指標 3。如果未命中，則傳回 0xFFFFFFFF。 |

如果 BVH 描述元中的「已啟用方塊排序」設定為 1，下表描述傳回的 4 個 VGPR 及其用途。

| VGPR | 資料 | 描述 |
| - | - | - |
| 0 | 命中的最近子節點指標 (u32) | 傳回所命中四個方塊中最近者對應的子節點指標。如果四個方塊全部未命中，則傳回 0xFFFFFFFF。 |
| 1 | 命中的第二近子節點指標 (u32) | 傳回所命中四個方塊中第二近者對應的子節點指標。如果命中的方塊少於或等於一個，則傳回 0xFFFFFFFF。 |
| 2 | 命中的第三近子節點指標 (u32) | 傳回所命中四個方塊中第三近者對應的子節點指標。如果命中的方塊少於或等於兩個，則傳回 0xFFFFFFFF。 |
| 3 | 命中的第四近子節點指標 (u32) | 傳回所命中四個方塊中第四近者對應的子節點指標。如果命中的方塊少於或等於三個，則傳回 0xFFFFFFFF。 |

## 其他資訊

* \_不\_要求 wave 中所有作用中的執行緒都要求相同的節點位址或相同的節點類型進行交集。在同一個指令中，有些執行緒可以要求光線/三角形交集測試，而其他執行緒則執行 FP16 或 FP32 AABB 交集測試。
* TD 內執行的所有作業都使用單精確度浮點數完成。
* 所有光線/AABB 和光線/三角形交集測試都是水密的。
* 非作用中的通道大致上可視為「免費」，不會在 TD 內耗費週期。執行下列動作可讓通道變成非作用中：
  * 使用執行遮罩 (也就是流程控制)
  * 將下列任何分量設定為 NaN：光線方向、光線反向方向、光線原點和光線範圍
  * 將下列任何分量設定為 Inf：光線原點

## 另請參閱

[光線追蹤 (與 DXR) 概觀](/zh-TW/build/core-features/graphics/newfeatures/raytracing/rt-overview)


## Related topics

- [NDA 主題目錄 - Microsoft Learn 線上連結](/zh-TW/nda/nda-topic-directory.md)
- [GDK 範例](/zh-TW/home/setup-install/samples.md)
- [XBOX Accessibility Guidelines (XAG)](/zh-TW/build/game-principles/accessibility/xbox-accessibility-guidelines.md)
- [認證 PC BVT 指南](/zh-TW/publishing/game-publishing/concepts/certification/certification-pc-bvt-guide.md)
- [Direct3D 12 程式設計指南](/zh-TW/build/gdk-and-engines/guides/directx-12-programming-guide.md)
