This chapter tries to introduce the reader to the actual use of the Lightflow Rendering Tools. The best way to do this is by giving a tutorial and commenting it accurately.
この章は Lightflow Rendering Tools を実際に使用して読者に紹介しようとするものです。これをする最も良い方法は、チュートリアルとその正確なコメントを与えることです。
The following example is one of the simplest possible scenes that can be rendered:
a sphere in the empty space.
Now start your preferred text editor and type the following
text. When you have finished save it in a file, and then start
python from a console passing the file name as an input (for
example, if you have saved the file as example.py, just type:
python example.py).
下のサンプルはレンダリングすることができる最も簡単なシーンの一つ、何もない空間の中の球体です。
それではさっそくお気に入りのテキストエディタを起動して、下記のテキストを入力して下さい。ファイルに保存し終わったら、入力としてファイル名を渡してコンソールから Python を起動して下さい (例えば、example.py としてファイルを保存したのであれば、python example.py と入力するだけです)。
from lightflowPM import * s = scene() s.lightOn( s.newLight( "point", [ "position", vector3( 5.0, -5.0, 4.0 ), "color", vector3( 300.0, 300.0, 300.0 ) ] ) ) plastic = s.newMaterial( "standard", [ "ka", vector3( 0, 0, 0.5 ), "kc", vector3( 1, 0.5, 0.5 ), "kd", 0.5, "km", 0.1 ] ) s.materialBegin( plastic ) s.addObject( s.newObject( "sphere", [ "radius", 1.0 ] ) ) s.materialEnd() saver = s.newImager( "tga-saver", [ "file", "ball1.tga" ] ) s.imagerBegin( saver ) camera = s.newCamera( "pinhole", [ "eye", vector3( 0, -4, 0 ), "aim", vector3( 0, 0, 0 ) ] ) s.imagerEnd() s.render( camera, 300, 300 )(画像の表示)
プログラムの最初の行は scene オブジェクトを含む変数を導入しています。この行は Lightflow プログラムのメインブロックである、新しいシーンを作成します。
The second line calls the two scene methods named lightOn and newLight.二行目は lightOn と newLight と名前を付けた二つの scene メソッドを呼び出します。
newLight is the first to be executed: it specifies the construction of a new light object belonging to the scene, and it takes two arguments, a string indicating the type of light to be created, in this case a "point" light, and a list containing the parameters that will be used in the construction process. Here the parameters are "position", which specifies that the next token should be interpreted as the position of the point-light, and "color", which says that the color of the light follows. Both the position and the color are specified with a three-dimensional vector, namely vector3, that in the first case represents a point in space, while in the second represents a RGB triple. Note that this string-value pairing is a peculiarity of all the parameter lists that are passed to scene methods that start with "new", such as newLight, newObject, newMaterial, etc. This mechanism in fact provides a method to distinguish between the meaning of the different parameters. Also it allows to specify only a subset of all the possible parameters that each type accepts, while the others will mantain their default value. For example "point" lights have also a field named "shadows" that accepts a boolean value specifying if shadows are projected or not, and its default is true.newLight が最初に実行されます: これはシーンに属する新しいライトオブジェクトの構造を指定し、作成されるライトの種類を示す文字列、この場合は "point" ライトと、構成プロセスで使われるパラメータを含むリスト、の二つの引数をとります。ここでのパラメータは、隣が形ばかりの点光源の位置として解釈されるものであるとして指定する "posiion" と、ライトが放射する色を示す "color" です。位置と色の両方は三次元のベクトル、通常は vector3 で指定されます。最初の場合は空間上の点を表し、二番目は RGB の三組を表しています。この文字の値の組み合わせは newLight, newObject, newMaterial, etc のように、"new" で始まる scene メソッドに渡す全てのパラメータリストの特殊形です。このメカニズムは実際に異なるパラメータの意味を区別するための方法を提供しています。さらにこれはそれ以外がデフォルトの値を保持するのに対して、それぞれのタイプを受け入れる全ての可能なパラメータのサブセットだけを指定することができます。例えば "point" ライトはシャドウが投影されるかどうか、そのデフォルトが真であるかによって、指定しているブール値を受け入れる "shadow" と名前の付いたフィールドも持ちます。
The second method call, lightOn, is very simple: it accepts a single argument, the handle to a light source that has been created using newLight. This handle is an integer, and it could also be assigned to a variable for future uses, but we will see that here there was no need to do this. The purpose of this method is to turn on the light source that is passed to it, that otherwise would not illuminate anything. This serves because we may want a light to illuminate only some parts of the scene. Note that this on/off mechanism has not any temporal significance, since we are rendering a single image at a time: it has only a geographical meaning.二番目のメソッドコール、lightOn は非常にシンプルです: 一つの引数を受け入れ、newLight を使用して作成されている光源を扱います。このハンドルは整数で、将来の用途のために変数を割り当てることもできますが、ここではこれをする必要が無かったことが分かるでしょう。このメソッドの目的は、それに渡される光源を点灯することです。さもなければ、何も照らすことはありません。これはシーンのある部分だけを照らすライトが欲しい時にサービスします。一度に一つの画像をレンダリングしているので、このオン/オフメカニズムが全く一時的な重要性を持っていないことに注意して下さい: これは地理的な意味だけを持つのです。
次のメソッドコール、newMaterial はライトを使うためと同じ方法でマテリアルを作成するプロシージャです。最初のパラメータはタイプで、この場合、"standard" マテリアルです。次の引数は通常のパラメータリストです。これは周囲の色 "ka" と、表面色 "kc" と、拡散の量 "kd" と、スペクトルハイライトの平滑係数 "km" で合成されます。ここれには "standerd' マテリアルドキュメントで与えられている係数の詳細な説明をしませんが、よくある RenderManシェーダによって使われるものと似ていることに気付いたかもしれません。だから名前が "standard" なのです。
plastic と名前の付いた変数へマテリアルハンドルを登録した後、これはメソッド materialBegin に渡されます。このメソッドは複雑なスタック操作を行うのですが、今のところ、続いているオブジェクトが作られるものから、渡したマテリアルを現在のものとして宣言するための目的であることだけは知っておくべきです。
次の操作は二つのメソッド、addObject と newObject を含んでいます。前者が実行されるたびに後者が現れます。そのため他を説明する前にこれの説明をします。newObject はオブジェクトを作成します。これは半径 1 の球体がある、ジオメトリな実体であると言えます。以前言ったように、この球体は現在のマテリアルを継承するので、plastic で作られます。addObject はオブジェクトをレンダリングセットに配置し、シーンに追加します。この操作がなぜ自動ではないのかとあなたは尋ねるかもしれません。一瞬ではなくても、答えは簡単です: オブジェクトは使う前に合成することができます。例えば、ブール演算です。中間オブジェクトを個別に残さなければならない一方、最終結果だけが実際に集合に追加する必要があります。
materialEnd の呼び出しは以前に宣言したマテリアルブロックの終りを示します。これはつまり、ここより後に別のマテリアルを宣言しても、もはやplastic は作られないという意味です。レンダリングインターフェイスのいたるところで広範囲に使われるので、このシンプルな概念はあなたが知るべきいくつかの複雑な欠点を持っています。二つのメソッド、materialBegin と materialEnd は、前者によって開かれて後者によって閉じられるブロックです。それらのメソッドは常に一組にならなくてはなりません。つまり、materialEnd を呼び出さずに materialBegin を呼び出したり、materialBegin でブロックを開くことなく materialEnd を呼び出すことはできないということです。さらにそれらのメソッドはスタックを保守するので、マテリアルブロックは入れ子であったり破綻無きカップリングルールを提供していても構いません。この関数の例を以下に挙げます:
s.materialBegin( plastic1 ) ... # do something s.materialBegin( plastic2 ) # マテリアルのネスト ... s.materialEnd() ... s.materialEnd()
s.materialBegin( plastic ) ... s.materialEnd() ... s.materialEnd() # マテリアルの終了と一致しない
s.materialBegin( plastic ) ... # マテリアルブロックを閉じていない
次の作成するエントリは、レンダリング結果を取り扱うために使用する特定の出力デバイスを示すイメージャーです。ここの "tga-saver" は最終画像を targa ファイルに書き出して作成します。
新規ブロックをマテリアルのために紹介します: imagerBegin に渡したイメージャーは、imageEnd を呼び出すまでカメラを続けて使われる現在の一つです。
このブロックを閉じる前に、"pinhole" カメラは eye の位置と aim の位置に渡す、newCamera で構成されます。
イメージャーブロックを閉じてしまった後で、カメラと 幅-高さ の形式で画像の解像度を入力としてとる、render を呼び出すことでレンダリングを行います。
Once you have seen and comprehended the results of the first example, you are ready to modify it in order to obtain something more than a simple sphere. Try typing this:
一度最初の例の結果を見て理解してしまえば、あなたは単純な球体以上の何かを得るためにこれを変更できるようになるでしょう。これを入力してみて下さい:
from lightflowPM import * s = scene() s.lightOn( s.newLight( "point", [ "position", vector3( 5.0, -5.0, 4.0 ), "color", vector3( 300.0, 300.0, 300.0 ) ] ) ) bump = s.newPattern( "multifractal", [ "basis", "sin", "scale", 0.6, "depth", 0.2, "turbulence.omega", 0.5, 0.7, "turbulence.octaves", 6] ) plastic = s.newMaterial( "standard", [ "ka", vector3( 0, 0, 0.05 ), "kc", vector3( 1, 1, 1 ), "kd", 0.5, "km", 0.1, "displacement", bump ] ) s.materialBegin( plastic ) sphere = s.newObject( "sphere", [ "radius", 1.0 ] ) s.addObject( s.newObject( "surface-engine", [ "surfaces", sphere, "tolerance", 0.02, 0.1, 0.05 ] ) ) s.materialEnd() saver = s.newImager( "tga-saver", [ "file", "ball2.tga" ] ) s.imagerBegin( saver ) camera = s.newCamera( "pinhole", [ "eye", vector3( 0, -4, 0 ), "aim", vector3( 0, 0, 0 ) ] ) s.imagerEnd() s.render( camera, 300, 300 )画像の表示
球体が奇妙で不可思議な方法で、奇妙な形になったことに気付くでしょう。これはプラスチックマテリアルの "displacement" チャンネルで挿入されている、bump と名前の付いた "multifractal" パターンの効果によるものです。そしてジオメトリも、その種類とは独立した、generic サーフェイスの視覚化を正確に計算する実体である、"surface-engine" オブジェクトを球体に通して渡すことで変更しています。この場合では、球体のサーフェイスの実際の変形を扱うことが必要で、さもなければ、バンプマップされたかのようにフラットに見えてしまうでしょう。
Lightflow のシンプルな優雅さとパワーが何なのかを見た今、あなたは二番目の章を読むことでサーフェイスを深く掘り下げることができます。その間、必要なら、ちょっと休憩を取って、あなたの計画が将来どのようになるだろうかと思い浮かべてみて下さい。