前へ | 上へ

三章

宮殿を建てるためにレンガを結合する



概要

Here begins Lightflow.
For now you have only seen part of the standard Interface, which allows Lightflow to be an open and extensible product. What makes the difference with other renderers, however, is the default set of tools that come with this interface, that is to say the set of built-in classes.
This chapter will show you possible combinations of some of these classes (they are almost a hundred!), so do not expect to learn all about Lightflow, try to comprehend how things work instead and then you'll be able to make your projects by yourself.

ここから Lightflow が始まります。
今のところあなたは Lightflow を開いてプロダクトを拡張できる、標準的なインターフェイスの一部を理解しているに過ぎません。しかし他のレンダラーで差異となるものは、組み込みのクラスの集合である、このインターフェイスに起因するデフォルトのツールの集合です。
この章はそれらのクラス (百近くもある!) のいくつかの可能な組み合わせをあなたに見せるので、Lightflow の全てについてを学ぶことを期待しないで、代わりにどのように作業を行い、自分自身でプロジェクトを作り上げることができるのかを理解して下さい。


小さな雲

Here we will see how to combine multiple patterns together to obtain more complex constructions.

ここではより複雑な構成を得るために、複数のパターンをお互いに結合する方法を理解します。


from lightflowPM import *

s = scene()

s.lightOn( s.newLight( "directional", [ "direction", vector3( 8.0, 5.0, -6.0 ), "color", vector3( 1.0, 1.0, 1.0 ) ] ) )


cloudpattern1 = s.newPattern( "granite",
                                     [ "value",
                                       0.3, 1.0, 1.0,
                                       0.5, 0.0, 0.0,
                                       "scale", 1.0,
                                       "turbulence.omega", 0.55,
                                       "turbulence.lambda", 1.8,
                                       "turbulence.octaves", 6 ] )

# Make a granite-like volumetric pattern.
# Note the keyword "value", followed by two rows of three parameters
# each. 
# This is an example of value-gradient. A gradient is a function which 
# interpolates many values, which may be numbers, colors, or entire
# patterns and materials.
# By convention numeric gradients are called value-gradients, color ones
# are named color-gradients and so on.
# As a function a gradient associates a value to a real variable.
# You can imagine it in cartesian coordinates, putting the variable on 
# the abscissas and the associated value on the ordinates.
# Here the first expected argument is the abscissa at which the value
# of the function is specified, then the value follows. The value is
# specified both at the right and at the left of the abscissa in order
# to model discontinuities, so it is composed by two numbers.
# You can specify how many abscissas (and values) you want.
# This gradient is used to model the output of our fractal pattern,
# that we will use to describe the spatial density of the cloud.
# Here the gradient smoothly blends from the value of 1 at the point 0.3, 
# to the value of 0 at the point 0.5.
# Normally the output would be a value between 0 and 1, but we
# make it droppoff rapidly from 1 to 0 to model masses of clouds that
# are denser at their center and that disappear at their boundaries.
# 花崗岩のようなボリュームパターンを作る。
# キーワード "value" がそれぞれ三つのパラメータの二つの行によって
# 続けられていることに注意すること。
# これは value-gradient の例である。グラデーションは数値や色や全体的な
# パターンやマテリアルとなる多くの値を改変する関数である。
# 慣習的によって数値グラデーションは value-gradients と呼ばれ、
# 色グラデーションは color-gradients というように名前が付いている。
# 関数のようにグラデーションは値から実際の変数を結び付けて考える。
# 横座標の変数と縦座標の関連する値を代入した、正当な座標であると考える
# ことができる。
# ここで最初に期待している引数は、関数で指定される値の横座標であり、
# その次に value が続く。value は不連続にモデル化するために、横座標の
# 左と右の両方で指定される。そのためこの value は二つの数値によって
# 合成される。
# どのくらいの横座標 (と value)が欲しいのかを指定することができる。
# このグラデーションは、雲の空間密度を説明するために使うフラクタル
# パターンの出力をモデル化するために使われる。
# ここのグラデーションはポイント 0.3 における値 1 からポイント 0.5
# における値 0 まで滑らかにブレンドする。
# 通常、出力は 0 と 1 との間の値になるが、中心でより濃くなり、境界が
# 見えなくなる多量の雲をモデル化するため 1 から 0 へ急速に落ち込ませた。

