情報処理 I - 第8回


1.VRMLによるコンピュータグラフィックス入門


1.1 形状データとコンピュータグラフィックス

これまでテキストデータ(文字だけからなるデータ)を用いて、通常の文書データ(テキストファイル)や電子メールのデータ(メッセージ)、それにシェルの入力データ、すなわちシェルスクリプトなんかを作ってきました。特に、シェルスクリプトが表しているものは作業の手順であり、手続き (procedure) などと呼ばれたりします。このようにコンピュータは、対象をデータで表現し、それを入力し、加工し、出力することによって目的の仕事を達成する道具です。

コンピュータで画像や図形を扱う場合も、それらをコンピュータのデータとして表現する必要があります。したがってコンピュータグラフィックスを学ぶ場合には、画像データとか図形データなどと呼ばれるものがどういった構造をもっており、何を表そうとしているのかについて理解する必要があります。そこで今回は、ものの形をデータとして表すことについて考えてみます。

とは言っても、いわゆる CG 作成ソフトウェアが扱うデータは、そのソフトウェア自身で作成するか、形状作成専用のソフトウェアで作成するのが普通です。しかし、それでは形状がコンピュータのデータとしてどのように表現されているのかが隠されてしまいます。そこで、ここではテキストエディタを使って直接形状を記述する方法を採用します。そのための素材として、VRML (Virtual Reality Modelng Language) という言語を使用します。

1.2 VRML とは

VRML はインターネット上に3次元の仮想空間を構築するための言語で、仮想空間中に配置する物体の形状や振る舞い、そしてそこをさまよい歩くあなた自身を記述します。Web ページ上で3次元形状を表示することを目的に生まれた言語ですが、現在まであまり普及しているとは言えません。しかし、ここから始まった Web3D 技術は、これからのインターネットの応用方法として、高い可能性を持つもののひとつだと考えます(またはずす可能性もあるけど)。


2.VRMLファイル


2.1 VRML ファイルの作成

簡単な VRML ファイルを作成してみましょう。

テキストエディタで VRML ファイルを作成する
% emacs data.wrl &[Enter]

VRML ファイルの拡張子は .vrml とすることもありますが、ここでは .wrl としてください。wrl は world の意味だそうです。仮想世界のデータと言うわけですね。テキストエディタが起動したら、以下の内容をタイプしてください。

#VRML V2.0 utf8[Enter]
Shape {}[Enter]

タイプできたら C-x C-s でファイルを保存してください。このとき、emacs は動かしたままにしておいてください。それでは、このファイルによって記述された世界を見てみましょう。ターミナルのウィンドウで lookat あるいは gtklookat コマンドを実行してください。

VRML ファイルを見る
% lookat data.wrl[Enter]

でも多分、開いたウィンドウは真っ黒で、何も見えないと思います。lookat コマンドを終了させるには、そのウィンドウを選択して q をタイプしてください。

VRMLファイルのヘッダ
#VRML V2.0 utf8

