In the previous chapter you have seen how to create a simple scene, composed
by elementary blocks such as lights, materials, objects and cameras.
What you
miss now is a deeper knowledge of the interactions between these entities. These
interactions are provided by a sort of glue that connects all of the elements,
the most important class of the Lightflow Rendering Interface: the
scene.
前の章では、あなたは光源やマテリアル、オブジェクトやカメラのような要素をブロック化することにより合成した、単純なシーンを作成する方法を理解しました。
現在あなたに足りないものは、これらのエンティティーの間の相互作用の深い知識です。これらの相互作用は
Lightflow Rendering Interface の最も重要なクラス、シーン
の全ての要素を結ぶ一種の接着剤によって提供されています。
Here is an overview of the scene class methods with step by step explanations. If you want to use Lightflow productively you should read it carefully, because you may find some unexpected behaviours, that you will comprehend and appreciate only after some times.
ここには一歩ずつ説明していく、scene クラスメソッドの概要があります。 Lightflow を効率的に使いたければ、これを良く読むようにしましょう。なぜなら、何回か後にならなければ理解して評価することができず、思い通りの振舞いを見られないからです。
scene scene (int texturememory = 10 * 1024)Creates a scene object.
シーンオブジェクトを作成する。
texturememory はテクスチャのキャッシュに使用するメモリの量 (KB)
を決めます。テクスチャメモリを増やすほど、特にテクスチャの量が莫大である時にレンダリング時間が短くなります。
int newCamera (string type, list parameters)Creates a camera. Objects of this type simulate the functionality of real photographic cameras, and their task is to produce a two-dimensional image from a three-dimensional scene.
カメラを作成する。このタイプのオブジェクトは実際の写真用カメラの原理をシミュレートし、その働きは三次元のシーンから二次元の画像を作成することです。
これらの実体を使用する通常の方法は、下で説明する
render メソッドに渡すことによって行います。
int newImager (string type, list parameters)Creates an imager. An imager is a special output device that is used by cameras when rendering. These devices may not only be able to store the resulting image to a file, but they may also accomplish particular operations onto it. An example is the halo imager class, which simulates haloing around the visible light sources, reproducing a common lens effect.
imager を作成します。imager はレンダリング時にカメラが使う特別な
出力デバイスです。これらのデバイスは画像をファイルに記録することができるだけでなく、それに特定の操作を行っても構いません。例えば、普通のレンズの効果を再現しながら、可視光源の周囲に後光をシミュレートする
halo imager クラスです。
それぞれのカメラは一つの imager に結合されており、カメラ自身を作成する手続きである
imaherBegin の最後の呼出しによって一つになることに注意して下さい。しかしほとんどの imager は一連の効果を作成するように、他の
imager とリンクするメカニズムを提供しています。
int newInterface (string type, list parameters)Creates an interface object. Interfaces are special data containers which mantain global information relative to the scene. This type is necessary to hold all the data and the various settings that are to be used during the rendering stage, and that are not known a priori by the Lightflow Rendering Interface. This need arises by the fact that the Lightflow Rendering Interface is completely extensible and it is not based on any particular and monolithic rendering device. This implies that each extension class may have its own global data.
インターフェイスオブジェクトを作成するインターフェイスは、シーンに関係する全体的な情報を保守するデーターコンテナです。このタイプはレンダリング段階の最中に使われる全てのデータと変数設定を保持するために必要です。
インターフェイスはシーンに含まれている異なるレンダリング要素を通して渡すべきレンダリング情報を記録するために使われるでしょう。例えば、外部モジュールはレンダリング中にシーンジオメトリから得られるデータと通信する必要のある、ライトとマテリアルの新しいクラスの集合を提供することができます。この場合では、モジュールはレンダリングの前に実例を挙げたインターフェイスも提供するかもしれません。それは多分その作成時にパラメータリストを通してアクセスできる特定の設定も含むでしょう。
int newInterior (string type, list parameters)Creates an interior. Interiors are materials that evaluate the behaviour of light inside the volumetric spaces defined by solids. An example could be a gas contained into a sphere, or a suspension contained into a glass pot. Note however that interiors are a property of materials, not of geometries. That is to say that each material possesses one and only one interior evaluator. Then this property transfers to geometric objects since each object possesses a material. The mechanism to attach interiors to materials is similar to the one used to attach materials to objects: blocks of materials sharing the same interior are defined using interiorBegin and interiorEnd before and after their creation.
インテリアを作成する。インテリアは一様に定義された体積のある空間の内側のライトの振舞いを評価するマテリアルです。例えば球体の中に詰めたガスであるとか、ガラスポットの中に入れたサスペンションが可能です。インテリアはマテリアルのプロパティであり、ジオメトリのプロパティではないことに注意して下さい。これはそれぞれのマテリアルが一つだけのインテリアの評価を所有するということです。それぞれのオブジェクトがマテリアルを所有するので、この特性は幾何学的オブジェクトに移ります。マテリアルにインテリアを取り付けるメカニズムは、オブジェクトにマテリアルを取り付けることに良く似ています。同じインテリアを共有しているマテリアルのブロックは、これらを作成する前後に interiorBegin と interiorEnd を使用して定義されます。
int newLight (string type, list parameters)Creates a new light. By default lights are turned off. LightOn and LightOff should be called to change their state, that is to say to specify which materials (and interiors) they illuminate.
新しいライトを作成する。デフォルトのライトは切られています。 LightOn と LightOff はどのマテリアル (とインテリア) を照らすのかを明示する、この状態を変更するために呼び出すべきです。
int newMaterial (string type, list parameters)Creates a material. Each material defines the way light is reflected by a surface, and by the volume this surface encloses. The volumetric behavior of a material is defined by the current interior.
マテリアルを作成する。それぞれのマテリアルはサーフェイスと、このサーフェイスが囲むボリュームによって反射される光の方向を定義します。マテリアルのボリュームの振舞いは現在のインテリアによって定義されます。
マテリアルが光源からやって来るライトを反射するので、それぞれのライト
(とそれぞれのインテリア) は寄与するライトのリストを所有します。このリストはマテリアル (やインテリア)
自身の作成において点灯している全てのライトを含みます。
int newObject (string type, list parameters)Creates an object. Objects are the geometric entities that define a scene. Each object is made up of a unique material, which is the one that was current at the object's creation. For this reason objects should always be declared inside a material block.
オブジェクトを作成する。オブジェクトはシーンを定義する、ジオメトリの実体です。それぞれのオブジェクトはオブジェクトの作成において最新であった、ユニークなマテリアルから構成されています。この理由はオブジェクトがマテリアルブロックの内部で常に宣言されているはずだからです。
int newPattern (string type, list parameters)Creates a pattern. A pattern is a function that associates a value to each surface or volume element it is evaluated on. For this reason there are two distinct types of patterns: volumetric and superficial. Volumetric patterns may be used to determine a property of an interior, while the superficial ones may be used for materials.
パターンを作成する。パターンはそれが評価されるそれぞれのサーフェィスやボリューム要素の値に対応する関数です。このような訳で、パターンの種類には別々に二つあります:
容量的なものと表面的なものです。容量的なパターンはインテリアのプロパティを決めるために使われるのに対して、表面的なパターンはマテリアルのために使われるでしょう。
パターンの値には四種類あります:
数値、色、点、法線です。数値と色のパターンは数値や色のフィールドを制御するために使われるのに対し、点と法線のパターンは、通常ディスプレースとバンプマップのために使われます。
パターンは入力としてパターンの扱いを受け入れるマテリアル
(やインテリア) の全てのパラメータを制御するために使われても構いません。例えば "standard" マテリアルは色とパターンの両方を受け入れる "ka" と
"kc" と名前の付いた二つのフィールドと、浮動点小数とパターンの両方を受け入れる "kd" と名前の付いたフィールドと、パターンだけを受け入れる
"displacement" と "bump"
と名前の付いた二つのシールドを持ちます。
パターンの用途は、実際にはマテリアルとインテリアだけに限定されないことに注意して下さい:
オブジェクトやライトも同じようにパターンチャンネルを提供することができます。
int newTexture (string name)Loads a texture and returns its handle. This may be used by some patterns that perform texture mapping, even if this is not the only possible application.
テクスチャを読み込んで、そのハンドルを返す。これは唯一の可能なアプリケーションではなくても、テクスチャマッピングを行ういくつかのパターンによって使われても構いません。
対応しているファイル形式は
Lightflow texture (.lft) と (.tga) です。
テクスチャファイルは一番はじめに現在のディレクトリが、次に
LIGHRFLOWPATH 環境変数でリストアップしたディレクトリが検索されます。
int newTrimmer (string type, list parameters)Creates a trimmer. Trimmers are functions that cut away parts of a parametric surface, and thus they are commonly used by objects. For example the "NURBS" object possesses a channel named "trimmer" that accepts a trimmer handle as input, and that allows to specify which portions of the surface should be considered.
トリマを作成する。トリマはパラメータサーフェイスの部分を切り取った関数であるため、オブジェクトによって同じように使われます。例えば "NURBS" オブジェクトは入力としてトリマハンンドルを受け入れ、サーフェイスのどの部分を考慮しなければならないかを指定することができる、 "trimmer" と名前の付いたチャンネルを所有します。
void imagerBegin (int imager) / void imagerEnd (void)Define an imager block. These blocks may be nested, since these functions mantain a stack which is global to the scene. Each block defines the current imager, which is used by all the cameras that are created into it. There is no default imager, so each camera should be created into an imager block to produce a result.
イメージャーブロックを定義する。関数が全体のシーンを積み重ねて保守するので、これらのブロックは入れ子になっていても構いません。それぞれのブロックはその中に作成される全てのカメラによって使われる、現在のイメージャーを定義します。デフォルトのイメージャーは無いので、それぞれのカメラを最終的にはイメージャーブロックの中に作成すべきです。
void interiorBegin (int interior) / void interiorEnd (void)Define an interior block. These blocks may be nested, since these functions mantain a stack which is global to the scene. Each block defines the current interior, which is used by all the materials that are created into it. By default there is no interior, and materials could be created even outside of a block.
インテリアブロックを作成する。関数が全体のシーンを積み重ねて保守するので、これらのブロックは入れ子になっていても構いません。それぞれのブロックは、その中に作成される全てのマテリアルによって使われる現在のインテリアを定義します。デフォルトのインテリアは無く、ブロックの外側であってもマテリアルは作成されます。
void lightOn (int light) / void lightOff (int light)Turn on or off a light. The state of each light influences the materials and the interiors, since each material and each interior has a list of contributors that illuminate it: these contributors are the lights that were turned on at its creation. Note that an interior and the material it was associated to may possess different sets of contributors.
ライトを点灯したり消灯する。それぞれのマテリアルとそれぞれのインテリアがそれを照らす寄与のリストを持っているので、それぞれのライトの状態はマテリアルとインテリアに影響を及ぼします: これらの寄与は作成時に点灯したライトです。インテリアと関連するマテリアルはコントリビューターを所有してもよいことに注意して下さい。
void lightBegin (void) / void lightEnd (void)Define a lighting block. These blocks may be nested, since these functions mantain a stack which is global to the scene. These functions are used to store the active state of lights at a given time in order to restore it later on. This is useful when there is a fixed set of lights that illuminate all of the materials and then there is an additional set that varies from material to material. For example if our scene contains the sun and two lamps and we want the sun to illuminate everything, and each lamp to illuminate only its neighbourhood, we could do this:
ライティングブロックを定義する。関数が全体のシーンの積み重なりを保守するので、これらのブロックは入れ子になっていても構いません。これらの関数は後でリストアするために、与えられた時点でのライトのアクティブな状態を記録するために使われます。これは全てのマテリアルを照らすライトの集合を修正する時や、マテリアルからマテリアルへの様々な追加集合がある時に便利です。例えば、シーンには太陽と二つのランプがあって、太陽で全てのものを照らし、ランプで近辺のものだけを照らしたい時、このようにすることができます:
sun = s.newLight( "directional", ... ) lamp1 = s.newLight( "point", ... ) lamp2 = s.newLight( "point", ... ) s.lightOn( sun ) ... # materials of distant objects s.lightBegin() s.lightOn( lamp1 ) ... # materials of the neighbours of lamp1 s.lightEnd() ... # materials of distant objects s.lightBegin() s.lightOn( lamp2 ) ... # materials of the neighbours of lamp2 s.lightEnd() ... # materials of distant objectsObviously this is not the only method, since we could also switch on/off lamp1 and lamp2 before and after their neighbours' definition, but in scenes where the lights are many and their configuration is complex the possibility of forgetting to turn off some of them may become very high.
近辺の定義の前後で lamp1 と lamp2 のスイッチをオン/オフすることができるので、これが唯一の方法でないことは明らかなのですが、ライトがたくさんあったり、ライトを切るのを忘れてしまうくらい複雑に設定されているシーンでは、非常に明るくなり過ぎてしまうでしょう。
void materialBegin (int material) / void materialEnd (void)Define a material block. These blocks may be nested, since these functions mantain a stack which is global to the scene. Each block defines the current material, which is used by all the objects that are created into it. There is no default material, so each object should be created into a material block.
マテリアルブロックを定義する。これらの関数が全体的なシーンの積み重なりを保守するので、入れ子になっていても構いません。それぞのれのブロックはその中に作成される全てのオブジェクトによって使われる、現在のマテリアルを定義します。デフォルトのマテリアルは無いで、それぞれのブロックはマテリアルブロックの中に作成されるべきです。
void addObject (int object)Adds an object to the scene. Objects that are created but not added are not rendered.
シーンにオブジェクトを追加する。オブジェクトは作成されるが、追加しなければレンダリングされません。
void transformBegin (transform transformation) / void transformEnd (void)Defines a transformation block. These blocks may be nested to compose multiple transformations. A transformation is an affine function that moves spatial points. This set of functions comprises translations, rotations, scalings and their compositions, which are documented within the definition of the transform type. Each block defines the current transformation, which is applied to the objects, lights, materials, interiors and patterns that are created into it. Note that the current transformation is the result of the composition of all the nested transformation blocks. This composition is performed in reverse order to facilitate hierarchical modeling, that is to say that if you want to move an object at (1, 0, 0) and rotate it by 90 degrees around the y axis that passes for this point, you should state the rotation first and the translation then. Otherwise you would move the object at (1, 0, 0) and then rotate it around the origin, bringing it to (0, 0, 1), instead of changing its orientation only.
トランスフォーメーションブロックを定義する。これらのブロックは複数のトランスフォーメーションを合成するために入れ子になっていても構いません。トランスフォーメーションは空間のポイントを移動する関数と親戚関係です。この関数の集合は
transform
タイプの定義の中でドキュメント化されている、その位置の遷移、回転、拡大縮小から成り立っています。それぞれのブロックはその中に作られたオブジェクト、ライト、マテリアル、インテリア、パターンに適用される、現在のトランスフォーメーションを定義します。現在のトランスフォーメーションが全ての入れ子になったトランスフォーメーションブロックの合成の結果であることに注意して下さい。この構成は階層的モデリングを容易にするために、逆順で行われます。これを言ってみれば、オブジェクトを
(1, 0, 0) に移動して、この点で y 軸周りに 90
度回すことで回転させたいなら、最初に回転してから、次に遷移するという意味になります。もしくは、オブジェクトを (0, 0, 1)
に移動してから、その元々だけを変更する代わりに (0, 0, 1) に持って行って、元の周りで回転します。
(古典的なロボットの腕のように)
ジョイントを繋ぎ合わせたモデルにしたい時に、最初にモデリングを始めて、次にジョイントのトランスフォーメーションを与えて、それを作成して、三番目以降にもそれらの操作を繰り返してもよいので、この順番は非常に便利です。
void radiosity (void)Computes the radiosity distribution over the scene.
シーンをラジオシティで計算します。
void render (int camera, int width, int height, float startcol=0.0, float startrow=0.0, float endcol=1.0, float endrow=1.0)Renders a camera view. width and height specify the resolution of the image, while the optional parameters specify the portion of the image to be rendered. These numbers may be specified both as integers going from 0 to width for the start/end columns and from 0 to height for the start/end rows, and as fractionals going from 0 to 1: in this case they are interpreted as fractions of the relative image dimensions.
カメラの視界でレンダリングする。width と height は画像の解像度を指定し、オプションパラメータはレンダリングする画像の位置を指定します。これらの数値は整数として開始/終了列のために 0 から width まで、開始/終了行のために 0 から height まで、小数として 0 から 1 までの両方で指定されるでしょう。小数の場合では相対的な画像次元の分数として解釈されます。
Now that the review of the scene class is completed we may start to illustrate its actual behaviour by compiling some ad hoc examples. The next will show you how to create a gaseous cloud using interiors.
これで scene クラスの練習問題が終了したので、いくつかの特別な例をコンパイルすることで、その実際の振舞いを検証しもよいでしょう。次に、インテリアを使用してガスのかかった雲を作成する方法を教えましょう。
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 ) ] ) ) gas = s.newInterior( "dust", [ "kr", vector3(1.0, 0.9, 0.8), "kaf", 0.3, "density", 0.3, "sampling", 40.0, "shadow-caching", vector3(-1.2,-1.2,-1.2), vector3(1.2,1.2,1.2) ] ) s.interiorBegin( gas ) cloud = s.newMaterial( "transparent", [] ) s.interiorEnd() s.materialBegin( cloud ) s.addObject( s.newObject( "sphere", [ "radius", 1.2 ] ) ) s.materialEnd() 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", 0.5 ] ) ) s.materialEnd() saver = s.newImager( "tga-saver", [ "file", "ball3.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 )(画像の表示)
ここでの雲の効果は "transparent" マテリアルに "dust"
インテリアを組み合わせた球面を作成することで得られています。このタイプのインテリアは空気中にホコリが漂っている様子をシミュレートします。このパラメータは長い説明を必要とするので、クラスドキュメントで探して下さい。
今のところは、変換とライティングスタックの用途を強調するために、別のサンプルを見る方が良いでしょう。
from lightflowPM import * from math import * s = scene() s.lightOn( s.newLight( "point", [ "position", vector3( 4.0, -6.0, -5.0 ), "color", vector3( 200.0, 200.0, 200.0 ) ] ) ) light1 = s.newLight( "point", [ "position", vector3( -7.5, -6.0, 2.0 ), "color", vector3( 300.0, 150.0, 150.0 ) ] ) light2 = s.newLight( "point", [ "position", vector3( -2.0, 0.0, 8.0 ), "color", vector3( 150.0, 300.0, 150.0 ) ] ) light3 = s.newLight( "point", [ "position", vector3( 8.0, -6.0, 5.0 ), "color", vector3( 150.0, 150.0, 300.0 ) ] ) s.lightBegin() s.lightOn( light1 ) plastic1 = s.newMaterial( "standard", [ "ka", vector3( 0.1, 0.1, 0.1 ), "kc", vector3( 1, 1, 1 ), "kd", 0.5, "km", 0.1 ] ) s.lightEnd() s.lightBegin() s.lightOn( light2 ) plastic2 = s.newMaterial( "standard", [ "ka", vector3( 0.1, 0.1, 0.1 ), "kc", vector3( 1, 1, 1 ), "kd", 0.5, "km", 0.1 ] ) s.lightEnd() s.lightBegin() s.lightOn( light3 ) plastic3 = s.newMaterial( "standard", [ "ka", vector3( 0.1, 0.1, 0.1 ), "kc", vector3( 1, 1, 1 ), "kd", 0.5, "km", 0.1 ] ) s.lightEnd() s.transformBegin( transform().translation( vector3( -2.0, 0, 0 ) ) ) s.materialBegin( plastic1 ) s.addObject( s.newObject( "sphere", [ "radius", 1.0 ] ) ) s.materialEnd() s.transformEnd() s.materialBegin( plastic2 ) s.addObject( s.newObject( "sphere", [ "radius", 1.0 ] ) ) s.materialEnd() s.transformBegin( transform().translation( vector3( 2.0, 0, 0 ) ) ) s.materialBegin( plastic3 ) s.addObject( s.newObject( "sphere", [ "radius", 1.0 ] ) ) s.materialEnd() s.transformEnd() saver = s.newImager( "tga-saver", [ "file", "lights.tga" ] ) s.imagerBegin( saver ) camera = s.newCamera( "pinhole", [ "eye", vector3( 0, -5, 0 ), "aim", vector3( 0, 0, 0 ), "fov", atan( 0.5 / 0.75 )*2.0 ] ) s.imagerEnd() s.render( camera, 300, 300 )(画像の表示)
見ての通り、三つのボールは同じマテリアルからできているが、明らかに実世界ではモデル化することが不可能なイルミネーションでできているように見えます。
このオブジェクト
(本当にマテリアル) にライトを照射する能力は、通常 light-linking
と呼ばれており、特にアニメーション中に非常に面白い効果です。もしあなたがコンピュータグラフィックスの分野の新参者なら、脳がその形の情報を得ることによって解釈される、光を我々の目が直接知覚するので、シーンの見方が証明で最も重要であることを忘れないで下さい。この概念をはっきりさせるために、宝石という素晴らしい構造物について考えてみましょう。これは同じ強さで別々の方向から照明されています:
その結果、判別不可能なくらいになっており、そのジオメトリは全く完璧です。その外見の質を高めるために、その部分毎にコントラストを作成しなければなりません。例えば、それを隠す光を配置することによる正面以外の多方向の照明など。
Light-linking
は観察者の目を刺激してその注意を引くことによって、それ以上のものを得ることができます。この項目で、これは個々のオブジェクトの詳細に光を当てるということで、第二の照明を作るために便利です。
次の章は
Lightflow Rendering Tools の最もパワフルな実際の用途、' 違ったことをする'
ものを紹介します。
これを読む前に、他のジオメトリ、マテリアル、パターンを作成する方法を学ぶためにクラスドキュメントに相談しているなら、あなた自身のシーンのモデルにトライしてみると良いかもしれません。経験というものは、どんなマニュアルや先生によっても代用することができない、必要なステップであることを忘れないで下さい。