共用方式為


使用 UVAtlas (Direct3D 9)

注意

UVAtlas 最初隨附於現已不再使用的 D3DX9 公用程式庫中。 最新版本可在 UV Atlas Command-Line Tool (uvatlas.exe)取得。

許多渲染和內容生成技術都需要將 2D 信號(例如紋理)唯一且非重疊地映射到一個網格上。 這類技術包括:

  • 一般/位移對應
  • 紋理空間 PRT 模擬和光線對應
  • 表面彩繪
  • 紋理空間光源

手動生成獨特的UV映射通常是耗時且乏味的,尤其是當輸入的幾何形狀複雜且需要高效或低失真的紋理空間利用時。 下圖顯示範例網格及其對應的紋理圖集。

顯示範例網格及其對應的紋理圖集。

本範例顯示網格(左側)和對應的UV空間法線地圖(右側)。 請注意,紋理圖集包含數個群組或數據叢集;每個叢集稱為圖表,並在上述範例中顯示包含網格部分的一般數據。

D3DX UVAtlas API 會自動產生最佳的非重疊紋理圖集。 API 提供輸入參數,可讓您:

  • 最小化紋理伸展、失真和取樣不足。
  • 最大化紋理空間封裝密度,以有效率地使用記憶體。
  • 提供跨網格的偶數取樣,將取樣頻率中的不連續程度降至最低。

UVAtlas 的運作方式

UVAtlas API(請參閱 UVAtlas 函式),藉由將表面分割成區塊並將區塊封裝成紋理圖集。 使用 D3DXUVAtlasPartitionD3DXUVAtlasPack 個別執行這些步驟:或使用 D3DXUVAtlasCreate 在單一呼叫中分割、參數化和封裝。

分割和參數化網格

首先,網格會分割成圖表,然後每個圖表都會參數化為自己的 [0,1] UV 空間。 圓柱體可以用一個圖表來參數化;然而,球體則需要兩個圖表,這如下面的插圖所示。

分割成兩個圖表的球體 圖例

可以使用單一圖表參數化的網格分類為「同胚於圓盤」,這表示您可以將無限彈性、無限延展的圓盤展開覆蓋在圖表上,並完美地覆蓋幾何形狀。 這種延展,稱為自體,是雙向函式:這表示您可以從一個參數化到另一個參數化,而不會遺失資訊。

很少有真實世界的網格可以參數化為兩個維度,而不需要將網格分成叢集或圖表。 下圖顯示另一個範例網格及其對應的紋理圖集。

顯示具有不同圖形及其對應紋理圖集的範例網格。

有兩個參數可決定建立的圖表數目:

  • 地圖集允許的圖表數目上限
  • 每個圖表允許的最大延展量

延展量將決定產生的圖表數目,以及取樣的整體品質。 伸展範圍從 0.0(無伸展)到 1.0(任何伸展量)。 D3DXUVAtlasCreate 和 D3DXUVAtlasPartition 會傳回演算法所產生的最大延展。 下圖顯示另一個範例網格及其對應的紋理圖集。

一個範例網格及其對應的紋理圖集之圖例

使用整合式計量張量來控制參數化

可以為每個三角形指定紋理空間的優先順序。 您可以提供 Integrated Metric Tensors 來控制三角形的延展方式於生成的紋理空間圖集。 可以直接指定 IMT,或透過使用 D3DX IMT 計算函式根據輸入訊號來計算。 整合式計量張量 (或 IMT) 是對稱的 2x2 矩陣,描述三角形在地圖集中的延展方式。 每個 IMT 都是由 3 個浮點數定義,分別為(a, b, c)。 它們可以以對稱的 2x2 矩陣來排列,如下所示:

a b
b c

然後,IMT 可用來尋找兩個向量之間的距離。 指定兩個向量 v1 和 v2, 其中 :

vector v1
vector v2 = v1 + (s,t)

v1 和 v2 之間的距離可計算為:

sqrt((s, t) * M * (s, t)^T)

換句話說,向量(s,t)可能是 u-v 空間中任意方向伸展的大小。 在此情況下,s 向量是從第一個到第二個頂點的方向,而 t 是 normal 和 s 的交叉乘積。 例如:

(1,1) * (1,1) = (2,2)
        (1,1)
IMT(1,1,1) scales by 2
(1,-1) * (1,1) = (0,0)
         (1,1)
IMT(2,0,2) scales by 2 with no shearing

您可以使用 D3DX IMT 計算函式,直接或根據輸入訊號來指定 IMT:D3DXComputeIMTFromPerVertexSignal、D3DXComputeIMTFromPerTexelSignal、D3DXComputeIMTFromSignal 和 D3DXComputeIMTFromTexture_graphics。