このファイルの1行目(#VRML V2.0 utf8)はヘッダと呼ばれ、このファイルが VRML ファイルであることを宣言します。VRML ファイルの先頭には、必ずこの1行を書きます。V2.0 は VRML の文法のバージョンを示し、utf8 は使用している文字コードを示します。

VRMLファイルの書式
#VRML V2.0 utf8
ノード
ノード
…

2行目以降にデータを記述します。Shape {} のようなものはノードと呼ばれ、これが VRML という言語の「単語」に相当します。VRML ファイルには、少なくとも1個の Shape ノードが含まれている必要があります。Shape ノードは「何か形がある」ことを示すノードです。

VRMLファイルの書式

2.2 ノードとフィールド

ノードは VRML ファイルを構成する基本単位です。VRML ファイルはいくつかのノードの集まりになっています。

ノードの書式
ノード名 {
    フィールド名 フィールド値
    フィールド名 フィールド値
    …
}

ノード名に続く { ... } 内には、そのノードを具体化する情報を記述します。この部分はフィールドと呼ばれます。以下は一つの Shape ノードだけからなる VRML ファイルですが、この Shape ノードには具体的な情報は何も記述されていません。

空の Shape ノードだけからなる VRML ファイル
#VRML V2.0 utf8
Shape {}

したがってこの VRML ファイルは、何か形があることは示されていますが、それがどんな形をしているのか、どんな色をしているのかは決まっていません。この VRML ファイルを見ても何も見えないのは、このためです。では、Shape ノードの { ... } 内に geometry フィールドを置き、そこにこの Shape ノードの「形」として Sphere ノード(球)を指定してください(# より右側に書かれたものは無視されます)。

#VRML V2.0 utf8
Shape {[Enter]
  geometry Sphere {}    # 球[Enter]
}

タイプできたら C-x C-s でファイルを保存し、もう一度 lookat あるいは gtklookat コマンドを実行してください。何か見えましたか?

VRML ファイルを見る
% lookat data.wrl[Enter]

この Sphere ノードも、大きさなどの具体的な情報が省略されています。Sphere ノードでは radius フィールドによってその球の半径を指定します。なお、VRML ファイルの改行は空白とほぼ同じに扱われるので、{ ... } 内で改行しても改行しなくても結果は変わりません。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
}

タイプできたら C-x C-s でファイルを保存し、lookat あるいは gtklookat コマンドで見てください。何か変化はあったでしょうか?多分球のサイズはさっきの2倍になったと思います。つまり、Sphere ノードにおいて radius フィールドを省略した場合は、半径1の球になります。このように値の指定を省略したときに採用される値を、デフォルト値と呼びます。

ノードの書式

フィールドの書式

この球には陰影が付いていないため、球と言ってもお月さまみたいに平たく見えてしまいます。物体が立体らしく見えるのは、物体の表面に光が当たって陰影が付くからです。陰影を表現するためには、物体表面における光の反射係数を指定する必要があります。Shape ノードには形を決める geometry フィールドのほかに、見かけを決める appearance フィールドを置くことができます。ここに Appearance ノードを置き、その material フィールドに指定する Material ノードによって光の反射係数を指定します。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {[Enter]
    material Material {}[Enter]
  }[Enter]
}

タイプできたら C-x C-s でファイルを保存し、lookat あるいは gtklookat コマンドで見てください。ちゃんと球らしく見えるでしょうか?なお、この Material ノードもフィールドが省略されているので、デフォルトの反射係数が採用されます。

Shape ノード

物体のノードです。 geometry フィールドに形状を指定します。 appearance フィールドには色などの属性情報を指定します。

Shape ノードの書式
Shape {
  geometry 形状
  appearance 見かけ
}
  1. appearance フィールドには物体の色などの見かけの情報を指定する。これには Appearance ノードを使用する。
  2. geometry フィールドに物体の形状を指定する。ここには以下のノードが指定できる。

Box(箱), Cone(円錐), Cylinder(円柱), Sphere(球), Text(文字), Extrusion(押し出し), ElevationGrid(地形等), IndexedFaceSet(ポリゴン集合), IndexedLineSet(線分集合), PointSet(点集合)

Sphere ノード

Shape ノードの geometry フィールドに指定する、球の形状のノードです。

Sphere ノードの書式
Sphere {
  radius 半径
}
  1. radius フィールドに半径を指定する。
  2. radius フィールドを省略したとき、半径は 1(デフォルト)になる。
  3. 原点は球の中心にある。

3.シェーディングとテクスチャマッピング


3.1 シェーディングモデル

コンピュータグラフィックスでは、物体の見え方も計算で求めなければなりません。物体の表面に光を当てたとき、そこがどんな色に見えるかを計算する処理を、シェーディング (shading、陰影付け) と言います。

面を単に色で塗り分けた場合 シェーディングを行った場合

また、光の方向や視点の位置、物体表面の反射特性などの条件と陰影との関係を表したものをシェーディングモデル (shading model, 陰影付けモデル)と呼びます。この代表的なものに Phong のシェーディングモデルがあります。VRML の Material ノードで指定する反射係数は、Phong のシェーディングモデルに準じたものになっています。

拡散反射と鏡面反射

