ゲーム開発ではなぜか mipmap が嫌われることがあります。

GPU のレンダリングではカメラからの距離に応じて、参照するテクスチャの解像度
を切り替えることができます。例えば 512x512 pixel のテクスチャ画像がある場合
あらかじめ縮小した画像を次のように何パターンも用意しておきます。

256x256
128x128
64x64
32x32
:

カメラから近い場合は高い解像度のテクスチャを参照しますが、遠くの場合は
高い解像度を使う必要がありません。mipmap を用意しておけばそのため遠くに行く
ほど小さいテクスチャの参照で済みます。いわゆるテクスチャ解像度の LOD の
ことです。この mip レベルの選択は pixel のレンダリング時に行われます。

正確にはカメラからの距離というよりも、レンダリングするポリゴンの面積から
計算すると効率が良いことがわかります。画面のピクセルに対してできる限り1対1で
対応する解像度のテクスチャを参照したいたいためです。

実際の実装ではピクセル間の uv の密集度から mipmap のレベルを判断します。
ピクセル間の差分は、PixelShader でも 2.x 以降なら dsx, dsy 命令で求める
ことができます。


テクスチャの拡大と異なり、縮小時のフィルタリングにはより多くの pixel 情報を
畳み込む必要があります。例えば最大まで縮小した 1x1 pixel の点には元の
テクスチャのすべての平均値が含まれます。

この計算はリアルタイムに向かないので、前処理でフィルタリングしておける
mipmap は低負荷ながら遠くのポリゴンのちらつきをおさえて画質の向上に
つながります。

もちろんテクスチャアクセス時の負担も減るので mipmap を使った方がテクスチャ
フェッチは高速です。

mipmap はできるだけ使ったほうが良いのです。


デメリットは、あらかじめ縮小した画像を含んでいる分だけテクスチャ容量が
1.34倍程度に増えることです。


コンシューマ系のゲーム開発で mipmap があまり使われないのは、ひとつは容量の
問題でしょう。Xbox1 以降なら容量に対してアクセス負荷が高いので、使用した
場合のメリットの方が大きいと考えられます。

極端にバスアクセスが速かったり、シェーダーでピクセル演算の方が重くて
テクスチャ読み込みが負担にならない場合はこの限りではありません。


もうひとつは mipmap を使ったほうが負荷が高いという思い込みがまだ残って
いることかもしれません。

そして画像が過度にぼけすぎることです。

画質がぼけすぎるのは、最適な解像度よりも下のレベルのテクスチャが参照される
ことがあるためです。

例えばテクスチャ画像とレンダリングされるポリゴンの縦横比が極端に異なると、
短い辺では最適な解像度でも、長い辺では解像度が足りなくなってしまいます。
見た目よりも低いレベルのテクスチャが参照され、引き伸ばされるが故に余計に
ぼけているように見えます。

3D 視点で描画される地面のように、カメラに対して角度のついたポリゴンはこの
傾向が強いので非常にボケボケの画質になりがちです。せっかく書き込んだ
テクスチャの詳細も失われてしまうので、これを嫌がるデザイナーも多いのです。


こんなときは mipmap を切るのではなく異方性フィルタ(Anisotropic filtering)
を活用します。
(続く)