Imaginantia

思ったことを書きます

メモ 260429 MipMap Bias の調査

最近何かと (?) 話題なのでちゃんと調べてみることにしました。

現状

結論

確かに -0.7 くらいが安定っぽい気はする

真値とは

「何が望ましいか」自体を定義することはできないです。ただ、MipMap を「指定範囲の平均値を取得する仕組み」と捉えるならば、「真の平均値に近い方が望ましい」という評価ができます。

上3つは tex2Dbias でそれぞれ -1, 0, 1 を入れた結果。下は ddx, ddy を元にして「ピクセル範囲を LOD 0 で 16x16 回サンプルした平均値」です。

見た感じそれっぽいし、0 < Fine < -1 でだんだん sharp になっていることもわかります。天井がわかりやすいかな。

というわけで、「Fine に最も近い Mip Bias を見つけたい」という問題だと思うことができます。

ちなみに VRChat は VRChat/Mobile/Worlds/Supersampled UI というシェーダを提供していて (↑ の SS)、これは Bias -1 で 4 回サンプルした平均を表示するもののようです。確かにちょっと sharp な見た目になっていますが、4 回平均を取っていることで少しボケてもいる雰囲気ですね。

最適を計算する

「最も Fine に近い Bias」をピクセル/チャンネルごとに計算することはできるんですが、それを画像全体の指標として使うところにはちょっとギャップがあります。人の眼としては「linear-RGB値の近さ」よりも、perceptual な明るさの比較とか、エイリアスが少ないとか、まぁそういうのを気にしたいです。

が、それは結局画像によって異なる尺度です (現実の写真か、VRChat の写真か、UI向けか、とか)。実際この話は画像やシチュエーションによって Bias を変えようという話にしかならないのですが、まぁ、逆に一般に使える尺度としてとりあえず Mean Squared Error で測ってみました。

こちらです。Claude Code くんが作ってくれました。正直怪しいんですが (ソース確認はしてるけどコーナーケースが多そう)、まぁ大体それっぽいのでそれっぽいということにします。

結論としては、「画像によっても勿論変わるし、画像との距離 (= 解像度) によっても変わる」です。ある決まった数値が「良い」ということはできなさそうなのですが、-0.5 ~ -0.8 あたりに最適値が出ることは確かに多い (↑ の図でもそんな感じ) ので、私は -0.65 あたりを使うかなあ…みたいな気持ちになりました。

VR で確認しているわけではないので感覚が違うというのも有り得ます。頭揺れによって位置も角度も変わります。が、それを考慮しないとしても-0.65 あたりが Fine に近い、ということになるようでした。なるほど。

VR を考慮する場合はさらにそこに時間軸方向の安定性が欲しいので、もう少し下げても (数字を増やしても) いい…のかもしれません。が、sharp に見せたいものが sharp であることは悪いことではないので、まぁ…。後は各々の調整というやつです。

いろんな画像での比較をおいておきます。各曲線の中で縦線が出てるところが最小値らしいです。だからそれらの平均的な場所が一応は最適なんじゃないの、ということになるはずです。

かなり散らばってますが、選ぶとしたら -0.6 かなあ…

これなら -0.7 あたり?

-0.6 ~ -1 くらいに散らばっています。

-0.7 + ε (ε > 0) くらいかな。

-0.6 くらいかな。

うーん、まぁ -0.65 とかかな…。

ちなみに緑とピンクは 1:2 の解像度の関係にあるので、trilinear の動き方がほぼ同一なはず。だからあんまり個別にカウントしないほうがいいですこれは。

解像度によって大きく変わっていて (変わりすぎじゃない?とも思うけど)、かつ Non-Power of 2 の処理方法でも結構違うっぽいように見えます。マジで測定が合ってるのかわかんないけど、trilinear の動き自体が変わるのでまぁそういうこともあるか…という気はする。

 

ちなみに目視だとまた結果が違っていて (そんなことある?)、つまり目視で最小 Mean Squared Error を取る Bias を調べてみると、順に: -0.85, -0.86, -0.63, -0.64, -0.7, -0.69 とかになります。

スライダーでいい感じのところを探して見つけています。

画像タイプによって変わっているようにも見えるんですが、それ以上に、カメラの解像度で変わります。体感 -0.6 ~ -0.8 の間に居るっぽくて。振動しているように見えます。

まぁ、なので、Oculus の言う -0.7 という数値はこの辺なのかな~という気持ちになりました。

正直こうなってくると VR での比較をした方が良さそうです。暇があったらやります。

まとめ

完璧な最適値みたいなのはないっぽいので、調節できるといいと思います。

余談ですが、Super Sampling していいなら (負荷を多少上げてもいいなら)、やると (理論上) 正しい結果になるので、うまく混ぜ合わせるといいのかもしれません。

追記: テキスト画像について

もともと調査を始めたきっかけは suzuki さんが「 のテクスチャの MipMap Bias を -0.7 にしたところジャギが激しかった」と言っていたのが気になったところでした。で、実際に見に行ったところ、確かにジャギが激しかったです。

なんでこんなに違うのかな、と見てみたところ、「頭を傾けて見るとジャギ感がない」ことがわかりました。

考えたところ、元画像に「細長い縦棒」「細長い横棒」が多く含まれている場合、Fine 自体が良い結果を与えないっぽい気がします。

「ピクセルに丁度乗っかると綺麗な 1px」「中途半端なところだと薄い 2px」になって、そのブレが目に見えている感じがします。これは「真値」なので、これ自体に改善できるところはなさそうです。

左の画像はもう縦線が識別できない状況になっていて、特に線の幅が変わったように見えます。

15度回転させてみると、線幅は一貫するようになりました。実際きれいに見えます。

これは15度回転させた画像を-15度回転させたやつです。根本的にどうしようもないという点は変わらずどうしようもないのですが、改善され…されてるか?本当に?

あんまり変わらない気もしてきました。もうちょっといい例をもってくるべきですね。

…うーん変わってないな、って思ったけど、これ解像度高いものを Fine でサンプリングしてるからそれはそうか。MipMap Bias での1点サンプリングにしてみます。

あー、これだと確かにちょっと「濃淡の差の出やすさ」が落ち着いたかな?、くらいの見た目になってますね (ちなみに -0.5 です)。真ん中ちょい右右下くらいの fugiat nulla あたりがわかりやすいです。改善されてると言えるとは思います。

さっきの縦線もこうなります。

そうですね。まぁ、場合によってはこういうことが改善になるかも、くらいの話題でした。おわり。