Phong のシェーディングモデルでは反射光を、入射光が物体表面で鏡のように反射した鏡面反射光 (specular) と、一旦物体内に進入(屈折光)したあと物体内で散乱して再び外部に放出された拡散反射光 (diffuse) の2つの成分に分けて取り扱います。このような反射は金属以外の物質で起こります。鏡面反射光は一般にはハイライトと呼ばれ、通常は入射光の色がそのまま現れます。これに対して拡散反射光には物体の色が反映されます。つまり、拡散反射光が物体の見かけの色になります。このほか、物体表面には光源から直接届く光のほかに、壁などによる照り返しなどの間接光も届きます。間接光を正確に求めればかなりリアルな画像が得られますが、その分時間も(とても)かかります。そこで Phong のシェーディングモデルでは、間接光など光源から直接届く光以外のものをまとめて定数で表現しています。これを環境光 (ambient) と呼びます。

拡散反射光による陰影 鏡面反射光による陰影 環境光による陰影

||

Phong のモデルによる陰影

余談ですが、間接光(相互反射光)を計算して陰影を求めるには、ラジオシティ (radiosity) という手段がよく用いられます。下の右側の図(ちょっと失敗しているけど)では、相互反射によって球の色が壁に映り込むカラーブリーディングという現象が発生しています。

環境光が定数 間接光を考慮

3.2 物体色の指定

それでは、先ほど作成した球の色を変えてみましょう。色はどの色の光をどれだけ反射するかで決まります。例えば、赤い光だけ反射する物体は赤色に見えます。太陽光のような白色光はすべての色を含んでいるので反射率は色(=波長)に対する分布関数になってしまいますが、人間の目は赤、緑、青の光の3原色しか知覚できないので、この3色に対する反射係数を指定すれば任意の色を表現できます。

拡散反射係数

物体の色は拡散反射係数によって設定できます。拡散反射係数は、Material ノードの diffuseColor フィールドの順で指定します。これらは 0~1 の値をとります。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {[Enter]
      diffuseColor 1 0 0[Enter]
    }
  }
}

タイプできたら C-x C-s でファイルを保存し、lookat あるいは gtklookat コマンドで見てください。上の例では赤成分の反射係数だけ1 (100%) になっているので、球は赤色に変わったと思います。赤、緑、青以外の色は、これらを混合して得られます。例えばオレンジ色は赤色と暗い緑色を合成すれば得られますから、diffuseColor フィールドに次のように変更します。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 1 0.5 0
    }
  }
}

鏡面反射係数

それでは、次にハイライトを付けてみましょう。鏡面反射係数は、Material ノードの specularColor フィールドの順で指定します。これらも 0~1 の値をとります。ただし「拡散反射光+鏡面反射光+環境光≦入射光」という制限があるので、鏡面反射光の反射係数の分だけ拡散反射係数を下げなければ、不自然な陰影になってしまいます。また、非金属の材質ではハイライトに光源色がそのまま現れますから、鏡面反射係数の各成分を等しくしておきます。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.4 0.2 0
      specularColor 0.6 0.6 0.6[Enter]
    }
  }
}

これに対して、金属のハイライトは材質の色に近い色になります(カラーシフトと言う現象が起きるので完全には一致しません)。従って、鏡面反射光の反射係数の「赤:緑:青」の比率は、拡散反射光の反射係数の比率と(だいたい)一致させます。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.4 0.2 0
      specularColor 0.6 0.3 0
    }
  }
}

ハイライトの広がり

粗い表面ではハイライトが出ないか、淡く大きく広がります。逆に滑らかな表面では、ハイライトは鋭くはっきりと現れます。したがって、ハイライトの広がり方を制御することによって、物体表面の質感を制御することが可能になります。ハイライトの広がり具合は Material ノードの shininess フィールドに 0~1 の値で指定します。値が大きいほど輝きが鋭くなります。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.4 0.2 0
      specularColor 0.6 0.3 0
      shininess 1[Enter]
    }
  }
}
shininess の値の最大値は 0~1 のはずなんだけど、lookat だと 10 とかに設定しないとハイライトらしくなりません。

Appearance ノード

