少しだけ詳しく水たまりプログラム説明 その4
朝起きてトイレに入ったら、トイレの壁がバケツで水をぶち撒けたように濡れていてしばらく呆然となりました(上の階からの水漏れ)、ヘリオドールです(挨拶)。
さて、そんな笑い話は置いておいて水たまり表現の解説その4です。
ここまでで色々小細工をしたわけですが、一度全てを忘れます。
そう、一番最初に試した、矩形の水面(記事1を参照)を配置してみる方法に戻ります。
このポリゴンメッシュにテクスチャーを貼り付けて描画していたわけですが、ここで冷静に考えてみると、このポリゴンメッシュを部分的に表示するための方法がもう一つあるのです。
それは各頂点のアルファを調節する方法です。
むしろなんでそれを早く思いつかなかったのかという感じですが……。よくありますよね。
例えばこんなメッシュがあったとします。
ここに水たまりを表す円を置いたと考えて……。
円の内側にある頂点を不透明に、それ以外が全て透明になるようにアルファを設定するわけです。
最初の画像で示した基本形でこれを試してみると、こんな感じのメッシュが出来上がります。
やっていることは3Dツールでの頂点カラー、頂点ペイントと同じです。
これに水面テクスチャを貼り付けると、こんな感じに。
この方法の利点は、メッシュ頂点の色を変えるだけで位置やサイズを自由に変更できる事ですね。
【補足】
動画をよく見ると、水たまりの円同士が近づいたときに円が引き寄せられているかのように微妙に変形していると思いますが、これは各頂点のアルファを決めるときにメタボールの原理を使っているからです。
float val = 0;
Vec2 pos = 調べたい頂点の座標;
for (int i=0; i<円の個数; i++) {
Vec2 d = 円[i]の座標 - pos; // 距離
float dr2 = d.x*d.x + d.y*d.y; // 距離二乗和
val += 円[i]の重み / dr2;
}
if (val >= 閾値) {
// この頂点を表示
}
ところでこれ、背景に穴をあけて、そこに合わせて水面を配置して……みたいな煩わしさはなくなったのですが、フチの部分が超劣化したJPGみたいにギザギザしてしまうという、ワリと致命的な欠陥があります。
これを滑らかにするにはメッシュを細かくするしかないのですが、全頂点の色をリアルタイムで書き換える必要があるのと、増えた頂点分の波の計算もしなくてはならないという仕組み上、処理時間がガンガン増大します。つまりどんどん重くなる。
※水面がずっと固定でサイズも変化しないならそんな必要はないのですが、ここではさらに高みを目指すということで、リアルタイムでサイズも位置も自由自在に変化できるものを目指すことにします。
あと、水面の独立性の問題(記事3を参照)も、実はあまり解決していません。
このあたりまでくると「なぜあの方法を使わないのだ?」と思う方もいると思います。
というわけで次回、ようやくピクセルシェーダーを使った方法に挑戦します。
つづく
どうでもいいおまけ
冒頭のトイレの事件はこういうことだったみたいです。
(聞いた話ですが、多分こんな感じ)
よくある普通のトイレ
トイレ使用後、何かの拍子で雑巾が落ちて穴を塞いだ(らしい)
※部屋主は気が付かずそのまま就寝
タンク内が水で満たされないので永久に水が出続ける
無限の泉!!
※実際はある程度溢れたところで止まったみたいです
そして真下の部屋の俺、朝っぱらから咽び泣く。
まあ、上の部屋の方が大変なことになっていたんだろうとは思いますが……。
みんなも気を付けようね!!マジで!!!!!