次の方法で共有


最近点サンプリング

最近点サンプリング

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

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

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

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

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

6 つの部分から成るボックスの右上にある 2 つの四角形の中に不連続の赤い水平線が入っている

グループ内の右上にある 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 テクセル幅のテクスチャに対して、次のようにマッピングされる。

テクセル間の境界のテクスチャ座標 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 リファレンス ラスタライザでは、各ピクセル位置でのテクスチャ インデックスの計算に直接評価法を用いる。直接評価は反復処理とは異なり、処理上の誤差がよりランダムなエラー分布を示す。この結果、境界上ではより顕著なサンプリング エラーが発生する。これは、リファレンス ラスタライザがこの処理を正確には実行しないためである。

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