共用方式為


資源類型

不同類型的資源會具備不同的配置 (或記憶體使用量)。 Direct3D 管線使用的所有資源都源自於兩種基本資源類型:緩衝區紋理。 緩衝區為原始資料 (元素) 的集合,紋理則為紋理像素 (紋理元素) 的集合。

完整指定資源配置 (或記憶體使用量) 的方式共有兩種:

項目 說明

具類型

在建立資源時完整指定類型。

不具類型

在資源繫結至管線時完整指定類型。

 

緩衝區資源

緩衝區資源是一系列完全具類型的資料;緩衝區內部則會包含多個元素。 元素會由 1 到 4 個元件組成。 元素資料類型的範例會包括:已封裝的資料值 (例如 R8G8B8A8)、單一 8 位元整數、四個 32 位元浮點值。 這些資料類型會用來儲存資料,例如位置向量、法向量、頂點向量中的紋理座標、索引緩衝區中的索引,或是裝置狀態。

緩衝區會以非結構化資源的形式建立。 由於緩衝區為非結構化,因此無法包含任何 Mipmap 層級、在讀取時不會進行篩選,而且無法進行多重取樣。

緩衝區類型

頂點緩衝區

緩衝區唯一系列的元素;頂點緩衝區則包含每個頂點的資料。 最簡單的範例,就是包含一種資料類型的頂點緩衝區,例如位置資料。 其視覺化呈現方式會如下圖所示。

包含位置數據的頂點緩衝區圖例

許多時候,頂點緩衝區會包含完整指定 3D 頂點所需的一切資料。 其中一個範例,就是包含每一頂點位置、一般和紋理座標的頂點緩衝區。 通常,這項資料會組織為一組每一頂點項目,如下圖所示。

包含位置、一般和紋理數據的頂點緩衝區圖例

這個頂點緩衝區會針對八個頂點包含每個頂點的資料;每個頂點都會儲存三個元素 (位置座標、法座標和紋理座標)。 通常,位置和一般都會使用三個 32 位元浮點值指定,而紋理座標則會使用兩個 32 位元浮點值指定。

若要存取頂點緩衝區的資料,您需要了解需要存取哪個頂點,以及下方所列的其他緩衝區參數:

  • Offset - 從緩衝區開頭到第一個頂點資料的位元組數。
  • BaseVertexLocation - 從 Offset 到適當繪製呼叫所使用之第一個頂點的位元組數。

建立頂點緩衝區前,您需要建立輸入配置物件,以定義其配置。 建立好輸入配置物件後,請將其繫結至輸入組合語言 (IA) 階段。

索引緩衝區

索引緩衝區包含一組循序的 16 位元或 32 位元索引;每個索引都會用來識別頂點緩衝區中的頂點。 使用索引緩衝區搭配一個或多個頂點緩衝區,藉此將資料提供給 IA 階段,就是所謂的索引編製。 索引緩衝區的視覺化呈現方式會如下圖所示。

索引緩衝區的圖例

儲存在索引緩衝區中的循序索引會具有下列參數:

  • Offset - 從緩衝區開頭到第一個索引的位元組數。
  • StartIndexLocation - 從 Offset 到適當繪製呼叫所使用之第一個頂點的位元組數。
  • IndexCount - 要轉譯的索引數。

索引緩衝區可透過使用寬帶切割索引,將多個線條或三角形寬帶 (原始物件拓撲) 予以結合。 寬帶切割索引可使用單一繪製呼叫來繪製多個線條或三角形寬帶。 寬帶切割索引為索引的最大可能值 (16 位元索引為 0xffff,32 位元索引為 0xffffffff)。 寬帶切割索引會重設已索引原始物件中的捲繞順序,且可用於免除變質三角形的必要性,否則,變質三角形可能需要在三角形寬帶中保持適當的捲繞順序。 下圖顯示了寬帶切割索引的範例。

帶狀切割索引的圖例

常數緩衝區

Direct3D 備有一個緩衝區,會提供名為著色器常數緩衝區的著色器常數,或單純提供常數緩衝區。 就概念上而言,它看起來就像單一元素頂點緩衝區,如下圖所示。

著色器常數緩衝區的圖例

視儲存的資料格式而定,每個項目都會儲存一個包含 1 個至 4 個元件的常數。

