Nearest-Point サンプリング (Direct3D 9)

アプリケーションでは、必ずしもテクスチャ フィルタリングを使用する必要はありません。 Direct3D は、テクセル アドレスを計算するように設定できます。この場合、整数に評価されることはあまりなく、最も近い整数アドレスを持つテクセルの色がコピーされます。 このプロセスは、最近点サンプリングと呼ばれます。 これは、テクスチャのサイズが画面上のプリミティブのイメージのサイズに似ている場合に、テクスチャを迅速かつ効率的に処理する方法です。 そうでない場合、テクスチャを拡大または縮小する必要があります。 結果には、分厚い画像、エイリアス化された画像、またはぼやけた画像を指定できます。

C++ アプリケーションは、 IDirect3DDevice9::SetSamplerState メソッドを呼び出すことによって、最も近いポイントサンプリングを選択できます。 最初のパラメーターの値を、テクスチャ フィルター方法を選択するテクスチャの整数インデックス番号 (0 から 7) に設定します。 2 番目のパラメーターにD3DSAMP_MAGFILTER、D3DSAMP_MINFILTER、またはD3DSAMP_MIPFILTERを渡して、倍率、縮小、またはミップマップ フィルターを設定します。 3 番目のパラメーターにD3DTEXF_POINTを渡します。

テクスチャが 2 つのテクセル間の境界でサンプリングされるとグラフィックアーティファクトが発生する場合があるため、最も近いポイントサンプリングを慎重に使用する必要があります。 この境界は、サンプリングされたテクセルがあるテクセルから次のテクセルに移動するテクスチャに沿った位置 (u または v) です。 点サンプリングを使うと、システムはいずれかのサンプル テクセルを選択するため、境界をまたぐと、あるテクセルと次のテクセルで結果が突然変わる可能性があります。 この効果は、表示されたテクスチャのグラフィックが不自然になって現れる可能性があります。 リニア フィルタリングを使うと、生成されるテクセルは隣接する両方のテクセルから計算され、テクスチャ インデックスが境界をまたいで移動するとそれらのテクセルをスムーズにブレンドします。

この効果は、非常に小さいテクスチャを非常に大きい多角形にマッピングすると (多くの場合、拡大と呼ばれる操作) 現れる可能性があります。 たとえば、チェッカーボードのようなテクスチャを使った場合、最近点サンプリングを行うと縁がはっきりした大きいチェッカーボードになります。 一方、リニア テクスチャ フィルタリングを行うと、チェッカーボードの色が多角形間でスムーズに変化するイメージになります。

ほとんどの場合、可能な限り最近点サンプリングを避けることでアプリケーションは最良の結果を出します。 現在のハードウェアの大部分は、リニア フィルタリングに合わせて最適化されているため、アプリケーションのパフォーマンスが低下することはありません。 目的の効果を出すためにどうしても最近点サンプリングを使う必要がある場合 (読みやすいテキスト文字を表示するためにテクスチャを使う場合など)、アプリケーションがテクセル境界でサンプリングを行わないように特に注意する必要があります (望ましくない効果が現れる可能性があるため)。 次の図は、どのように不自然な効果が現れるかを示しています。

右上の 2 つの四角形に連続しない水平線が表示されている、6 つに分割されたボックスの図

グループの右上にある 2 つの四角形は、隣接する正方形とは異なって表示され、斜めのオフセットが通っています。 このような不自然なグラフィックを避けるには、最近点サンプリングの Direct3D テクスチャ サンプリング ルールについて精通している必要があります。 Direct3D は、[0.0, 1.0] (0.0 から 1.0。両端を含む) の範囲の浮動小数点テクスチャ座標を、[ - 0.5, n - 0.5] (n はテクスチャの特定の範囲におけるテクセルの数) の範囲の整数テクセル空間値にマッピングします。 生成されたテクスチャ インデックスは最も近い整数に丸められます。 このマッピングにより、テクセル境界でサンプリングが不正確になる可能性があります。

簡単な例として、D3DTADDRESS_WRAP テクスチャ アドレッシング モードでポリゴンをレンダリングするアプリケーションを想像してください。 Direct3D により採用されているマッピングを使うと、次のテクスチャの図に示すように、u テクスチャ インデックスは 4 テクセルの幅にマッピングされます。

テクセルの境界にあるテクスチャ座標 0.0 および 1.0 の図

この図のテクスチャ座標 0.0 と 1.0 は、テクセル間の境界に正確に存在します。 Direct3D が値をマッピングする方法を使うと、テクスチャ座標の範囲は [ - 0.5, 4 - 0.5] (4 はテクスチャの幅) になります。 この場合、サンプリングされたテクセルはテクスチャ インデックスが 1.0 の 0 テクセルになります。 ただし、テクスチャ座標が 1.0 をわずかに下回る場合、サンプリングされたテクセルは 0 テクセルではなく n テクセルになります。

これは、画面空間に沿った三角形で最近点フィルタリングを行って、ちょうど 0.0 および 1.0 のテクスチャ座標を使って小さいテクスチャを拡大すると、テクセルの境界でテクスチャ マップがサンプリングされるピクセルとなることを意味します。 テクスチャ座標の計算における不正確さは大きくありませんが、テクスチャ マップのテクセルの縁に対応する、レンダリングされたイメージ内の領域に沿って不自然な結果が生じます。

浮動小数点テクスチャ座標を完全な正確さで整数テクセルにマッピングするのは難しいだけでなく、計算に時間がかり、一般には必要ありません。 ほとんどのハードウェア実装では、三角形内の各ピクセル位置でテクスチャ座標を計算するために反復的な方法が使われます。 反復的な方法では、反復中エラーが均等に積み重なるため、このような不正確さが隠れる傾向にあります。

Direct3D リファレンス ラスタライザーでは、各ピクセル位置でテクスチャ インデックスを計算するために直接評価の方法が使われます。 直接評価は、操作の不正確さがよりランダムなエラー分布となって現れる点が反復的な方法と異なります。 この結果、境界で発生したサンプリング エラーがより目立つことがあります。リファレンス ラスタライザーは、完全な正確さでこの操作を実行しないためです。

最も良い方法は、必要なときにだけ最近点フィルタリングを使うことです。 使う必要がある場合は、テクスチャ座標を境界位置からわずかにオフセットして、不自然な結果を回避することをお勧めします。

テクスチャ フィルタリング