Shape ノードの appearance フィールドに指定する、物体の色などの属性情報を指定するノードです。

Appearance ノードの書式
Appearance {
  material 材質の指定
  texture 貼り付けるテクスチャの指定
  textureTransform テクスチャの張り付け位置
}
  1. material フィールドには物体の表面の材質パラメータを指定する。これには Material ノードを使用する。
  2. texture フィールドには物体表面に貼り付ける別の画像を指定する。貼り付ける画像の指定には ImageTexture ノード、MovieTexture ノード、あるいは PixelTexutre ノードを使用する。デフォルトでは何も貼り付けない。
  3. texture フィールドで指定した画像の位置やスケールを調整する座標変換を、 TextureTransform ノードで指定する。デフォルトは無変換。

Material ノード

物体表面の材質パラメータを指定します。 Appearance ノードの material フィールドで使用します。

Material ノードの書式
Material {
  ambientIntensity 環境光の反射率
  diffuseColor r g b
  specularColor r g b
  shininess 輝き
  emissiveColor r g b
  transparency 透明度
}
  1. ambientIntensity フィールドは環境光(光源からの光の当たっていない部分の明るさ)に対する反射率を指定する。これが 0 だと陰の部分が真っ暗になる。
  2. diffuseColor フィールドは拡散反射率を光の3原色(赤:r, 緑:g, 青:b、いずれも 0~1)で指定する。これが物体の色になる。
  3. specularColor フィールドには鏡面反射率を3原色(赤:r, 緑:g, 青:b、いずれも 0~1)で指定する。これは光源の光が物体表面でそのまま反射して見える部分(ハイライト)の色になる。
  4. shininess フィールドは輝き具合、すなわちハイライトの「強さ」を、 0~1 の間で指定する。この値が大きくなるにつれてハイライトが鋭くなり、輝き感が増す。
  5. emissiveColor の3つの値(赤:r, 緑:g, 青:b、いずれも 0~1)を 0 0 0 より大きくすると、この物体自体がその色で発光する。
  6. transparency フィールドは透明度を指定する。 0 で不透明になり、1 で透明になる。デフォルトは 0。

3.3 テクスチャマッピング

物体には一様な色ではなく、別の画像を貼り付けることもできます。物体の表面に画像を貼り付けて表面に模様を付けたりする処理を、テクスチャマッピングと言います。

テクスチャマッピングなし テクスチャマッピングあり

先ほどの球に、下の画像を貼り付けて見ましょう。

貼り付ける画像は URL で指定します。したがって VRML では、インターネット上にある画像を貼り付けることができます。上の画像は http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg という URL でアクセスできます。これを Appearance ノードの texture フィールドImageTexture ノードを指定し、その url フィールドに画像データの在り処を指定します。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.4 0.2 0
      specularColor 0.6 0.3 0
      shininess 1
    }
    texture ImageTexture {[Enter]
      url "http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg"[Enter]
    }[Enter]
  }
}

なお、画像を貼り付けた物体の色は画像と Material ノードで指定した色との合成になりますから、画像の色をそのまま使いたいときは Material ノードでグレー(灰色~白色)の反射係数(赤:緑:青の比が等しい)を設定してください。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.6 0.6 0.6
      specularColor 0.4 0.4 0.4
      shininess 1
    }
    texture ImageTexture {
      url "http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg"
    }
  }
}

ImageTexture ノード

テクスチャマッピングに使う画像を指定します。Appearance ノードの texture フィールドで使用します。

ImageTexture ノードの書式
ImageTexture {
  url 画像ファイルの URL
  repeatS 画像空間のS軸(横)方向の繰り返し
  repeatT 画像空間のT軸(縦)方向の繰り返し
}
  1. Appearance ノードで用いるテクスチャファイルを指定する。画像ファイルの url は、このノードを含む VRML ファイルがある場所からの相対 URL あるいは http://... からはじまる絶対 URL。画像ファイルには GIF, JPEG などが指定できる。
  2. repeatS および repeatT フィールドが TRUE なら、貼り付けるテクスチャのサイズが貼り付ける場所より小さかったときに、テクスチャを繰り返し表示する。FALSE なら繰り返さない。デフォルトは TRUE。

