次の方法で共有


最近点サンプリング (Direct3D 9)

アプリケーションでは、必ずしもテクスチャー フィルタリングを使用する必要はありません。Direct3D の設定により、テクセル アドレスを計算したり (これは多くの場合、整数として評価されません)、最も近い整数アドレスを持つテクセルのカラーをコピーさせることができます。このプロセスは、最近点サンプリングと呼ばれます。テクスチャーのサイズがスクリーン上のプリミティブのイメージのサイズと近い場合、この方法によって迅速かつ効率的にテクスチャーを処理できます。サイズの差が大きい場合は、テクスチャーを拡大または縮小する必要があります。その結果、イメージが粗くなったり、不鮮明になったり、輪郭がギザギザになることがあります。

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

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

この不自然な効果は、小さなテクスチャーを大きなポリゴンにマッピングしたときに発生します。この処理は、多くの場合、拡大と呼ばれます。たとえば、チェッカーボードのようなテクスチャーで最近点サンプリングを使用すると、チェッカーボードが拡大されてエッジが明瞭になります。それとは対照的に、線形テクスチャー フィルタリングを使用すると、チェッカーボードのカラーがポリゴン全体で滑らかに変化したイメージが生成されます。

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

Six-sectioned box with noncontinuous red horizontal lines in the two upper-right squares

グループの右上にある 2 つの正方形が隣接する正方形と異なっていることに注目してください。これらの正方形には対角線上にずれがあります。このような不自然なグラフィック効果を防ぐには、Direct3D における最近点フィルタリングのテクスチャー サンプリングの規則を理解しておく必要があります。Direct3D では、[0.0, 1.0] (0.0 ~ 1.0、0.0 および 1.0 を含む) の範囲の浮動小数点テクスチャー座標を [ - 0.5, n - 0.5] の範囲の整数テクセル空間値にマッピングします。n はテクスチャーのサイズにおけるテクセルの数です。生成されるテクスチャー インデックスは、最も近い整数に丸められます。このマッピングによって、テクセル境界でサンプリングの誤差が生じる可能性があります。

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

Texture coordinates 0.0 and 1.0 at the boundary between texels

この図のテクスチャー座標 0.0 と 1.0 は、ちょうどテクセルの境界にあります。Direct3D での値のマッピングを使用した場合、テクスチャー座標は [ - 0.5, 4 - 0.5] の範囲内にマッピングされます (4 はテクスチャーの幅です)。この場合、テクスチャー インデックス 1.0 に対して 0 番目のテクセルがサンプリングされます。ただし、テクスチャー座標が 1.0 よりもわずかに小さい場合、サンプリングされるテクセルは 0 番目のテクセルではなく、n 番目のテクセルになります。

これは、テクスチャー座標が正確に 0.0 と 1.0 の小さなテクスチャーを、三角形が並べられたスクリーン空間で拡大すると、最近点フィルタリングによって、テクセルの境界でテクスチャー マップのサンプリングが行われるピクセルが生じることを意味します。テクスチャー座標の計算誤差がいかに小さくても、テクスチャー マップのテクセル エッジに対応するレンダリングされたイメージの領域に沿って、不自然な効果が発生します。

このように浮動小数点テクスチャー座標を整数テクセルに完全に正確にマッピングするのは困難であると同時に、計算にも時間がかかります。通常、このような処理は必要ありません。ほとんどのハードウェア実装では、三角形内の各ピクセル位置におけるテクスチャー座標の計算には補間の手法が使用されます。補間アプローチでは、補間時に誤差が均等に累積されるので、このような誤差が目立たない傾向にあります。

Direct3D リファレンス ラスタライザーは、各ピクセル位置でのテクスチャー インデックスの計算に直接評価の方法を使用します。直接評価は補間の手法とは異なり、処理誤差によるエラーがよりランダムに分散します。この結果、境界上で、より顕著なサンプリング エラーが発生します。これは、リファレンス ラスタライザーによって、この処理が正確に実行されないためです。

最も良い方法は、必要な場合にのみ最近点フィルタリングを使用することです。最近点フィルタリングを使用しなければならない場合は、不自然な効果を防ぐために、テクスチャー座標を境界位置から少し離すことをお勧めします。