フリーウェアでシミュレーション結果アニメーションを作る

Pov-Ray 編 2. 流体データの場合

<< Prev - Index - Next >>

6. 等値面を表示する

■ Pov-Rayには等値面を表示する機能があります。等値面の基本は次のような設定になります。

isosurface {
  function { 0.5 * x*x + y*y + z*z - 1 }
  contained_by { box {-1, 1} }
}
等値面
  関数
  関数の入っている箱のサイズ


この場合は、楕円球 (0.5x2 + y2 + z2 - 1 = 0) のうち、<-1, -1, -1> <1, 1, 1> の大きさの箱に含まれる部分が等値面として表示されます。

しかし、等値面は表面を持ったオブジェクトなので、光源を置いたり、色を決めてやらなければ見えません。

例として次のような.pov ファイルをレンダリングしてみます。

camera {
  location  <1.5, 0.5, -2.0>
  look_at   <0.0, 0.0, 0.0>
  right     x * image_width/image_height
}
light_source {
  <20, 40, -20>                  
  color rgb <1,1,1>    
}
isosurface {
  function { 0.5 * x*x + y*y + z*z - 1 }
  contained_by { box {-1, 1} }
  max_gradient 3
  texture {
    pigment { color rgb < 1, 0.8, 0.5 > }
    finish {
      ambient rgb <0.1, 0.1, 0.1>
      diffuse 0.9
      specular 0.2
    }
  }
}
カメラ
 位置
  方向
  アスペクト比

光源
  位置
  色

等値面
  関数
  関数の入っている箱のサイズ
  最大勾配(内部での計算に必要)
  テクスチャ
    色
    表面の特性
      照らされていない方向の明るさ
      光の反射
      スペキュラー




楕円球を途中で切ったようなオブジェクトが表示されました。

■ 関数の式を見てわかるように、しきい値(この場合0)よりも小さい部分が表示されています。

このように、任意の数式から等値面を作り表示することができます。


■ 複雑な形状の例として、ノイズ関数から等値面を作ることができます。
#include "functions.inc"
であらかじめ用意されている関数群をインクルードして、関数部分を
function { f_noise3d(x, y, z)-0.5 }
とすることで、左のような図を表示できます。

■ しきい値に関係して、関数部分の正負を逆にすると、反転された部分が表示されることがわかります。
function { 0.5-f_noise3d(x, y, z) }



6.1. DF3ファイルのデータから等値面を作る
■ 関数の部分を、DF3 ファイルからつくるパターンにすることでデータから等値面を作ります。
まず、DF3 ファイルを元にした関数を設定します。
ここではFUNCという名前に設定しましたが、名前は任意に設定できます。

#declare FUNC=function{
  pattern {
    density_file df3 "sample.3df"
    interpolate 1
  }
}
FUNC という名前の関数を設定
  関数のパターン
    読み込むファイル
    補間設定(線形補間)



■ 等値面の計算用の関数を FUNCを使ってあらわします。
値が0.15以上の領域を表示する場合、以下のようになります。
(実際に表示されるのは値が0以下の領域なので、濃いほうを表示するには引き算します)

isosurface {
  function { 0.15 - FUNC(x,y,z) }
  ...省略...

density_file df3 で読み込んだパターンは、<0,0,0> から <1,1,1> に配置されるので、 contained_by の設定などもそれにあわせて変えなければ位置がずれてしまいます。

下の例では、<0,0,0> から <1,1,1> に作った等値面に対し、translateとscaleを使って、原点周りへの移動とスケールの調整をしています。


camera {
  location  <1.1, -1.1, 1.2>
  look_at   <0.0, 0.0, 0.0>
  sky       <0, 0, 1>
  right     x * image_width/image_height
}
light_source {
  <20, -40, 120>                  
  color rgb <1,1,1>    
}
#declare FUNC=function{
  pattern {
    density_file df3 "sample.3df"
    interpolate 1
  }
}
isosurface {
  function { 0.15 - FUNC(x,y,z) }
  contained_by { box {0, 1} }
  max_gradient 3
  accuracy 0.0003
  texture { ...省略... }
  translate < -0.5, -0.5, -0.5 >
  scale <2, 2, 0.5>
}
カメラ
  位置
  向く方向
  z方向を上に
  アスペクト比

