飴屋

Flash3D/AGAL実践編 Part3

ベジェ曲線

フラグメントシェーダーを使ってベジェ曲線をひけるとのことなので、簡単そうな二次ベジェ曲線シェーダーを実装してみることにしました。
参考にしたサイトはこちら

ポリゴンでモデリングされた物体は当然のごとく角張っていて、曲線の表現が難しいので、一般的にはテセレーション工程を経てポリゴン面を細かいポリゴンに分割して数の力で滑らかさを得ます。自分もポリゴンの分割処理を考えていたのですが、当然のことながら一フレームで表示できるポリゴンの数には限度がありますので、どこかのポリゴンを増やしてきれいな絵を得れば、その歪みが別の場所に影響するというものです。ベジェ曲線で代用できるものなら、それが役立つケースもたくさんありそうです。

参考サイトの内容をかいつまんで説明すると、曲線の始点と終点と制御点の三点を頂点とする三角形を一つのポリゴンとして描画します。曲線一つにつきポリゴン一枚で済むならなかなかリーズナブルかもしれません。今回はこの三点に「3D座標」「色」の他に曲線描画用の値を二つ加えてあげます。情報が二つなのでそれぞれUとVとでも名付けましょう。

UV
始点00
制御点0.50
終点11

この情報をフラグメントシェーダーに渡すと u*u-v=0 のところがベジェ曲線となります。なので、0未満かどうかで塗りつぶすか否かを決めると曲線の内側と外側を塗り分けられます。実際に書いてみたAGALは↓こんな感じです。

//頂点シェーダー
//va0=座標、va1=色、va2=UとV、vc0=投影用行列
m44 op, va0, vc0
mov v0, va1
mov v1, va2
//フラグメントシェーダー
//v0=色、v1=UとV
mul ft0.x, v1.x, v1.x //v*v
sub ft0.x, v1.y, ft0.x //u-v*v
kil ft0.x //u-v*v > 0 なら曲線の内側(凸側)なので描画する
mov oc v0

円を描いてみる

確かFlashのオーサリングツールで円を描くと正円ではなくてベジェ曲線で円を近似した曲線をひいていたように思います。そんな感じでベジェ曲線で3D空間に円を描いてみるとことにしました。ベジェ曲線4本で近似したらあんまりきれいな円にならなかったので、Flashのオーサリングツールは6本とか8本で近似しているのかもしれませんが、細かいところは気にしないことにします。3D空間らしさを出すためにグルグル回してみました。

#swf(/images/2013/1/19/bezier.swf,500,300)

AGALでは三角関数も使えたと思うので正円もかけるんだと思いますが、sinやcosがどのくらいコストがかかるのかわからないので、簡単な四則演算で実装できるこちらの方がコストパフォーマンスに優れているかもしれませんね。

本当は球が描けないか頭を捻っていたのですが、実装を思いつかなかったので断念しました。頂点シェーダーを使って、円がずっと視点の方を向いてれば実質球になるので、場所を選べばそんな実装でもよさそうです。円に影や光沢をつける場合は、もうちょっと工夫しないとならなそうです。

Date: 2013/1/19

Flash3D