如果您想要控制紋理空間配置給個別三角形的方式,請直接指定IMT數據。 如此一來,將紋理貼圖中的更多區域配置給網格的重要部分(例如角色的臉部或胸部標誌,或玩家行走路徑附近場景的區域)。 藉由指定身分識別矩陣的倍數 IMT,產生的三角形將會在紋理空間中統一縮放。

例如,假設有高解析度的一般地圖,您可以計算 IMT,為一般地圖中較高頻率訊號的區域提供更多紋理空間。 「平面」的三角形(對應至原始一般地圖的常數區域)將會收到較少的紋理空間。 包含大量一般地圖詳細數據的三角形將會在最終結果中接收更多紋理區域。 然後,您可以將一般地圖重新取樣到較小的紋理,但會維護詳細數據,或者您可以使用更理想的 UV 對應重新計算一般地圖。

針對使用者指定的摺痕使用相鄰數據

使用者定義的鄰接資訊可以提供給分區功能,以描述網格中預先定義的摺痕,從而定義相鄰面之間的區域邊界。 這是使用者將自己的圖表分區指定為演算法輸入的一種簡便方法,這將進一步調整圖表,使伸展控制在允許的最大值以下。

此範例說明如何使用UVAtlas API和 DirectX 查看器 (Dxviewer.exe) 來尋找並修正模型中的不連續性,而這可能會大幅影響紋理圖集的大小。 您可以從 DirectX SDK 取得 Dxviewer.exe 並瞭解相關資訊。 Dxviewer.exe 在 2009 年 8 月版本之後從 DirectX 軟體開發包中移除,因此您至少需要 2009 年 8 月的 DirectX 軟體開發包。 如需 DirectX SDK 的相關信息,請參閱 DirectX SDK 在哪裡?

假設您在慣用的內容產生軟體中開始使用一些模型(本範例使用在Maya中建立的矮頭模型)。 將紋理模型導出至 .x 檔案,並使用 D3DXUVAtlasCreate 建立紋理圖集。 產生的紋理圖集看起來會類似下圖。

矮人模型的插圖

此地圖集有 22 個圖表,最大延展為 0.994。

現在查看紋理模型,看看紋理圖集如何映射到幾何結構。 若要這樣做,請將模型載入查看器工具:

  • 從 DirectX 公用程式開啟查看器工具。
  • 按兩下 [開啟] 按鈕以載入 .x 檔案。
  • 按一下檢視按鈕,然後從彈出視窗中選取 [摺痕],以啟用摺痕檢視選項。

下圖顯示您應該在查看器工具中看到的內容。

查看器工具中紋理網格的 插圖

每一條線都是摺痕,這是紋理圖集中兩個圖表之間的相鄰邊緣。 演算法所產生的圖表數目可能是因為常態的不連續而產生微差異所造成。 這些小差異可以藉由整合數據來減少,也就是說,將接近相等的數據強制調整為完全相等。 若要焊接正常值和重量級:

  • 在網格上使用下列命令行執行 DirectX Ops (dxops.exe) 工具 (以模型的名稱取代 'modelName.x' ):
    Dxops.exe -s "load 'modelName.x'; Optimize n:2.01 w:2.01 uv0:0.01;  save 'newModelName.x';"
    

這會比較法線和蒙皮權重,當其值之差小於 2.01 時,數據會設為相等。 下圖顯示眼睛的特寫,以查看焊接前的摺痕(左上)和焊接後摺痕(右圖):

焊接後折痕圖例 焊接後摺痕圖例

圖 7:通過焊接移除摺痕

在此範例中,焊接已從輸入網格中移除 86 個頂點。 由於網格中的摺痕較少,您可以重新產生地圖集,如下圖所示。

已移除摺痕的新地圖集 圖例

此地圖集只有 7 個圖表,最大延展約 0.0776。 新的地圖集現在適合更小的紋理(在此範例中大約小了 30%%)。

將圖表封裝到 Atlas

一旦網格分割成個別參數化圖表,圖表就必須有效率地封裝成單一紋理地圖。 此動作會作為 D3DXUVAtlasCreate 的第二個步驟來執行,或可以直接呼叫 D3DXUVAtlasPack 來達成。

包裝圖表會以使用者指定的排水溝寬度分隔。 圖表間距是圖表之間的分隔量,可以進行雙線性插值和 Mip 映射,以避免在圖表邊界出現渲染瑕疵。 D3DX 提供介面來自動填入這些排水溝 - 如需詳細資訊,請參閱 ID3DXTextureGutterHelper

將UVAtlas整合到管線中

除了在紋理繪製之前由藝術家使用之外,這些功能還可以整合到自動化藝術管線中。 例如,在資產更新後,可以在執行PRT模擬或法線貼圖處理之前,自動發出UVAtlas呼叫。 這可避免在修改網格拓撲時需要手動修復物件的 UV 對應。

範例使用UVAtlas函數,請參閱 UV Atlas Command-Line Tool (uvatlas.exe)

進階主題