ミップマップを使用したテクスチャ フィルター処理 (Direct3D 9)

ミップマップは連続したテクスチャで、各テクスチャは同じイメージを徐々に低い解像度で表したものです。 ミップマップ内の各画像 (レベル) の高さと幅は、前のレベルよりも 2 つ小さい累乗です。 ミップマップは正方形である必要はありません。

ユーザーに近いオブジェクトには、解像度の高いミップマップ イメージが使用されます。 オブジェクトが遠くに表示されるにつれて、より低い解像度のイメージが使用されます。 ミップマップ処理によってレンダリングしたテクスチャの品質は向上しますが、使用するメモリは増加します。

Direct3D では、付属サーフェスのチェーンとしてミップマップが表現されます。 解像度が最も高いテクスチャはチェーンの先頭にあり、次のレベルのミップマップを添付データとして保有します。 さらに、そのレベルではミップマップ内の次のレベルの添付データを保有し、解像度が最も低いミップマップに至るまで続きます。

以下の各図は、これらのレベルの例を示したものです。 このビットマップ テクスチャは、主観視点の 3D ゲームにおけるコンテナーの警告表示を表しています。 ミップマップとして作成すると、解像度が最も高いテクスチャが先頭になります。 ミップマップ セット内のその後に続く各テクスチャの高さと幅は 2 の累乗ずつ小さくなります。 この場合、解像度が最も高いミップマップは 256 × 256 ピクセルです。 次のテクスチャは 128 × 128 です。 チェーン内の最後のテクスチャは 64 × 64 です。

この表示は、可視範囲から最大の距離にあります。 ユーザーがこの表示から遠く離れたところからゲームを始めた場合、ミップマップ チェーン内の最小のテクスチャ (この場合は 64 x 64 のテクスチャ) が表示されます。

警告表示の 64 x 64 のテクスチャの図

ユーザーが視点を警告表示に近づけるにつれて、徐々にミップマップ チェーン内の解像度が高いテクスチャが使用されます。 次の図の解像度は 128 x 128 です。

警告表示の 128 x 128 のテクスチャの図

次の図に示すように、ユーザーの視点が警告表示からの許容最短距離にあるとき、解像度が最も高いテクスチャが使用されます。

警告表示の 256 x 256 のテクスチャの図

これは、テクスチャの遠近の見え方をシミュレートする際の効率的な方法です。 1 つのテクスチャを多くの解像度でレンダリングするよりも、複数のテクスチャを各解像度で使用する方が時間がかかりません。

Direct3D では、ミップマップ セット内のどのテクスチャが目的とする出力に最も近い解像度であるかを評価し、そのテクセル空間にピクセルをマッピングすることができます。 最終画像の解像度がミップマップ セット内の複数のテクスチャ解像度の間にある場合、Direct3D では、両方のミップマップのテクセルを調べて、そのカラー値をブレンドします。

ミップマップを使用するには、アプリケーションでミップマップのセットを作成する必要があります。 アプリケーションでは、ミップマップ セットを現在のテクスチャ セットの最初のテクスチャとして選択することによって、ミップマップを適用します。 詳細については、「 テクスチャ ブレンド (Direct3D 9)」を参照してください。

次に、Direct3D でテクセルのサンプリングに使用するフィルタリング方法を設定する必要があります。 最も時間がかからないミップマップ フィルタリング方法は、Direct3D で最も近いテクセルを選択する方法です。 これを選択するには、D3DTEXF_POINT 列挙値を使用します。 Direct3D では、D3DTEXF_LINEAR 列挙値を使用すると、より適切なフィルタリング結果を生成することができます。 これによって最も近いミップマップが選択され、テクスチャ内の現在のピクセルがマッピングされる位置の周辺で、テクセルの加重平均が計算されます。

ミップマップ テクスチャは 3D シーンで使用され、シーンのレンダリングに必要な時間が短縮されます。 また、シーンのリアリティも増します。 ただし、多くの場合、大量のメモリを必要とします。

ミップマップのセットの作成

次の例は、アプリケーションで IDirect3DDevice9::CreateTexture メソッドを呼び出して、256x256、128x128、64x64、32x32、16x16 の 5 つのミップマップ レベルのチェーンを構築する方法を示しています。