常數緩衝區可允許著色器常數組成群組並同時認可 (而非進行個別呼叫以單獨認可每個常數),藉此減少更新著色器常數所需要的頻寬。

著色器會依照變數名稱來持續且直接讀取常數緩衝區中的變數,而讀取方法與不屬於常數緩衝區之變數所適用的方法相同。

每個著色器階段最多允許 15 個著色器常數緩衝區;每個緩衝區最多可以保存 4096 個常數。

使用常數緩衝區,即可儲存資料流輸出階段的結果。

如需在著色器中宣告常數緩衝區的範例,請參閱著色器常數 (DirectX HLSL)

紋理資源

紋理資源是專為儲存紋理像素所設計的一系列結構化資料。 不同於緩衝區,紋理可使用紋理取樣器篩選,因為它們會由著色器單位讀取。 紋理類型會影響紋理的篩選方式。 紋理像素代表紋理的最小單位,且可由管線讀取或寫入。 每個紋理像素都包含 1 到 4 個元件,並使用其中一種 DXGI 格式加以排列 (請參閱 DXGI_FORMAT)。

紋理會建立為結構化資源,以便告知其大小。 不過,在資源建立時,每個紋理都有可能具類型或不具類型,只要類型會在紋理繫結至管線時使用檢視來完整指定,就不會發生問題。

紋理類型

紋理包含多種類型:1D、2D 和 3D,而每個類型都可使用或不使用 Mipmap 加以建立。 Direct3D 也支援紋理陣列和多重取樣紋理。

1D 紋理

1D 紋理為最簡單的形式,而當中包含的紋理資料可使用單一紋理座標來定址;它可視覺化為紋理像素陣列,如下圖所示。

1d 紋理的圖例

視儲存資料的格式而定,每個紋理像素都包含多個色彩元件。 只要新增更多複雜度,您就能建立具有 Mipmap 層級的 1D 紋理,如下圖所示。

具有 Mipmap 層級的 1d 紋理圖例

Mipmap 層級是一種紋理,會比上一個層級小二次方。 最上層包含最多詳細資料,每個後續層級都會越來越小;對 1D Mipmap 而言,最小層級會包含一個紋理像素。 不同層級會由名為 LOD (詳細資料層級) 的索引進行識別;轉譯並未盡可能接近相機的幾何時,您可以使用 LOD 存取較小的紋理。

1D 紋理陣列

Direct3D 10 也有提供適用於紋理陣列的新資料架構。 就概念上而言,1D 紋理陣列會如下圖所示。

1d 紋理陣列的圖例

這個紋理陣列包含三個紋理。 三個紋理的寬度都是 5 (這也是第一層中的元素數量)。 每個紋理也包含一個 3 層 Mipmap。

Direct3D 中的所有紋理陣列都是紋理的同質陣列;這表示,紋理陣列中的每個紋理,都必須使用相同的資料格式和大小 (包括紋理寬度和 Mipmap 層級的數量。) 您可以建立不同大小的紋理陣列,只要每個陣列中的所有紋理都使用相同的大小即可。

2D 紋理和 2D 紋理陣列

Texture2D 資源包含一個 2D 紋理像素方格。 每個紋理像素都可透過 u、v 向量定址。 由於它是紋理資源,因此,當中可能包含 Mipmap 層級和子資源。 完整填入的 2D 紋理資源會如下圖所示。

2d 紋理資源的圖例

這個紋理資源包含單一 3x5 紋理,且具有三個 Mipmap 層級。

Texture2DArray 資源為 2D 紋理的同質陣列;這表示,每個紋理都有相同的資料格式和維度 (包括 Mipmap 層級)。 其配置與 1D 紋理陣列相似,而兩者的差異在於:紋理現在包含 2D 資料,因此會如下圖所示。

2d 紋理資源的陣列圖例

這個紋理陣列包含三個紋理;每個紋理都是 3x5,且具有兩個 Mipmap 層級。

將 Texture2DArray 做為紋理立方體

紋理立方體是一個 2D 紋理陣列,當中包含 6 個紋理,立方體的每一面各一個紋理。 完整填入的紋理立方體會如下圖所示。

代表紋理立方體之 2d 紋理資源的陣列圖例

包含 6 個紋理的 2D 陣列使用立方體紋理檢視繫結至管線後,就能從具有立方體對應內建函式的立方體著色器中讀取。 紋理立方體可從具有自紋理立方體中心指向之 3D 向量的著色器來定址。