光源
  位置
  色

FUNC という名前の関数を設定
  関数のパターン
    読み込むファイル
    補間設定(線形補間)


等値面
  関数設定
  関数の入っている箱のサイズ
  最大勾配(内部での計算に必要)
  精度
  テクスチャ (中身は省略)
  平行移動
  スケール変換


■ このサンプルでは、良く見るとデータボックスの表面の一部に薄くノイズが載っています。
これは、パターンが周期境界条件を仮定しているので、PovRay内部で等値面を計算している際に、計算精度の関係で反対側のデータが少し漏れているためです。
対症療法的ですが、わずかにデータを拡大して、表示領域から少しはみでるようにすることで改善されます。


#declare FUNC=function{
  pattern {
    density_file df3 "sample.3df"
    interpolate 1
    scale <1.01, 1.01, 1.03>
  }
}




約1メッシュ分拡大



■ 単純に半透明なオブジェクトを複数置くことで、入れ子式に等値面を配置することもできます。

下の図は、色と透過度(rgbt)の設定を変えて2つの等値面を表示した例になります。
(rgbtによる設定の場合は、t=1が完全に透明で t=0が不透明になります。)

外側の等値面:pigment { color rgbt < 1, 1, 0.5, 0.75 > }
内側の等値面:pigment { color rgbt < 1, 0.3, 0, 0 > }

6.2. パラメータ設定の詳細

■ max_gradient (デフォルト 1.1)

しきい値をまたいだかどうかの判定の計算に使うパラメータです。値が小さいほど、大雑把に判定するので、計算時間は短くなりますが、不正確になります。
細かい構造が存在するほど大きく値をとる必要があります。
以下の画像は max_gradient をそれぞれ1.1、5、20としてレンダリングしたものです。



この様に細かい構造のあるデータでは、大きめな値にしないとまともに表示できません。

■ accurcy (デフォルト 0.001)

しきい値をまたいだかどうかの計算を打ちきる距離です。値が大きいほど計算時間は短くなりますが、不正確になります。
今回はグリッドデータで構造の細かさの上限が決まっているため、1/グリッドサイズよりやや小さめ程度がよいでしょう。
以下の画像は accuracy をそれぞれ 0.01、0.003、0.001としてレンダリングしたものです。



■ max_trace (デフォルト all_intersections)

光線が何回面を通過するまで計算するかのパラメーターです。
CSGといって、2つのオブジェクトを合体させたり、くりぬいたりする操作を併用するときに必要で、all_intersections か1以上の整数をいれます。
(というようなことがPov-Rayのヘルプ文書に書いてあるように思うのですが、それだと半透明オブジェクトにすると違いが発生しそうな気がします。しかしCSGを使わない場合では数値を変えても(レンダリング時間に違いはあっても)レンダリング結果には変化がありませんでした。何故?
とりあえずCSGを使わない場合は計算が早いので1で良いように思えます)


6.3. ボリュームと等値面
■ ボリュームレンダリングと等値面表示は同時に行うことができます。下は非常に複雑な3次元スキャンデータを元にした.DF3ファイルを、ボリュームレンダリングだけで表示したものと、等値面を組み合わせて表示したものです。



等値面で表面を持ったオブジェクトを表示することで、ボリュームレンダリングだけでは分かりにくい前後関係がよく分かります。また、ボリュームレンダリングによる光の吸収により、空気遠近法的な前後関係の表現をすることができます。

■ こうした表現は、パラメータの調性に手間がかかり、レンダリング時間も多くかかりますが、一つ二つここぞというデータに対して画像や映像を作っておくと、役に立つときもあるのではないでしょうか。

レンダリング時間に関しては、PovRay3.7、早く安定版にならないかなぁ。

<< Prev - Index - Next >>
inserted by FC2 system