// This code example assumes that m_d3dDevice is a
// valid pointer to a IDirect3DDevice9 interface

IDirect3DTexture9 * pMipMap;
m_pD3DDevice->CreateTexture(256, 256, 5, 0, D3DFMT_R8G8B8, 
    D3DPOOL_MANAGED, &pMipMap);

IDirect3DDevice9::CreateTexture で受け入れられる最初の 2 つのパラメーターは、最上位のテクスチャのサイズと幅です。 3 番目のパラメーターは、テクスチャ内のレベルの数を指定します。 これを 0 に設定すると、Direct3D はサーフェスのチェーンを作成し、それぞれが前のサーフェスより 2 つ小さく、可能な限り小さいサイズの 1x1 まで小さくなります。 4 番目のパラメーターは、このリソースの使用状況を指定します。この場合、リソースの特定の使用状況を示すために 0 が指定されます。 5 番目のパラメーターは、テクスチャのサーフェス形式を指定します。 このパラメーターには、 D3DFORMAT 列挙型の値を使用します。 6 番目のパラメーターは、作成されたリソースを配置するメモリ クラスを示す D3DPOOL 列挙型のメンバーを指定します。 動的テクスチャを使用しない限り、D3DPOOL_MANAGEDをお勧めします。 最後のパラメーターは、 IDirect3DTexture9 インターフェイスへのポインターのアドレスを受け取ります。

Note

ミップマップ チェーン内の各サーフェスには、チェーン内の前のサーフェスの 2 分の 1 の寸法があります。 最上位のミップマップのサイズが 256 x 128 である場合、第 2 レベルのミップマップのサイズは 128 x 64、第 3 レベルは 64 x 32 というように小さくなり、最終的には 1 x 1 になります。 Levels では、チェーン内のミップマップの幅または高さが 1 より小さくなるようなミップマップ レベルを指定することはできません。 最上位のミップマップ サーフェスが 4 × 2 の単純な場合、Levels の有効最大値は 3 です。 最上位のサイズが 4 × 2 である場合、第 2 レベルのサイズは 2 × 1、第 3 レベルのサイズは 1 × 1 になります。 Levels の値が 3 よりも大きい場合、第 2 レベルのミップマップの高さが小数値になるので、許可されません。

 

Mipmap の選択と表示

IDirect3DDevice9::SetTexture メソッドを呼び出して、現在のテクスチャの一覧の最初のテクスチャとして設定されたミップマップ テクスチャを設定します。 詳細については、「 テクスチャ ブレンド (Direct3D 9)」を参照してください。

アプリケーションで mipmap テクスチャ セットを選択した後、 D3DTEXTUREFILTERTYPE 列挙型の値を D3DSAMP_MIPFILTER サンプラー状態に割り当てる必要があります。 その後、Direct3D はミップマップ テクスチャ のフィルター処理を自動的に実行します。 次のコード例では、mipmap テクスチャ のフィルター処理を有効にする方法を示します。

m_pD3DDevice->SetTexture(0, pMipMap);
m_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

アプリケーションでは、 IDirect3DTexture9::GetSurfaceLevel メソッドを使用し、取得するミップマップ レベルを指定することで、ミップマップ サーフェスのチェーンを手動で走査することもできます。 次の例では、ミップマップ チェーンを最高解像度から最小解像度まで走査します。

IDirect3DSurface9 * pSurfaceLevel;
for (int iLevel = 0; iLevel < pMipMap->GetLevelCount(); iLevel++)
{
    pMipMap->GetSurfaceLevel(iLevel, &pSurfaceLevel);
    // Process this level
    pSurfaceLevel->Release();
}

アプリケーションでは、ミップマップ チェーンを手動で走査して、ビットマップ データをチェーン内の各サーフェスに読み込む必要があります。 これは通常、チェーンを走査する唯一の理由です。 アプリケーションは、 IDirect3DBaseTexture9::GetLevelCount を呼び出すことによって、ミップマップ内のレベルの数を取得できます。

テクスチャ のフィルター処理