4.単純な形状の組み合わせによる形の表現


4.1 複数の物体

それでは次に、この世界に他の部品を追加してみましょう。円柱を追加することにします。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.6 0.6 0.6
      specularColor 0.4 0.4 0.4
      shininess 1
    }
    texture ImageTexture {
      url "http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg"
    }
  }
}
[Enter]
Shape {[Enter]
  geometry Cylinder {[Enter]
    radius 1.5[Enter]
    height 5[Enter]
  }[Enter]
  appearance Appearance {[Enter]
    material Material {[Enter]
      diffuseColor 1 1 0[Enter]
    }[Enter]
  }[Enter]
}[Enter]

Cylinder ノード

Shape ノードの geometry フィールドに指定する、円筒の形状のノードです。

Cylinder ノードの書式
Cylinder {
  radius 半径
  height 高さ
  bottom 底面の有無
  top 上面の有無
  side 側面の有無
}
  1. radius フィールドに半径を指定する。
  2. height フィールドに高さを指定する。
  3. bottom フィールドが TRUE なら底面を付ける。FALSE なら付けない。デフォルトは TRUE。
  4. top フィールドが TRUE なら上面を付ける。FALSE なら付けない。デフォルトは TRUE。
  5. side フィールドが TRUE なら側面を付ける。FALSE なら付けない。デフォルトは TRUE。

これを lookat か gtklookat で見ると、球と円柱が重なってしまっています。これは球も円柱も同じ位置に配置しているからです。

4.2 物体の移動と回転

それでは、この円柱を平行移動してみましょう。物体を移動したり回転したりするためには、Transform ノードを使用します。移動したい Shape ノードを、Transform ノードの children フィールドに指定します。また、移動する量は translation フィールドに指定します。座標値は右手系で指定します。右図において、視点は最初Z軸上の正の方向にあります。


#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.6 0.6 0.6
      specularColor 0.4 0.4 0.4
      shininess 1
    }
    texture ImageTexture {
      url "http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg"
    }
  }
}

Transform {[Enter]
  translation 0 -4 0[Enter]
  children [[Enter]
    Shape {
      geometry Cylinder {
        radius 1.5
        height 5
      }
      appearance Appearance {
        material Material {
          diffuseColor 1 1 0
        }
      }
    }
  ][Enter]
}[Enter]

children フィールドの [ ... ] の中の Shape ノードは先ほどと変更ありませんが、ノードの階層関係(この Shape ノードは Transform ノードの子供にした)がぱっと見でわかるように、インデント字下げ、行頭にスペースをあけること)しています。

Transform ノードの rotation フィールドを指定することで、物体を回転させることもできます。回転は回転軸の単位ベクトルと回転角(ラジアン)で指定します。1.5708 は約π/2(90°)です。

#VRML V2.0 utf8
Shape {
  geometry Sphere { radius 2 }    # 球
  appearance Appearance {
    material Material {
      diffuseColor 0.6 0.6 0.6
      specularColor 0.4 0.4 0.4
      shininess 1
    }
    texture ImageTexture {
      url "http://www.wakayama-u.ac.jp/~tokoi/vrml/face.jpg"
    }
  }
}

Transform {
  translation 0 -4 0
  rotation 0 0 1 1.5708[Enter]
  children [
    Shape {
      geometry Cylinder {
        radius 1.5
        height 5
      }
      appearance Appearance {
        material Material {
          diffuseColor 1 1 0
        }
      }
    }
  ]
}

Transform ノード

children フィールドに列挙したノードに対して座標変換を行うグループ化ノードです。形状を空間中に配置するのに使います。

