はてなブックマーク
X
Bluesky
Facebook
Pocket

VRML - 3D・立体図形作成

更新:

VRMLは「Virtual Reality Modeling Language」の略で、ウェブ上で3D(3次元)の物体(立体図形)を見られるようにする言語です。

当ページでは、VRMLノード(node)のサンプルコードをもとに様々な立体図形や空間の作成方法を解説しています。 もともと複数のページに分かれていた内容を1ページに集約しました。

VRMLは古くからあり、VRML1.0、VRML2.0、X3Dと発展しています。 ただ、あまり使い道がなく一般には普及していません。 機械設計のCADデータや3DCGソフトで作成した立体図形をウェブ上で閲覧するために、ごく一部で利用されているようです。 作成したCGは、いろいろな角度に動かして閲覧することができます。

Web3Dに関する情報は Web3D Consortium などにあります。

VRMLを見るには

VRMLは、基本的に一般的なウェブブラウザでは表示できません。 専用のソフトウェアやプラグインをインストールする必要があります。

昔はCOSMO PLAYER(SGI)が有名で、他にもCommunity Place(SONY)、VRML2.0 Viewers(Microsoft)などがありました。 現在はCortonaというソフトウェアがあり、 Cortona3D からダウンロードできます。

CortonaのVRMLサンプル画面

VRMLを作るには

VRMLファイルを作るには以下のような方法があります。

3DCGソフトで作成
3DCGソフトでCGを作り、VRMLやX3D形式でファイルを保存します。 3DCGソフトでは、VRMLやX3D形式でファイルを保存できるものがあります。
テキストエディタで作成
HTMLと同様にVRMLやX3Dもテキストエディタで作成することができます。 ただし、手作業で複雑な立体図形を作るのは大変です。

ファイルの拡張子は、VRMLが「.wrl」、X3Dが「.x3d」。

ウェブ上で公開するには、サーバーにMIME Typeを追加しなければいけない場合があります。 .htaccessに以下のように書きます。

VRMLの場合
AddType x-world/x-vrml .wrl
または
AddType model/vrml .wrl
X3Dの場合
AddType model/x3d+xml .x3d
AddType model/x3d+vrml .x3dv
AddType model/x3d+binary .x3db
AddEncoding gzip .x3dvz
AddEncoding gzip .x3dbz

作成したVRMLやX3Dをサイトで公開するには、それらをサーバーにアップロードし、それらにリンクを張るだけです。 VRMLやX3DのファイルへのリンクをクリックするとVRMLブラウザが起動し、3DCGを見ることができます。 ただし、事前にCortonaなどのプラグインをインストールしている必要があります。

リンク(Aタグ)
<a href="sample.wrl">VRMLサンプル</a>
ページに埋め込む場合(EMBEDタグ)
<embed src="sample.wrl" width="300" height="200">
<noembed>
プラグインをインストールしていない場合の表示
</noembed>

立体図形(直方体、球、円錐、円柱)

以下は、赤色の直方体を表示するサンプルコードです。

#VRML V2.0 utf8

Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 1 0 0
      }
    }
    geometry Box{
      size 1 1 1
    }
  }
}

「diffuseColor 1 0 0」は図形の色で、「diffuseColor 赤 緑 青」となっています。 指定できる数値の範囲は0~1で、間の数値は0.4など小数を使用します。 例えば黄色にしたい場合は「diffuseColor 1 1 0」とします。

「geometry Box」は直方体を指定するノード。 その他、基本の図形は直方体の他に、球、円錐、円柱があります。

図形 ノード 説明
直方体 Box{
 size 1 1 1
}
size x y z
横縦奥行きを指定。
Sphere{
 radius 1
}
radius r
球の半径を指定。
円錐 Cone{
 height 1
 bottomRadius 1
}
height h
円錐の高さを指定。
bottomRadius r
底辺の円の半径を指定。
円柱 Cylinder{
 height 1
 radius 1
}
height h
円柱の高さを指定。
radius r
底辺の円の半径を指定。

図形にテクスチャを貼る

テクスチャとは図形に画像を貼ることです。 色を指定するより岩やレンガの画像を貼った方が奇麗に見えます。 以下は、直方体にテクスチャを貼るサンプルコードです。

#VRML V2.0 utf8

Transform{
  children Shape{
    appearance Appearance{
      texture ImageTexture{
        url "../tex/stone001.gif"
      }
    }
    geometry Box{
      size 2 2 1
    }
  }
}

色を指定する場合は

material Material{
  diffuseColor 1 0 0
}

としましたが、これを

texture ImageTexture{
  url "stone001.gif"
}

と変えるだけでテクスチャを指定できます。 画像ファイルの指定はHTMLのハイパーリンクと同じ要領で、VRMLファイルから見たパスを指定します。

