空中に浮遊する水滴らしきものをモデリングしてみたいと思います。
空気の噴射か何かで空中に浮いている水滴が、形を変えながら変形する様子を表現したいので、その様な不確定な形状を表現できるものと言えば、ポリゴンかメタボール辺りです。ただ、このケースのメタボールは最強だと思うのですよ。
メタボール中心の濃度を1より大きく設定すると、中心から外周に向かうにつれて濃度が低くなり(0に近づく)、定義域表面で0になります。
この時、濃度が1になる点の集合を下図の様に実線、定義域表面を破線で示します。
メタボールは、他のメタボールが作り出す濃度分布をすべて足し合わせ、濃度が1に等しくなった点の集合として可視化しています。上図の様に、中心の濃度が1を超えるメタボールの場合、他のメタボールが近くに無くても、単体で実線部分の球面が可視となります。
このメタボールの周りに、今度は中心の濃度が1を超えないメタボールをランダムに配置します(下図、橙、赤、緑)。
すると、青いメタボールと他の色のメタボールの濃度が加算されることによって、複雑な曲面が形成されます。これを空中に浮遊する水滴に見立てます。
後は、周りのメタボール(橙、赤、緑)を一定方向に動かしてやると、複雑にプルプルと形を変えるように見えるはずです。
var RR=10; // 水滴の半径
var LL=32; // メタボールの移動量LL×RR
var NN=128; // 水滴を形成するメタボール数
rseed 987;
上の様に、定義域半径RRのメタボールを、縦にLL×RRの距離内に均等にNN個配置して、全てのメタボールが一定の速度で上から下に落ちるようにパラメータを設定して制御しました。
乱数は、毎回異なる乱数を発生させてしまうと、複数のCPUに分配してレイトレーシングする時、CPU毎に乱数値が異なってしまうとダメなので、乱数の種を固定(上コードでは987)しています。
その他、以下に示すメタボールの座標計算コードも、水滴らしさを醸し出すパラメータとなります。
// 水滴データ生成
varray mx:0,#(NN - 1)=0;
varray my:0,#(NN - 1)=0;
varray mz:0,#(NN - 1)=0;
varray md:0,#(NN - 1)=0;
var idx;
idx=0;
while (idx<NN)
{
mx#(idx)=rnd (RR) - RR/2;
my#(idx)=(LL - 1)*RR*idx/NN + RR;
mz#(idx)=rnd (RR) - RR/2;
md#(idx)=rnd (1) - 0.5;
// continue
idx=idx + 1;
}
最後に、水の屈折率を持った透明な属性を与えて完成です。
attr water=
{
index index_water;
refl 0.90,1,0.2;
tran 0.90,0,0;
diff 0.10,0.00;
colpix cblue;
};
ポリゴンでは、光が屈折するような透明な属性を設定できないので、メタボールで正解です。
よりリアリティを持たせるなら、水滴表面の微小な波などを表現した凹凸マッピングを貼り付けると、良かったかもしれません。
完成したデータをリンクしておきます。
Xi-TRACEデータ | water_drop.xitr |
レイトレーシングした結果を以下動画でご覧いただけます。
最初と最後のフレームでつじつまが合うようにモデリングしてあるので、15秒の繰り返しになっています。