cloudpattern2 = s.newPattern( "radial",
                                     [ "value",
                                       0.8, 1.0, 1.0,
                                       1.0, 0.0, 0.0,
                                       "scale", 1.2 ] )

# Make a radial pattern, that is to say a spherical figure that is
# dense at its center and that has zero density at its border.
# This sphere has a radius of 1.2.
# 放射上パターンを作る。これは中心で濃く、境界で濃度零である球体図形
# といえる。
# この球体は 1.2 の半径を持つ。

cloudpattern = s.newPattern( "compose",
                                    [ "patterns", cloudpattern1, cloudpattern2 ] )

# Compose the two patterns. Here the output of cloudpattern1 is used
# as the input of cloudpattern2. Since the radial pattern uses its
# input to scale its output, the result will be a sphere containing a
# granitic texture which diminishes its intensity near the border.
# 二つのパターンを合成する。ここの cloudpattern1 の出力は
# cloudpattern2 の入力として使われる、放射状パターンが出力を拡大縮小
# するためその入力を使うので、境界付近の強度を最小化する花崗岩のテクス
# チャを持つ球体になる。

cloudinterior = s.newInterior( "cloud",
                                      [ "kr", vector3(0.7, 0.85, 1.0),
                                        "kaf", vector3(0.4 * 0.5, 0.7 * 0.5, 1.0 * 0.5),
                                        "density", 1.0,
                                        "density", cloudpattern,
                                        "sampling", 20.0,
                                        "shadow-caching", vector3(-1.2,-1.2,-1.2), vector3(1.2,1.2,1.2),
                                        "density-caching", 2048, vector3(-1.2,-1.2,-1.2), vector3(1.2,1.2,1.2) ] )

# Here you should note how we described density.
# It has been specified with a single value of 1 and then with the
# pattern we modeled before. The value of 1 will be used as a input to 
# cloudpattern1, which will scale its output by this factor. In
# this case there will be no scaling, and the output will go from 1 to 
# 0, as we stated above.
# The "shadow-caching" and "density-caching" attributes specify the use of 
# two different caching mechanisms that will be used to speed-up
# computations. They both require a bounding box where to work, and
# the density cache also requires the maximum allowed memory
# occupancy, which is expressed in Kb (here 2048, i.e. 2 Mb).
# The "sampling" value specifies how many samples will be taken into a
# segment long one.

# ここでどのくらいの濃度を記述したのかに注意すべきである。
# 一つの値 1 と、パターンをモデル化する前に指定されている。値 1 はこの
# 拡大縮小率によって拡大縮小する cloudpattern1 の入力として使われて
# いる。この場合、拡大縮小はなく、出力は上ではじめたように 1 から 0 へ
# 向かう。
# "shadow-caching" と "density-caching" は、計算を高速化するために使わ
# れる二つの差分キャッシングメカニズムの特殊な用途の性質を持つ。両方が
# 束縛している作業ボックスに必要で、密度のキャッシュも Kb で表される
# メモリ占有ができる最大値 (ここでは 2048, つまり 2 MB) が必要である。
# "sampling" の値はセグメントの長いものにどのくらいのサンプルをとるの
# かを指定する。

s.interiorBegin( cloudinterior )

cloud = s.newMaterial( "transparent", [] )

s.interiorEnd()


s.materialBegin( cloud )

s.addObject( s.newObject( "sphere", [ "radius", 1.2 ] ) )

s.materialEnd()