空間の背景色、グラデーション

以下は、空間に背景色を指定するサンプルコードです。

#VRML V2.0 utf8

Background{
  skyColor[
    0.5 0.0 1.0
  ]
}
Transform{
  children Shape{
    appearance Appearance{
      texture ImageTexture{
        url "../tex/stone028.gif"
      }
    }
    geometry Cone{
      height 3
      bottomRadius 1
    }
  }
}

背景色を指定する場合は以下を追加します。

Background{
  skyColor[
    0.5 0.0 1.0
  ]
}

色は数値で指定します。 左から順に[赤 緑 青]を表し、0~1までの数値を記述します。

また、背景色は単一色だけでなくグラデーション効果などを付けられます。 以下のサンプルでは、skyColorで色を、skyAngleで色の分割の割合を指定しています。

#VRML V2.0 utf8

Background{
  skyAngle[0.3 0.6 0.9 1.2 1.5 1.57]
  skyColor[
    0.0 0.0 0.4
    0.1 0.1 0.4
    0.1 0.1 0.5
    0.1 0.1 0.5
    0.2 0.2 0.6
    0.2 0.2 0.8
    0.8 0.8 0.9
  ]
}
Transform{
  children Shape{
    appearance Appearance{
      texture ImageTexture {
        url "../tex/stone028.gif"
      }
    }
    geometry Cone{
      height 3
      bottomRadius 1
    }
  }
}

複数の図形を配置する

空間には複数の図形を配置することができます。 以下は、赤色の直方体と青色の球を表示するサンプルコードです。

#VRML V2.0 utf8

Transform{
  translation 2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 1 0 0
      }
    }
    geometry Box{
      size 2 3 1
    }
  }
}
Transform{
  translation -2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0 0 1
      }
    }
    geometry Sphere{
      radius 1
    }
  }
}

上記「translation 2 0 0」は図形の座標を表し、「diffuseColor x y z」となっています。

図形を表すノード Transform{~} を繰り返し記述し、translationで座標、geometryで形を指定すれば、いくつでも配置できます。

図形の傾きを変える

以下は、円錐を傾けるサンプルコードです。

#VRML V2.0 utf8

Transform{
  rotation 0 0 1 1.2
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 1 0 0
      }
    }
    geometry Cone{
      height 3
      bottomRadius 1
    }
  }
}

図形の中心軸を傾けることで図形が傾きます。 上記「rotation 0 0 1 1.2」が傾きの指定で、「rotation x y z rad」となっています。 この例では、円錐をZ軸を中心に1.2ラジアン傾けています。 10度 = 0.1745rad。

空間の視点(カメラの位置)を変更

以下は、空間の視点(カメラの位置)を変更するサンプルコードです。

#VRML V2.0 utf8

Viewpoint{
  position 5 0 5
  orientation 0 1 0 0.7
  description "View1"
}
Transform{
  translation 2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 1 0 0
      }
    }
    geometry Box{
      size 2 3 1
    }
  }
}
Transform{
  translation -2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0 0 1
      }
    }
    geometry Sphere{
      radius 1
    }
  }
}

以下が視点の定義。

Viewpoint{
  position 5 0 5
  orientation 0 1 0 0.7
  description "View1"
}

「position x y z」は視点のX、Y、Z座標の位置。 「orientation x y z rad」は視点の中心軸の回転。 この例では、視点のY軸を中心に0.7ラジアン回転させています。 「description "View1"」は視点の名前で、省略可能。

視点を表すノード Viewpoint{~} を複数記述することで複数の視点を配置できます。

#VRML V2.0 utf8

Viewpoint{
  position 5 0 5
  orientation 0 1 0 0.7
  description "View1"
}
Viewpoint{
  position 0 0 5
  orientation 0 0 0 0
  description "View2"
}
Transform{
  translation 2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 1 0 0
      }
    }
    geometry Box{
      size 2 3 1
    }
  }
}
Transform{
  translation -2 0 0
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0 0 1
      }
    }
    geometry Sphere{
      radius 1
    }
  }
}

図形にリンクを張る

以下は、球をクリックするとリンク先のページへジャンプするサンプルコードです。

#VRML V2.0 utf8

Anchor{
  children[
    Transform{
      children Shape{
        appearance Appearance{
          material Material{
            diffuseColor 1 0 0
          }
        }
        geometry Sphere{
          radius 1
        }
      }
    }
  ]
url "https://www.yahoo.co.jp/"
description "Yahoo! Japan"
}

リンクの指定は以下のとおり。

Anchor{
  children[
    図形の定義
  ]
url "URLのアドレスやパス"
description "文字列(英語のみ)"
}

「url "http://www.yahoo.co.jp/"」はリンク先のURL。 「description "Yahoo! Japan"」はマウスが図形に重なったときに表示される文字。

