使用 UVAtlas (Direct3D 9)

注意

UVAtlas 原本已過時的 D3DX9 utilty 程式庫隨附。 最新版本位於 UV Atlas Command-Line Tool (uvatlas.exe)

許多轉譯和內容產生技術都需要 2D 訊號 (的唯一非重迭地圖,例如紋理) 網格。 這類技術包括:

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

手動產生唯一的 UV 對應通常是耗時且繁瑣的;當輸入幾何很複雜且需要有效率/低失真紋理空間使用率時,這特別適用。 下圖顯示範例網格及其對應的紋理圖集。

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

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

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

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

UVAtlas 的運作方式

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

分割和參數化網格

首先,網格會分割成圖表,然後每個圖表都會參數化為自己的 [0,1] UV 空間。 一張圖表可以參數化直條圖;另一方面,球體需要兩個圖表,如下圖所示。

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

可使用單一圖表參數化的網格分類為「主型至磁片」,這表示您可以將無限彈性、無限延展的磁片分散到圖表上,並完全涵蓋幾何。 這個延展稱為主型,是雙向函式;這表示您可以從一個參數化到另一個參數化,而不會遺失資訊。

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

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

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

  • Atlas 允許的最大圖表數目
  • 每個圖表允許的延展最大數量

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

範例網格及其對應的紋理圖例

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

紋理空間優先順序可以依據每個三角形來指定。 您可以提供整合式計量 Tensors 來控制三角形在產生的紋理空間圖中如何延展。 您可以使用 D3DX IMT 計算函式,直接或根據輸入訊號來指定 IMT。 整合式計量張量 (或 IMT) 是對稱的 2x2 矩陣,描述如何在 atlas 中延展三角形。 每個 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 是一般 和 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 資料。 如此一來,請在 atlas 中配置更多區域給網格 (的重要區域,例如字元的臉部或標誌,或玩家的逐步路徑) 附近的場景區域。 藉由指定身分識別矩陣的倍數,產生的三角形將會在紋理空間中統一縮放。

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

針對使用者指定的 Creases 使用相鄰資料

使用者定義相鄰資訊可以提供給資料分割函式,以描述網格中預先定義的 Crease,進而定義相鄰臉部之間的圖表界限。 這是呼叫端將自己的圖表分割指定為演算法輸入的簡單方式,這會進一步精簡圖表,使延展達到允許的最大值。

範例

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

假設您已在慣用的內容產生軟體中開始使用一些模型, (此範例會使用在 Maya) 中建立的 dwarf 前端模型。 將紋理模型匯出至 .x 檔案,並使用 D3DXUVAtlasCreate 建立紋理 atlas。 產生的紋理 atlas 看起來會像下圖所示。

dwarf 模型的 Atlas 圖例

atlas 有 22 個圖表,最大延展為 0.994。

現在查看紋理模型,以查看紋理圖集對應至幾何的方式。 若要這樣做,請將模型載入檢視器工具:

  • 從 DirectX 公用程式開啟檢視器工具。
  • 按一下 [開啟] 按鈕以載入 .x 檔案。
  • 按一下 [檢視] 按鈕,然後從快顯視窗選取 [Creases],以啟用 Crease 檢視選項。

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

檢視器工具中紋理網格的圖例

每一條線都是一個折線,這是紋理圖集中兩個圖表之間的相鄰邊緣。 演算法所產生的圖表數目可能是因為常態中的不連續而有些許差異所造成。 這些小型差異可藉由將資料接合來減少,也就是說,強制幾乎等於等於的資料。 若要將常態和麵板重量接合:

  • 在網格上使用下列命令列執行 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 個頂點從輸入網格中移除。 在網格中產生較少的 Crease 時,您可以重新產生 atlas,如下圖所示。

已移除擷取新 atlas 的圖例

atlas 只有 7 個圖表,且最大延展約 0.0776。 新的 atlas 現在可放入較小的紋理, (本範例中大約 30% 的紋理) 。

將圖表封裝到 Atlas

一旦網格分割成個別參數化的圖表,圖表就必須有效率地封裝成單一紋理貼圖。 這會執行為 D3DXUVAtlasCreate 的第二個步驟,或可藉由呼叫 D3DXUVAtlasPack 明確叫用。

已封裝的圖表會以使用者指定的通線寬度分隔。 條形寬度是圖表之間的分隔量,並允許雙向內插補點和 Mip 對應,以避免在圖表界限轉譯成品。 D3DX 提供介面來自動填入這些通管線 - 如需詳細資訊,請參閱 ID3DXTextureGutterHelper

將 UVAtlas 整合到管線中

除了在紋理繪製之前叫用藝術師之外,這些函式還可以整合到自動化的藝術管線中。 例如,在更新資產之前,可以在執行 PRT 模擬或一般對應階段之前,自動發出 UVAtlas 呼叫。 如果網格拓撲已修改,這可避免手動修復物件的 UV 對應。

如需 UVAtlas 函式的使用範例,請參閱 UV Atlas Command-Line 工具 (uvatlas.exe)

進階主題