ピクセルシェーダがMip mapで適切なサイズの画像を選択する仕組み
一般論
普通に縮小すると情報が落ちる
時間をかけると綺麗に縮小できる
このような綺麗な縮小をシェーダーですることができない
テクスチャのピクセルをtex2Dでひろうとき
tex2D(_MainTex, i.uv)
ピクセルシェーダでフラグメントシェーダで隣のUVの座標が大きくジャンプしていたらどうしても荒くなる
i.uv
が大きくなる
無限平面を作ることを考える
カメラの視界に必ず入るような平面を頂点シェーダで計算したい
頂点を広げる
テクスチャ画像のuvにはワールド座標をそのまま入れる
すると繰り返される
テクスチャ画像は [0, 1]
平面で構成される
1を超えたら繰り返す(ようにできる)。折り返しを返すようになっている(repeat)
Clampならまた別になる
無限平面の端っこはなぜ綺麗に縮小されるのか?
テクスチャがインポートされたら、半分のサイズのテクスチャをあらかじめ作る
縮小すみのテクスチャが使用される
ピクセルシェーダシェーダはtex2Dをよんでいるだけなのに、mip mapのレベルをどう選択するのか?
ピクセルシェーダは必ず4ピクセル同時に実行しているので、tex2Dを計算するときに異なる4つのuvを取得できる
なのでif文をかくと隣接する方は別の分岐にしているかもしれない
「おそらく両方実行して、どちらかを選択するコードが出ている」
隣接ピクセルのuvの値との差分が取れるので、飛び具合がわかり、適切なmip mapを取れる
カメラ近くだと隣接するUVがあまり飛ばないが(テクスチャがあまり変わらない)、遠くだとかなり変わる、みたいなのを見ている??
まずUVがずれるというものがなんなのか確認したい
テクスチャ上のローカル座標だと思っている
隣接ピクセルのUVの差分は
自分に適用されるUV(0,0.1)
隣接ピクセル(1,0.2)
の差分のことだ思う
カメラから遠くなると、隣接ピクセルのUVの距離が遠くなるはず
これを見てどうにかしている(どうやってどうにかしてるのかは謎)、のだと思っている
繰り返しが気になるので対応する
単位範囲ごとにuvをずらす
繰り返しは気にならなくなったが、mip mapがちらついてしまう
正しいmip mapが引けていないのが原因
なぜ?
>tex2Dという関数は、ハードウェアにより巧妙に作られていて、同時に実行される隣接ピクセルの処理と組み合わせて動作します。ここに渡されるuvが連続していることが前提になっていて、隣接ピクセルとの微分値でmipmapが選択されるのです。
どうすればいいか?
tex2Dではなくtex2Dgradを使う
ddx, ddyで横/縦のピクセルとのUVの変化量を取ることができる
gradはuvが連続していなくても大丈夫なようだけどその説明はない

勾配な急なところはuvのエッジだということはわかる
これでuvが日連続でもわかるようになっている?
変化量を取るとエッジ抽出ができる