文字を表示する

以下は、文字を表示するサンプルコードです。

#VRML V2.0 utf8

Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0.4 0.9 0.3
      }
    }
    geometry Text{
      string["Google"]
      length[3]
      fontStyle FontStyle{
        family "Comic Sans MS"
      }
    }
  }
}

string[""] は表示したい文字、length[ ] は文字の長さ。 フォント(書体)を変更する場合は family にフォントを指定します。

背景にテクスチャを貼る

以下は、背景にテクスチャを貼るサンプルコードです。 背景というのは空間(箱庭)の前後左右上下の壁です。

#VRML V2.0 utf8

Background{
  backUrl "natur007.gif"
  bottomUrl "natur007.gif"
  frontUrl "natur007.gif"
  leftUrl "natur007.gif"
  rightUrl "natur007.gif"
  topUrl "natur007.gif"
}
Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0.2 0.3 0.8
      }
    }
    geometry Cone{
      height 3
      bottomRadius 1
    }
  }
}

Background{~}の中にテクスチャを指定します。 背景の位置は、それぞれ以下のようになっています。

backUrl: 背面背景の画像
bottomUrl: 下面背景の画像
frontUrl: 前面背景の画像
leftUrl: 左面背景の画像
rightUrl: 右面背景の画像
topUrl: 上面背景の画像

背景の画像は無限遠に貼られるので近づくことはできません。

音楽・音声を再生する

以下は、空間内で音楽や音声を再生するサンプルコードです。

#VRML V2.0 utf8

Sound{
  location 0 0 0
  source AudioClip{
    url "test.mid"
    loop TRUE
  }
}
Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0.9 0.5 0.7
      }
    }
    geometry Cylinder{
      height 3
      radius 0.8
    }
  }
}

Sound{~}が音の設定形式。 「location x y z」は音源の座標位置。

AudioClipが音の再生設定。 urlは再生するファイルのパスやURLを指定します。 loopは、TRUEが繰り返し再生、FALSEが一度だけ再生。 音声ファイルは、WAVEやMIDIファイルを再生できます。 音源の位置に近づくほど音は大きくなります。

図形の回転

以下は、図形の中心軸を基準に図形を回転させるサンプルコードです。 回転というのは単に図形を傾ける(上述)のではなく、ぐるぐる回る動作のことです。

#VRML V2.0 utf8

DEF TIME TimeSensor{
  cycleInterval 3.5
  loop TRUE
}
DEF MOVE OrientationInterpolator{
  key[0 0.15 0.3 0.45 0.6 0.75 0.9 1]
  keyValue[
    0 1 0 0
    0 1 0 0.9
    0 1 0 1.8
    0 1 0 2.7
    0 1 0 3.6
    0 1 0 4.5
    0 1 0 5.4
    0 1 0 0
  ]
}
DEF BOX Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0.1 0.5 1
      }
    }
    geometry Box{
      size 1 3 1
    }
  }
}
ROUTE TIME.fraction_changed TO MOVE.set_fraction
ROUTE MOVE.value_changed TO BOX.set_rotation

この例では、Transform{~}という通常の図形のノードと異なり、DEF BOX Transform{~}となっています。 これは図形に名前を付けて定義しています。 それによりBOX(他の名前でも良い)という名前で図形を呼び出すことができます。

TimeSensorは、JavaScriptのsetTimeoutのようなもので時間(タイマー)を設定します。 「cycleInterval n」は時間の進み具合(イベントの発生間隔)。 loopは、TRUE(無限繰り返し)とFALSE(一度だけ再生)があります。

OrientationInterpolatorは、図形を回転させるノードです。 回転の動作(どのように回転するか)を定義します。 keyは、0~1までの数値を分割し、動作の回数を決めます。 多くの動きを定義する場合は、たくさん分割することになります。 keyValueは、[x y z rad]で表されていて、左から順に図形のx軸、y軸、z軸、回転角度となっています。 keyValue[0 1 0 0.5]の場合、図形のy軸を中心に0.5ラジアン回転させることを意味します。 keyの分割数とkeyValueの個数は一致させる必要があります。 この例では8個。

ROUTEは、各ノードに関連性を持たせ、あるパラメータが変化すると別のパラメータも変化するようになります。 ここでDEFで定義した内容が活かされます。 この例では、TIME、MOVE、BOXの3つのノードのグループがあります。 ROUTEを記述しないと動作しないので必ず記述します。

図形の移動

以下は、図形を空間内で自由に移動させるサンプルコードです。

#VRML V2.0 utf8

