パソコン・メモメモ備忘録

気の向くままパソコン関係等で気になることを書き記す。時々更新!

Shader での ddx(), ddy()

最近の GPU だと、Shader で ddx(a) や ddy(a) という関数が使える。定義的には、隣接ピクセルとの a の値の差分を返すらしい。が、実際そんなことが可能なのかどうか、アルゴリズム的に気になっていた。で、調べてみると、2x2 ピクセル毎しか値は変化しないとのこと。実際、試してみると(GeForceGTX275)、2x2 ずつ同じ値になっているのを確認できた。この 2x2 ピクセルで計算した値を、この4ピクセルのどこでも同じ値で返すようだ。ひとまず、テクスチャ座標の UV で色々確認している。他にも normal vector とか、上の a として色々使えるようだ。複雑な関数を a としていれることもできるようだが、ちゃんと動いているか未確認..

それはさておき、ひとつ気づいたのは、ポリゴン境界で値が不連続になっているように見えること。ポリゴン内はなだらかに変化するのだが(もちろん 2x2 ピクセル単位で)。仮説としては、ポリゴン内は、各値が線形に補間される。よって、隣接ピクセル間の差分は一定である。要するに、ポリゴンごとに一定値で塗りつぶされる感じ?

そこで疑問が出てくる。実際にテストしてみると、ポリゴン内でもなだらかに値が変化している。それはなぜか。透視投影変換のせいではないか。透視投影変換は非線形であり、そのせいでポリゴン内でも値が変化してしまうのではないか。ということで、平行投影でレンダリングしてテストしてみると、やはり、ポリゴン内での ddx, ddy の値は一定となった。きっと仮説はあっているのだろう。

あと、もう一つ疑問が残る。ポリゴンの境界部分である。例えば、2x2 ピクセルのブロックの、1 ピクセルしかポリゴンが覆っていない場合、どうやって計算するのだろうか。なんとなく、ポリゴンの外も線形に外挿して計算しているように思われる。つまり、GPU はかなり無駄なピクセル分も計算している、ということか。ポリゴンが多くなればなるほど、極端に言えば、ピクセル以下のマイクロポリゴンとか考え出すと、実際に描画するピクセル数の4倍とかそれ以上のピクセルを計算することになる。本当だろうか?

いやぁ、想像以上に GPU って複雑な計算をしているようだ。これで、アンチエイリアシングとかマルチサンプル処理とか考えると頭がこんがらがってしまう。

もともと、ddx,ddy の挙動に興味を持ったは、ポリゴン境界でなぜ不連続になるか、なんとか連続にする方法がないかを調べていたからなのだが、簡単には連続にはできなさそうだ。ポリゴン内で線形補間されたものではないない値(とは言え線形補間された値から求められる値)で、ポリゴン境界で少なくとも1次微分まで連続な関数を考えないといけないのか。ポリゴン面の補間曲面生成に近い話だなぁ。もう少し考えてみるか..