Transform ノードの書式
Transform {
  translation x y z
  rotation x y z r
  scale x y z
  scaleOrientation x y z r
  bboxCenter 外接箱の中心
  bboxSize 外接箱サイズ
  children [ノード ノード ... ]
}
  1. children フィールドに指定した複数のノードを一つのノードにまとめ、それらに対する変換を指定する。
  2. translation フィールドには、children フィールドに指定したノードを移動する位置を指定する。
  3. rotation フィールドには、children フィールドに指定したノードの回転を指定する。 x y z には回転軸ベクトル、r には回転角を与える。
  4. scale フィールドには、children フィールドに指定したノードの、 x軸、y軸、z軸方向の拡大率を指定する。x y z > 0。
  5. scaleOrientation は、scale フィールドによる拡大縮小を行う「前」の、 children フィールドに指定したノードの回転を指定する。この回転により、任意の軸方向の拡大縮小が行える。x y z は回転軸ベクトル、 r は回転角。

5.ポリゴンによる形の表現


5.1 多面体で形を表す

球や箱のような、あらかじめ用意された単純な形状(プリミティブと呼びます)を空間中に配置して形状を表現する方法は簡単ですが、どんな形でもうまく表現できるわけではありません。物体形状を多面体で表現し、その個々の面(多角形)をデータに用いれば、どんな形でも正確に表現することができます。曲面は多面体で近似します。

下図の物体(ピラミッド型の5面体)を、VRML のデータにしてみましょう。

この形状は5つの頂点と5枚の面からなります。まず、個々の頂点の座標値を求めて、それぞれに番号を割り当てます。

頂点データ
頂点番号 x y z
0 0 4 0
1 -3 0 -3
2 -3 0 3
3 3 0 3
4 3 0 -3

次に、各面がどの頂点で構成されているかを調べます。このとき頂点の順序は非常に重要であり、面を表から見たとき、頂点は必ず左回りにとる必要があります。例えば面4(底面)を下から見上げたとして頂点を左回りにたどれば、順序は4→3→2→1になります。

面データ
面番号 頂点番号
0 0 1 2
1 0 2 3
2 0 3 4
3 0 4 1
4 4 3 2 1

これが、この多面体の形状データです。この形状を VRML で使用するには、Coordinate ノードIndexedFaceSet ノードを使います。emacs でこの形状の VRML ファイルを作成してみましょう。

テキストエディタで VRML ファイルを作成する
% emacs pyramid.wrl &[Enter]

座標データは Coordinate ノードを使って表現します。point フィールドに [ ... ] でくくって座標値を列挙します。途中で改行しても構いません。

Coordinate {[Enter]
  point [ 0 4 0  -3 0 -3  -3 0 3  3 0 3  3 0 -3 ][Enter]
}[Enter]

この Coordinate ノードを IndexedFaceSet ノードの coord フィールドに指定します。

IndexedFaceSet {[Enter]
  coord Coordinate {
    point [ 0 4 0  -3 0 -3  -3 0 3  3 0 3  3 0 -3 ]
  }
}[Enter]

面データは、IndexedFaceSet ノードの coordIndex フィールドに [ ... ] でくくって頂点番号を列挙します。こちらも途中で改行することができます。ただし、面と面のデータを区切るために -1 を置いてください。

IndexedFaceSet {
  coord Coordinate {
    point [ 0 4 0  -3 0 -3  -3 0 3  3 0 3  3 0 -3 ]
  }
  coordIndex [ 0 1 2 -1  0 2 3 -1  0 3 4 -1  0 4 1 -1  4 3 2 1 -1 ][Enter]
}

それでは、このノードの形を見てみましょう。ファイルにヘッダを付け、このノードを Shape ノードの geometry フィールドに指定します。appearance ノードも設定しましょう。

#VRML V2.0 utf8[Enter]
Shape {[Enter]
  geometry IndexedFaceSet {
    coord Coordinate {
      point [ 0 4 0  -3 0 -3  -3 0 3  3 0 3  3 0 -3 ]
    }
    coordIndex [ 0 1 2 -1  0 2 3 -1  0 3 4 -1  0 4 1 -1  4 3 2 1 -1 ]
  }
  appearance Appearance {[Enter]
    material Material {}[Enter]
  }[Enter]
}[Enter]

C-x C-s でこのファイルを保存し、lookat あるいは gtklookat コマンドで見てください。

IndexedFaceSet ノード

Shape ノードの geometry フィールドに指定する、任意の多面体形状(ポリゴン)を表現するための形状のノードです。

