champagne_tower


シャンパンタワーを作ってみる

 スクリプト言語のようなmodelaという言語でレイトレーシングデータを生成するXi-TRACEですので、一定の規則に従ったシーンを作るのは得意です。規則的に積み重ねられたシャンパンタワーを記述してみたいと思います。


ワイングラスのモデリング

 まずは、1個のワイングラスから。昔作ったワイングラスのデータを引っ張り出してきました。中身は、以下図のような感じで、二次曲面をうまく当てはめて作っているので、プリミティブ数はそれほど多くはありません。プリミティブの増加=演算時間の増加、ですので、いかに少ないプリミティブで表現するか?も、非常に重要なファクターです。

wine

 データ中では、円錐台の手続きや一葉双曲面の手続きなどを作り、それぞれ境界体積を設定して高速化を図っています。以下図は一葉双曲面(手続き:oneshtb)の概念図です。

oneshtb

 これからワイングラスを複数並べますので、こうして作成したワイングラス1個分を手続き(procedure)として定義しておきます。
 最後に頂上からシャンパンをそそぐアニメーションにしようとしていますので、ワイングラスの手続きの中に、シャンパンの記述が入っています。


ワイングラスを積み上げる

 積み上げるワイングラスを上から見下ろすと、円形となり、以下図のような感じになります。

tower

 下に黒い輪郭で描いたワイングラスが4つ並び、その上に緑色の輪郭で描いたワイングラスが載っかります。一番上のグラスは1個ですが、2段目は4個、3段目は9個、n段目はn2個と数が増えていきます。
 頂点のワイングラス(緑色)からみると、下段の左上グラスはワイングラスの半径分、x軸、y軸方向に移動します。他のグラスは、左上グラスからワイングラスの直径分移動して配置すればOKです。規則的に配置していきましょう。実際のデータではシャンパンの量を制御するアニメーション用の記述が入っていて煩雑ですが、グラスを配置する記述だけを抜き出すと、こんな感じです。

  // n段目(n=0:頂上、0<n<towr_n :下段)
  idx=0;
  while (idx<towr_n)
  {
    var iy=0;
    while (iy<idx + 1)
    {
      var ix=0;
      while (ix<idx + 1)
      {
        wine_glass (ix - 0.5*idx)*wine_d,
           (iy - 0.5*idx)*wine_d,
           (towr_n - idx - 1)*wine_h, 0,0,1, chmp_amt;
        ix=ix + 1;
      }
      iy=iy + 1;
    }
    idx=idx + 1;
  }


 一番外側のループで積み上げる段数、その内側にx方向とy方向のループを回しています。


出来栄え

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

 Xi-TRACEデータ:champagne_tower.xitr



 薄い透明体があるので、自然なレンダリング結果を得るために最大トレース回数を多めに取りました(100回)。

  cond 0,2, 100,10,5;

 薄い透明体の中に入り込んだ光は、薄い壁の間で全反射を繰り返し、なかなか外に出てこないため、最大トレース回数を多めに設定して外に出てくるところまでトレースしてやらないと、少し不自然になります。
 さらに、下から照らす局所光線源を4つも配置してしまったので、計算時間は長めです。本当は、もう少しサブサンプリング数を大きく、分散数を大きくしたかったのですが、計算時間がかかりすぎるのでやめました……。
 ご覧に入れた5段のシャンパンタワーで、プリミティブ数は779個(見えていない境界体積も含む)でした。


home

download

gallery