saver = s.newImager( "tga-saver", [ "file", "cloud.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 )
(画像の表示)
海洋を眺める

In my opinion the ocean is a beautyful subject. It is fascinating, amusing, romantic and full of remembrances... but what really matters are its wonderful reflections that the common computer graphics man appreciates a lot. So, let's go.

私見ですが、海洋は美しい実験台です。魅力的で、楽しくて、ロマンチックで、想い出に満ちている... しかしどこにでもいるようなコンピュータグラフィックスの人間がおおいに鑑賞する素晴らしい映像とは実際のところは何でしょうか。さあ、やってやりましょうか。


from lightflowPM import *

s = scene()

# Specify some rendering settings. These values are used by
# all the built-in types, so they are grouped under a unique
# interface, named "default".
# いくつかのレンダリング設定を指定する。これらの値は全てのビルトイン
# タイプによって使われる。そのため "default" と名前の付いたユニークな
# インターフェイスの下でグループ化されている。
s.newInterface( "default", [ "trace-depth", 5, "lighting-depth", 3 ] )

# Make a bright, bright light to model the sun.
# 太陽を作成するために、とても明るい照明を作る。

s.lightOn( s.newLight( "point", [ "position", vector3( 0, 900, 100 ), "color", vector3( 60000.0, 60000.0, 60000.0 ) ] ) )


# Model the water waves with a fractal pattern.
# フラクタルパターンで水面の波をモデル化する。
s.transformBegin( transform().scaling( vector3( 10, 5, 5 ) ) )

waterbumps = s.newPattern( "multifractal",
    [ "basis", "sin",
      "scale", 2.0,
      "depth", 0.1,
      "turbulence.distortion", 1.0,
      "turbulence.omega", 0.1, 0.3,
      "turbulence.lambda", 2.0,
      "turbulence.octaves", 5 ] )

# the "basis" value describes the fractal basis, that here is set to
# "sin", as waves have a sinusoidal origin. 
# "scale" represents the width of the waves. This factor is then
# multiplied by the scaling transform we put before. 
# "depth" represents the depth of the waves, when used to displace a
# surface. 
# the "turbulence." keywords are turbulence parameters, that are
# explained in the "multifractal" documentation. 

# "basis" の値はフラクタルベースを記述する。ここでは、シヌソイドの起源
# を持つ波として "sin" に設定している。
# "scale" は波の幅を表す。この係数は以前代入した変形の拡大縮小によって
# 乗算される。
# "depth" は波の深さを表し、サーフェイスを置換するために使われる。
# "turbulence" キーワードは混乱度の変数で、"multifractal" ドキュメント
# で説明されている。

s.transformEnd()

# Model water with a material.
# マテリアルで水をモデル化する。
water = s.newMaterial( "physical",
    [ "fresnel", 1, 0.3, 0.0,
      "IOR", 1.33,
      "kr", vector3( 1, 1, 1 ),
      "kt", vector3( 1, 1, 1 ),
      "kd", 0.0,
      "km", 0.03,
      "shinyness", 0.5,
      "displacement", waterbumps ] )

# the choosed type is "physical", because this provides physical
# parameters, very good to model liquids, glasses and metals. 
# note the use of the waterbumps pattern as a displacement.

# 液体やガラスや金属をモデル化するのに非常に良い、物理的パラメータを
# 提供するため、選んだタイプは "physical" である。
# waterbump パターンをディスプレーメントとして使っていることに注意。


# Model the ocean fundals in a similar way.
# 良く似た方法で海洋をモデル化する。
earthbumps = s.newPattern( "multifractal",
    [ "basis", "sin",
      "scale", 10.0,
      "depth", 0.5,
      "turbulence.distortion", 1.0,
      "turbulence.omega", 0.1, 0.3,
      "turbulence.lambda", 2.0,
      "turbulence.octaves", 5 ] )

earth = s.newMaterial( "diffuse",
    [ "kr", vector3( 0.8, 0.75, 0.7 ),
      "displacement", earthbumps ] )


# Here starts the sky.
# It contains a lot of volumetric clouds, especially at the horizon,
# so it is a bit complex. 

# ここから空が始まる。
# 特に地平線で大量のボリューム雲が含まれているので、ちょっと複雑。

# Volumetric clouds are modeled with an interior and a pattern that modulates its density.
# ボリューメトリック雲はインテリアとその強度を調節するパターンでモデル化されている。
s.transformBegin( transform().scaling( vector3( 100, 100, 100 ) ) )
s.transformBegin( transform().translation( vector3( 0, 0, -0.5 ) ) )

cloudpattern = s.newPattern( "multifractal",
    [ "value",
           0.0, 1.0, 1.0,
           0.3, 0.1, 0.1,
      "scale", 1.0,
      "turbulence.distortion", 1.0,
      "turbulence.omega", 0.5, 0.8,
      "turbulence.lambda", 2.0,
      "turbulence.octaves", 3 ] )

# Make the output distribution go from 1 to 0.1 to model clouds.

# 雲をモデル化するため 1 から 0 へ出力を分配させる

s.transformEnd()
s.transformEnd()

cloudinterior = s.newInterior( "cloud",
    [ "kr", vector3( 2.0, 0.8, 0.4 ),
      "kaf", vector3( 0.6 * 0.035, 0.8 * 0.035, 0.4 * 0.035),
      "density", 1.0,
      "density", cloudpattern,
      "sampling", 0.07, 1
      "shadow-caching", vector3( -1000, -1000, -1 ), vector3( 1000, 1000, 100 ),
      "density-caching", 2048, vector3( -1000, -1000, -1 ), vector3( 1000, 1000, 100 ) ] )

# Note that our scene will have a radius of 1000 unities, and our
# camera would be at its center, so with a sampling factor of 0.07 we
# allow 70 samples per ray: an enormous quantity! This will make our
# scene render slowly, but the caches will give a help. Obviously if
# you remove these volumetric clouds the rendering will be much faster.
# Here we don't care about speed however, since we want only to
# produce a single, astonishing image...

# シーンには 1000 単位の半径があり、カメラが中央に位置していることに
# 注意すること。そのためサンプリング係数 0.7 で放射当毎に 70 サンプル
# が可能である: 膨大な量です! これはシーンの描画を遅くするが、キャッシュ
# には助かる。明らかに、ボリューム雲を取り除けばレンダリングはとても
# 高速になる。 ただ一つの仰天画像を作りたいだけなので、ここでは速度に
# ついては気にしていない。


# Now model the fundal, a blue sky made of flat clouds that will be
# wrapped on a sphere.

# 球体に回り込むフラットな雲からできる青い空のファンダルをモデル化する

skypattern1 = s.newPattern( "linear-v",
    [ "color",
          0.2, vector3( 0.8, 0.9, 1.0 ), vector3( 0.8, 0.9, 1.0 ),
	  1.0, vector3( 0.2, 0.4, 0.9 ), vector3( 0.2, 0.4, 0.9 ) ] )

s.transformBegin( transform().scaling( vector3( 80, 80, 10 ) ) )

skypattern2 = s.newPattern( "multifractal",
    [ "color",
          0.2, vector3( 0.2, 0.4, 0.9 ), vector3( 0.2, 0.4, 0.9 ),
	  1.0, vector3( 0.2, 0.3, 0.7 ), vector3( 0.2, 0.3, 0.7 ),
      "scale", 1.1,
      "turbulence.distortion", 1.0,
      "turbulence.omega", 0.5, 0.8 ] )

s.transformEnd()

skypattern = s.newPattern( "blend",
    [ "pattern", skypattern1,
      "gradient",
          0.3, skypattern1, skypattern1,
          1.0, skypattern2, skypattern2 ] )

# Note that we actually created two patterns, and we merged them
# together with a "blend".
# The first pattern is a linear gradient that will span the V
# direction of the parametric surface we will attach it to.
# In this case we will use it on a sphere, where the V direction is
# the one which connects the north and south poles (that is to say a
# line of constant U and varying V is a meridian).
# This gradient associates a color to each parallel of the sphere,
# going from bright blue near the horizon to dark blue near the
# azimuth.
# The second pattern is again a "multifractal", which we use to model
# very distant clouds. Note that we stretch it with a scaling, so that 
# the clouds will look wide and thin.
# The "blend" pattern finally blends the two. It uses the pattern
# specified with "pattern" to mix more patterns. In particular it
# defines a pattern-gradient that smoothly interpolates between
# different patterns. In this case we use the linear pattern both to
# model the distribution of the gradient and to model the gradient
# itself.
# The numeric value of the linear pattern has not been specified
# (with a value-gradient), and so it goes from 0 to 1, as default.
# Thus the "blend" will make a transition that goes from a clear
# and bright sky near the horizon (at the V value of 0.3) to a cloudy
# sky near the azimuth (at the V value of 1.0).

# 二つのパターンを実際に作成し、"blend" でお互いに結合したことに注意。
# 最初のパターンは取り付けたパラメトリックサーフェイスの V 方向に
# 広がる線形グラデーションである。
# この場合、球体でこれを使っている。V 方向のところは南北の極 (これは
# 一定の U と不定の V が子午線である線といえる) を接続したものである。
# このグラデーションは地平付近の明るい青から方向付近の暗い青まで行く
# 球体のそれぞれの並列に色を結び付ける。
# 次のパターンは非常に離れている雲をモデル化するために使う
# "multifractal" である。雲が薄く広がっているようにするため拡大縮小で
# 引き伸ばしていることに注意すること。
# "blend" パターンは最終的に二つをブレンドする。"pattern" で指定した
# パターンはもっと多くのパターンを混ぜるために使用する。個々において
# それぞれのパターン間で滑らかに改変したパターングラデーションを定義
# する。この場合では、グラデーション分配のモデル化とグラデーション自
# 身のモデル化の両方に線形パターンを使用する。
# 線形パターンの数値は (value-gradient で) 指定されることは無く、
# デフォルトでは 0 から 1 までである。
# 従って、"blend" は水平付近 (V の値は 0.3) の明るくはっきりした空から
# 天井付近 (V の値は 1.0) の曇空まで続いて推移していく。


# Create the sky material.
# 空のマテリアルの作成
s.interiorBegin( cloudinterior )

sky = s.newMaterial( "matte", 
    [ "kc", vector3( 1, 1, 1 ),
      "kc", skypattern,
      "shadowing", 0.0 ] )

s.interiorEnd()

# "matte" is a material made to create matte objects, that are not
# shaded by light, but that emit a uniform color. In this case this
# color is first set to white (1, 1, 1) and then scaled by the skypattern.
# The result will be the skypattern itself.

# "matte" はライトによって影を落とさない、マットオブジェクトを作成する
# マテリアルである。この場合、最初にこの色は白 (1, 1, 1) に設定され、
# 次に skypattern によって拡大縮小される。
# その結果、skypattern 自身となる。


# Create a water disc.
# 水ののディスクを作成
s.materialBegin( water )

s.addObject( s.newObject( "disc", [ "radius", 1000.0 ] ) )

s.materialEnd()


# Create an under-water disc made of earth.
# 水面下のディスクを作成
s.transformBegin( transform().translation( vector3( 0, 0, -10 ) ) )

s.materialBegin( earth )

s.addObject( s.newObject( "disc", [ "radius", 1000.0 ] ) )

s.materialEnd()

s.transformEnd()


# Create the sky sphere.
# 空の球体を作成
s.transformBegin( transform().scaling( vector3( 1, 1, 0.1 ) ) )

s.materialBegin( sky )

s.addObject( s.newObject( "sphere", [ "radius", 1000.0 ] ) )

s.materialEnd()

s.transformEnd()


saver = s.newImager( "tga-saver", [ "file", "ocean.tga" ] )

s.imagerBegin( saver )

camera = s.newCamera( "pinhole",
    [ "eye", vector3( 0, -8, 4 ),
      "aim", vector3( 0, 0, 4 ) ] )

s.imagerEnd()

s.render( camera, 400, 300 )
(画像の表示)

Now you have just experienced the power of flexible composition of basic blocks. The next chapter ends this tutorial by illustrating one of the main tools that will help you obtaining the best quality from your renderings. Let's go to it...

これでようやく基本的なブロックの柔軟な構成能力を理解しました。次の章はレンダリングから最高の品質を得る手助けをするメインツールの一つを例証することによってこのチュートリアルが終了します。さぁ、行きましょう。

次へ