IndexedFaceSet ノードの書式
IndexedFaceSet {
  creaseAngle スムーズシェーディングするときの限界角
  ccw 頂点の順序が反時計回りか否か
  convex 面がすべて凸多角形か否か
  solid 閉じた形状か否か
  colorPerVertex 頂点ごとに色を与えるか否か
  normalPerVertex 頂点ごとに法線を与えるか否か
  color 各面/頂点の色
  normal 各面/頂点の法線ベクトル
  texCoord テクスチャの座標
  colorIndex 色データの指標
  normalIndex 法線ベクトルデータの指標
  texCoordIndex テクスチャ座標データの指標
  coord 頂点座標データ
  coordIndex 面データ(頂点座標データの指標)
}
  1. 隣接する面同士がなす角度が cleaseAngle フィールドの値よりも小さければ、この2つの面の間で輝度が補間されてスムーズシェーディングされる。デフォルトは0(スムーズシェーディングしない)。
  2. ccw フィールドが TRUE なら、多角形の両方ののうち、頂点の順序が反時計回り(左回り)に見える側の面を表として扱う。 FALSE なら時計回り(右回り)に見える側を表として扱う。デフォルトは TRUE。
  3. convex フィールドが TRUE なら、すべての面が凸多角形であると仮定して処理する。このとき凹多角形が含まれていると正確に表示されない場合がある。デフォルトは TRUE。
  4. solid フィールドが TRUE なら、物体を閉じた形状と仮定して処理する。開いた形状の場合に見える、視点に対して裏を向いている面は表示されない。デフォルトは TRUE。
  5. colorPerVertex フィールドが TRUE なら頂点ごとに色を指定する。 FALSE なら面ごとに色を指定する。デフォルトは TRUE。
  6. normalPerVertex フィールドが TRUE なら頂点ごとに法線ベクトルを指定する。 FALSE なら面ごとに法線ベクトルを指定する。デフォルトは TRUE。
  7. color フィールドには頂点/面に与える色を指定する。これには Color ノードを使用する。
  8. normal フィールドには頂点/面に与える法線ベクトルを指定する。これには Normal ノードを使用する。
  9. texCoord フィールドにはテクスチャの座標を指定する。これには TextureCoordinate ノードを使用する。
  10. colorIndex, normalIndex, texCoordIndex フィールドは、色/法線ベクトル/テクスチャの座標を、それぞれのデータの指標(番号)で指定する場合に用いる。同じデータが繰り返し現れるような場合は、データ量を削減できる。
  11. coord フィールドに座標データを指定する。これには Coordinate ノードを用いる。
  12. coordIndex フィールドに面データを指定する。面データは面(多角形)を構成する頂点の座標を、座標データの指標で列挙する。面と面の区切りに -1 を置く。

Coordinate ノード

IndexedFaceSet ノード、IndexedLineSet ノード、PointSet ノードの coord フィールドに指定する、頂点の座標値を指定するためのノードです。

IndexedFaceSet ノードの書式
Coordinate {
  point [ x y z x y z ... ]
}

課題


(1)下図に示す図形(三角柱)を IndexedFaceSet ノード(あるいはExtrusion ノード)を使って表現しなさい。

(2)この授業で作成した data.wrl に(1)で作成した形状のノードを追加し、それを平行移動して下図のような図形を作成してください。

上の図形の VRML ファイルを電子メールで tokoi@sys.wakayama-u.ac.jp まで送ってください。Subject: は「第8回」にしてください。

VRML の仕様の一部をVRML の概要にまとめてあります(ごめんなさい、まだ途中)ので、 よかったら参考にしてください。PDF形式の資料もあります(いろいろ間違いがあります)。これはダウンロードした後 xpdf コマンドで読んでください。ただ、これらよりも about VRML97 の方がずっと良くできています。インターネット上では他にも多くの人が情報を提供しています。 これも Yahoo Japan の VRML のリンク集から探しはじめるといいでしょう。 安藤さんのページ にも豊富なリンクがあります。また、最新情報が知りたければ、大元の Web 3D Consortiumのページをあたってみてください。