3D 紋理

Texture3D 資源 (又稱為體積紋理) 包含一個 3D 紋理像素體積。 由於它是紋理資源,因此可能包含 Mipmap 層級。 完整填入的 3D 紋理會如下圖所示。

3d 紋理資源的圖例

當 3D 紋理 Mipmap 配量繫結為轉譯目標輸出 (使用轉譯目標檢視) 時,3D 紋理的行為就會與具有 n 配量之 2D 紋理相同。 特定轉譯配量會從幾何著色器階段選取。

由於 3D 紋理陣列概念並不存在;因此,3D 紋理子資源為單一 Mipmap 層級。

子資源

Direct3D API 會參考整個資源或資源子集。 為了指定部分資源,Direct3D 導入了子資源一詞,並用以代表資源子集。

緩衝區會定義為單一子資源。 紋理則比較複雜一點,因為存在許多不同的紋理類型 (1D、2D 等),而有些類型可支援 Mipmap 層級和/或紋理陣列。 從最簡單的案例開始,1D 紋理會定義為單一子資源,如下圖所示。

1d 紋理的圖例

這表示,組成 1D 紋理的紋理像素陣列會包含在單一子資源中。

如果展開具有三個 Mipmap 層級的 1D 紋理,就能像這樣將其視覺化。

具有 Mipmap 層級的 1d 紋理圖例

請將此視為由三個子紋理組成的單一紋理。 每個子紋理都會視為子資源,因此,這個 1D 紋理包含 3 個子資源。 子紋理 (或子資源) 可使用單一紋理的詳細資料層級 (LOD) 編製索引。 使用紋理陣列時,必須具備 LOD 和特定紋理,才能存取特定子紋理。 或者,API 可將這兩個資訊片段合併為單一以零為基底的子資源索引,如下方所示。

以零起始的子資源索引圖例

選取子資源

有些 API 會存取完整資源,有些則只會存取部分資源。 通常,存取部分資源的 API 會使用檢視描述,以指定想要存取的子資源。

這些數字會說明檢視描述在存取紋理陣列時使用的詞彙。

陣列配量

假設有一個紋理陣列,當中的每個紋理都具備 Mipmap,則紋理配量 (使用白色矩形表示) 會包含一個紋理及其所有子紋理,如下圖所示。

陣列接合圖例

Mip 配量

Mip 配量 (使用白色矩形表示) 會在陣列中的每個紋理內包含一個 Mipmap 層級,如下圖所示。

mip 接合圖例

選取單一子資源

您可以使用這兩個類型的配量來選擇單一子資源,如下圖所示。

使用陣列配量和 mip 接合選擇子資源的圖例

選取多個子資源

或者,您可以使用這兩個類型的配量搭配 Mipmap 層級和/或紋理數量,以選擇多個子資源。

選擇多個子資源的圖例

無論所使用的紋理類型為何,是否具有 Mipmap,以及是否具有紋理陣列,通常都會提供 Helper 函式,以計算特定子資源的索引。

強式與弱式輸入

建立完全具類型資源,即可將資源限縮在當初建立時所使用的格式中。 這可讓執行階段最佳化存取,特別在資源使用指出其無法由應用程式對應之旗標加以建立時,更是如此。 使用特定類型建立的資源,將無法使用檢視機制來重新解譯。

在不具類型的資源中第一次建立資源時,資料類型為未知。 應用程式必須在可用的不具類型格式中進行選擇。 您必須指定要配置的記憶體大小,以及執行階段是否需要在 Mipmap 中產生子紋理。

不過,在資源繫結至具有檢視的管線前,將不會判斷確切的資料格式 (無論記憶體是否將解譯為整數、浮點值、不帶正負號的整數等)。 由於紋理格式會保有彈性,直到紋理繫結至管線為止,因此,資源會稱為弱式具類型儲存。 弱勢具類型儲存的優勢在於:只要新格式的元件位元與舊格式的位元計數相符,就可重複使用或重新解譯 (使用其他格式)。

只要每個館現階段都有唯一的檢視,以完全符合每個位置的格式,單一資源就能繫結至多個管線階段。 舉例來說,使用不具類型格式建立的資源,可同時在管線中的不同地點做為 FLOAT 格式和 UINT 格式使用。

資源