cup_and_water


コップに水を注ぎましょう

 どこかのTVでやってました。コップの向こうに矢印が見えています。このコップに水を注いでいくと、あら不思議。矢印が反転して見えます。
 入れた水の屈折によって、レンズを通った時の様に光が曲がり、左右が反転して見えるんですね。この現象であれば、Xi-TRACEのレイトレーシングという画像生成手法が持っているモデルで再現できるはずです。
 やってみましょう。


モデリング

台と壁

 テーブルに見立てた台と、向こう側に「矢印」の張り紙を貼り付ける壁を配置します。グラフィック画面にsymbol命令で「→」の文字を書き、cmap命令でマッピングデータを作成しました。

      // 張り紙のマッピングデータを作る
      ginit   128,128,32;
      symbol   0,0, fwid,fhei, "",fhei/2, cblue, "→→";
      symbol   0,fhei/2, fwid,fhei, "",fhei/2, cred, "→→";
      cmap   hari,0,0, fwid - 1,fhei - 1, fwid,fhei;

 マッピングは、属性定義(attr命令)で設定します。

  attr wall=
  {
    diff 1.00,0.00;
    color 0.80,0.80,0.80;
    nmap hari;
    mpla 0,cup_h/2,-2.5*cup_dt, 0,0,1, 0,1,0, 100,100;
    mreg -0.5,0.5, -0.5,0.5, -0.5,-0.5;
  };

 nmap項では、先ほどcmap命令で作成したカラーマッピングデータ名を指定します。
 mpla項はマッピングの貼り付け方を指定するパラメータです。他にmcyl、msph、mdsk等の貼り付け方を選べます。中心点(0,cup_h/2,-2.5*cup_dt)、平面の法線ベクタ(0,0,1)、マッピングデータの上方向(0,1,0)を設定した後、マッピングデータを実際にどのくらいの大きさで表示するか、サイズ(<a>,<b>)=(100,100)を指定します。

mpla

 図のu,v,nは各々直交していることが期待ですが、mplaの設定で直交していない場合は、自動的に以下の式で直交するように調整されます。

  [u] = [v] * [n]
  [v] = [n] * [u]

 [x]は、三次元のxベクタを表し、*は、ベクタ積(外積)です。
 最後に、mregでマッピングデータを貼り付ける領域と、位置を調整します。mregを指定しなかった場合、マッビングデータは以下の様に張り付きます。

mreg

 mplaで指定した中心点にグラフィック画面の左下座標が位置し、mplaの最後に指定したサイズ(<a>,<b>)で張り付き、ます。さらに、マッピングデータは上下・左右に無限に繰り返して張り付きます。
 mregではまず、横(u)方向の表示範囲を、<a>で正規化した座標で指定します。本例では、<u1>=-0.5、<u2>=0.5ですので、u軸の-0.5*<a>〜0.5*<b>までの範囲にデータを貼り付けることを指定しています。今回は縦(v)方向も同じ設定です(<v1>、<v2>)。もしここで、mreg 0,0, …など、範囲に同じ数値を指定すると、デフォルト設定と同じ様に無限にマッピングデータを貼り付けます。
 最後の<pu>、<pv>は、マッピングデータの平行移動で、やはり<a>、<b>で正規化された座標を使います。この例では、<pu>=-0.5、<pv>=-0.5ですので、マッピングデータの中心が、平面マッピングの中心点に表示されるように平行移動されます。

コップと蛇口

 コップは、作者宅にあったコップでサイズを取りましたが、ビーカのような形状にいじっています。屈折率はガラスの屈折率1.6程度を使っています。
 少し面倒だったのが、蛇口。二次曲面を使って、それらしく見えるようにモデリングしてみましたが、円柱面と楕円面の組み合わせなので、おもちゃみたいなものです。属性値も、適切に金属っぽい値を入れてみましたが、レイトレーシングしてみたら、アルミみたいな感じです。普通はステンレスなどが用いられるでしょうから、これも今一つですね。

  attr 蛇口=
  {
    refl 0.40,1,0.2;
    diff 0.60,0.00;
    color 1.00,1.00,1.00;
  };

 原因は、拡散反射の設定(diff)にて、拡散反射率を60%(0.6)という値に設定し、色(color)を白にしているところでしょうか。

 水の屈折率1.33程度を使っています。コップに溜まる水と、蛇口から流れ出る水の2種類があります。
 コップに溜まる水には、cos関数を使って、波紋の凹凸データをつくり、凹凸マッピングを掛けています。真横から見ているため、ほとんどわかりませんが……。
 流れ出る水には、ランダムな凹凸データを作って、やはり凹凸マッピングを掛けています。アニメーションデータなので、mregの平行移動を使って凹凸マッピングデータを上から下へ流し、流水を表現しています。


完成

 完成したデータと動画をご覧に入れます。

  Xi-TRACEデータ:cup_and_water.xitr



 水が溜まっていくと、矢印の向きが逆に見えました。
 直接は映っていませんが、蛇口から水が出たり止まったりするときに、コックをひねっています。コックの影が回転しているのが確認できると思います。


home

download

gallery