Platform SDK: DirectX

最近点サンプリング

アプリケーションでは、テクスチャ フィルタリングを使用する必要はない。Direct3D は、テクセル アドレスを計算 (このアドレスは整数でないことが多い) したり、この値に最も近い整数アドレスを持つテクセルの色を単にコピーするように設定できる。この処理を最近点サンプリングと呼ぶ。テクスチャのサイズがスクリーン上のプリミティブの画像のサイズとほぼ同じ場合には、この方法によってテクスチャは高速で効率的に処理できる。両方のサイズの差が大きい場合は、テクスチャを拡大したり、縮小する必要がある。このような処理を実行した結果、画像が粗くなったり、ぎざぎざができたり、不鮮明になることがある。

[C++]

C++ アプリケーションでは、IDirect3DDevice7::SetTextureStageState メソッドを呼び出して最近点サンプリングを選択できる。第 1 パラメータの値を、テクスチャ フィルタリング方法を選択するテクスチャの整数インデックス番号 (0 〜 7) に設定する。第 2 パラメータを D3DTSS_MAGFILTER、D3DTSS_MIMIFILTER、または D3D_MIPFILTER に設定する。D3DTEXTUREMAGFILTERD3DTEXTUREMINFILTER、または D3DTEXTUREMIPFILTER 列挙型のメンバを次のパラメータの値として渡して、拡大、縮小、またはミップマップ フィルタを設定する。

詳細については、「テクスチャ フィルタリング ステート」を参照すること。

[Visual Basic]

Visual Basic アプリケーションでは、Direct3DDevice7.SetTextureStageState メソッドを呼び出して最近点サンプリングを選択できる。第 1 パラメータの値を、テクスチャ フィルタリング方法を選択するテクスチャの整数インデックス番号 (0 〜 7) に設定する。第 2 パラメータを D3DTSS_MAGFILTER、D3DTSS_MIMIFILTER、または D3D_MIPFILTER に設定する。CONST_D3DTEXTUREMAGFILTERCONST_D3DTEXTUREMINFILTER、または CONST_D3DTEXTUREMIPFILTER 列挙のメンバを次のパラメータに渡して、拡大、縮小、またはミップマップ フィルタを設定する。

詳細については、「テクスチャ フィルタリング ステート」を参照すること。

最近点サンプリングは注意して使用すること。2 つのテクセル間の境界でテクスチャがサンプリングされる際、場合によっては不自然なグラフィックス効果が生じることがある。この境界とは、サンプリング対象のテクセルが次のテクセルに移るときの、テクスチャに沿った位置座標 (u または v) である。ポイント サンプリングを使用するとき、システムではサンプル テクセルを 1 つ選択するか、別のテクセルを選択する。これにより、境界が交差している際は結果がテクセル間で不意に変化することがある。この影響から、表示されるテクスチャの中に、好ましくない不自然なグラフィックス エフェクトが現れることがある (線形フィルタリングを使用した場合、結果テクセルは隣接テクセル間で計算され、テクスチャ インデックスが境界に沿って移るのに従って滑らかにブレンドされる)。

このようなエフェクトは、非常に小さなテクスチャを非常に大きなポリゴンにマッピングする (多くの場合 "拡大" と呼ぶ) ときに発生する可能性がある。たとえば、チェッカー盤のようなテクスチャでポイント サンプリングを使用すると、チェッカー盤は拡大されてエッジが際立つ。対照的に、線形テクスチャ フィルタリングを使用した場合は、チェッカー盤の色がポリゴン全体にわたって滑らかに変化した画像ができあがる。

ほとんどの場合、最良の結果を得るためには、最近点サンプリングの使用をできるだけ避けるようにする。最近のハードウェアのほとんどは、線形フィルタリング用に最適化されているため、パフォーマンスが低下することはない。ただし、テクスチャを使用して読みやすいテキスト文字を表示する場合など、希望のエフェクトを出すためにどうしても最近点サンプリングを使用しなければならない場合は、テクセル境界でサンプリングを行わないように心がけ、思わぬエフェクトが生じないよう細心の注意を払う必要がある。次の図は、不自然なグラフィックス効果がどのようなものであるかを示す。

グループ内の右上にある 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 は、テクセル間の境界上に正確に位置する。Direct3D のマッピング用のメソッドを使用すると、テクスチャ座標は [–0.5, 4 0.5] の範囲内にマッピングされる。ここで、4 はテクスチャの幅である。この場合、サンプリングされるのは、テクスチャ インデックス 1.0 の 0 番目のテクセルである。ただし、テクスチャ座標が 1.0 よりもわずかに少ない場合には、サンプリングされるのは 0 番目のテクセルではなく、n 番目のテクセルになる。

これは、つまり、テクスチャ座標 0.0 と 1.0 を持つ小さなテクスチャを、スクリーン空間に配列された三角形上で最近点フィルタリングによって拡大すると、その結果、テクスチャ マップがテクセル間の境界でサンプリングされる際の対象となるピクセルになる、という意味である。テクスチャ座標の計算の誤差がわずかな場合であっても、テクスチャ マップのテクセル エッジに対応する、レンダリング画像の領域に沿って不自然な効果が現れる。

このように浮動小数点テクスチャ座標を整数テクセルに完璧に正確にマッピングするのは、困難な作業であり、計算負荷も大きいが、このような処理を一般には行う必要はない。ほとんどのハードウェア実装では、三角形内の各ピクセル位置座標におけるテクスチャ座標の計算に反復処理を用いる。この方法を使用すると、反復処理間で誤差が均等に累積されていくため、これらの誤差がいくらかは目立たなくなる。

Direct3D リファレンス ラスタライザでは、各ピクセル位置座標でのテクスチャ インデックスの計算に直接評価法を用いる。直接評価は反復処理とは異なり、処理上の誤差がよりランダムなエラー分布を示す。この結果、境界上ではより顕著なサンプリング エラーが発生する。これは、リファレンス ラスタライザによってこの処理が正確に実行されないためである (繰り返しになるが、浮動小数点テクスチャ座標の処理は、困難かつ計算負荷が非常に大きい)。

最近点フィルタリングは、必要な場合にのみ使用するとよい。これを使用する必要がある場合は、テクスチャ座標を境界位置座標から少しだけオフセットして不自然な効果の発生を防ぐことが推奨される。