DEF TIME TimeSensor{
  cycleInterval 2
  loop TRUE
}
DEF MOVE PositionInterpolator{
  key[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]
  keyValue[
    0 0 0
    1 0 1.2
    2 0 2.4
    3 0 3.6
    4 0 4.8
    0 0 4.8
    -4 0 4.8
    -3 0 3.6
    -2 0 2.4
    -1 0 1.2
    0 0 0
  ]
}
DEF Sphere Transform{
  children Shape{
    appearance Appearance{
      material Material{
        diffuseColor 0.1 0.5 1
      }
    }
    geometry Sphere{
      radius 1
    }
  }
}
ROUTE TIME.fraction_changed TO MOVE.set_fraction
ROUTE MOVE.value_changed TO Sphere.set_translation

PositionInterpolatorは、図形に移動の動作を与えることができます。 keyは、0~1までの数値を分割し、動作の回数を決めます。 多くの動きを定義する場合は、たくさん分割することになります。 keyValueは、[x y z]で表されていて、左から順に図形のx座標、y座標、z座標となっています。

図形をクリック

以下は、図形をクリックしたら図形が動くサンプルコードです。

#VRML V2.0 utf8

DEF TIME TimeSensor{
  cycleInterval 2
}
DEF MOVE PositionInterpolator{
  key[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]
  keyValue[
    0 0 0
    1 0 1.2
    2 0 2.4
    3 0 3.6
    4 0 4.8
    0 0 4.8
    -4 0 4.8
    -3 0 3.6
    -2 0 2.4
    -1 0 1.2
    0 0 0
  ]
}
DEF Sphere Transform{
  children[
    DEF TOUCH TouchSensor{}
    Shape{
      appearance Appearance{
        material Material{
          diffuseColor 0.1 0.5 1
        }
      }
      geometry Sphere{
        radius 1
      }
    }
  ]
}
ROUTE TOUCH.touchTime TO TIME.set_startTime
ROUTE TIME.fraction_changed TO MOVE.set_fraction
ROUTE MOVE.value_changed TO Sphere.set_translation

TouchSensorは、図形をクリックしたときにアクションを発生させます。 図形の情報を記述するShape{~}と、クリックに反応するTouchSensor{}をひとつにまとめてchildren[~]で囲みます。 これにより図形はクリックに反応するようになります。 ここではTouchSensorに「TOUCH」という名前を付けました。 名前は自由に定義できます。 最後にTouchSensorとShapeを合わせたchildren[~]を図形のひとつの情報としてDEF Sphere Transform{~}というように定義します。

線を描く

以下は、空間内に線(ライン)を描くサンプルコードです。

#VRML V2.0 utf8
Transform{
  children Shape{
    geometry IndexedLineSet{
      coord Coordinate{
        point[
          1 0 0,
          0 1 0,
          -1 0 0,
          0 -2 0,
          -2 0 0,
        ]
      }
      coordIndex[
        0,1,2,-1,
        0,3,4,-1,
      ]
      color Color{
        color[
          1 0 0,
          0 1 0,
          0 0 1,
        ]
      }
      colorIndex[
        0,1,0,1,
        0,2,2,0,
      ]
    }
  }
}

point[x, y, z] により点を定義します。 次にcoordIndex[a, b, c,-1]で、どの点と点を結ぶかを指定します。 point[~]で定義した点は、上から順に0番目、1番目、・・・となっています。 a, b, c は、この点の番号を書きます。 color[r, g, b] で色(赤、緑、青)を0~1の数値(0.1や0.2など)で定義します。 次にcoordIndex[0, l, m, n]で、どの色を使うかを決めます。 color[r, g, b]で定義した色は、上から順に0番目、1番目、・・・となっています。 l, m, n は、この点の番号です。

平面を作成する

以下は、空間内に平面を作成するサンプルコードです。

#VRML V2.0 utf8

Transform{
  children Shape{
    geometry IndexedFaceSet{
      coord Coordinate{
        point[
          0 0 0,
          2 0 0,
          0 2 0,
          -2 0 0,
          0 -2 0,
          3 3 0,
        ]
      }
      coordIndex[
        0,1,5,2,-1,
      ]
      color Color{
        color[
          1 0 0,
          0 1 0,
          0 0 1,
        ]
      }
      colorIndex[
        2,0,1,0,-1,
      ]
    }
  }
}

point[x, y, z] により点を定義します。 次にcoordIndex[a, b, c, d, -1]で、どの点と点を結ぶかを指定します。 point[~]で定義した点は、上から順に0番目、1番目、・・・となっています。 a, b, c, d は、この点の番号を書きます。 color[r, g, b] で色(赤、緑、青)を0~1の数値(0.1や0.2など)で定義します。 次にcoordIndex[l, m, n, o, -1]で、どの色を使うかを決めます。 color[r, g, b]で定義した色は、上から順に0番目、1番目、・・・となっています。 l, m, n, o は、この番号です。


はてなブックマーク
X
Bluesky
Facebook
Pocket