Away3Dはオープンソースのリアルタイム3Dエンジンだ。もともとはFlashプラットフォーム向けに開発された。そのAway3Dエンジンが「Away3D TypeScript」というJavaScriptライブラリに移植されはじめている。現在アルファリリースが公開され、先月の11月5日にビルドが改められた。この最新版のAway3D TypeScriptによる3次元表現の基礎をご説明したい。
01 Away3DのJavaScriptライブラリとクラスの読込み
Away3DのJavaScriptライブラリはつぎの5つを使う。これまでの2014年8月26日付ビルドでは3ライブラリだった(図001上)。新たなライブラリは、名前の頭が「awayjs-」で揃っている。JavaScript(JS)ファイルだけでなく、それぞれのmapも与えられているので、同じ場所に入れておく(図001下)。
- awayjs-core
- awayjs-display
- awayjs-renderergl
- awayjs-stagegl
- awayjs-methodmaterials
図001■Away3Dで用いるライブラリのファイル
2014年8月26日付
2014年11月5日付
なお、ライブラリはGitHubの「AwayJS」からダウンロードする。Away3D TypeScriptサイトの「Source Files」の欄には、本稿執筆時ではこれまでのまま、3つのライブラリと作例(「GitHub: Examples」)のリンクしかない(図2)。
図002■Away3D TypeScriptサイトの「Source Files」の欄
そして、script要素で5つのJSファイルを読込む。
<!--
<script src="lib/awayjs-core.next.min.js"></script>
<script src="lib/stagegl-core.next.min.js"></script>
<script src="lib/stagegl-extensions.next.min.js"></script>
-->
<script src="lib/awayjs-core.min.js"></script>
<script src="lib/awayjs-display.min.js"></script>
<script src="lib/awayjs-renderergl.min.js"></script>
<script src="lib/awayjs-stagegl.min.js"></script>
<script src="lib/awayjs-methodmaterials.min.js"></script>
|
これまでAway3Dのクラスは「away」から始まる長い名前空間を添えて参照した。新たなライブラリでは、require()関数でクラスの参照を得る。それを変数に与えて用いるというやり方だ。変数名はクラスと同じにするとわかりやすい。
var 変数 = require(ライブラリにおけるクラスのパス)
- var View = require("awayjs-display/lib/containers/View");
- var PrimitiveSpherePrefab = require("awayjs-display/lib/prefabs/PrimitiveSpherePrefab");
- var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
- var DefaultMaterialManager = require("awayjs-renderergl/lib/managers/DefaultMaterialManager");
- var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
|
これまでのAway3Dライブラリとの違いについて、詳しくは「Away3D TypeScriptではじめる3次元表現」第3回「ライブラリとクラスの読込みが変わった」を参照してほしい。
02 Away3Dで用意しなければならないもの
3次元表現では、3次元空間と光源、および物体の3つを用意する。
Away3Dで用意しなければならないもの
- 舞台:Viewオブジェクトで3次元空間の表示領域を定める
- 照明:光源のオブジェクトで3次元空間を照らす
- 役者:物体のひながたからインスタンスをつくって3次元空間に加える
03 Viewオブジェクトで3次元空間を定める
Viewクラスのコンストラクタには、引数としてレンダラを渡す。デフォルトのレンダラはDefaultRendererクラスでつくる。Viewオブジェクトをつくる関数(createView())はつぎのように定め、初期化の関数から呼出した(行番号は後掲コード001にもとづく)。
- var view;
- function initialize() {
- view = createView(240, 180);
- }
- function createView(width, height) {
- var defaultRenderer = new DefaultRenderer();
- var view = new View(defaultRenderer);
- view.width = width;
- view.height = height;
- return view;
- }
|
04 球体をプレハブのクラスからつくる
基本的な形状の物体は、プレハブクラスでひながたを定め、PrefabBase.getNewObject()メソッドを呼出してつくる。
new プレハブクラス.getNewObject()
球体をつくるのはPrimitiveSpherePrefabクラスで、コンストラクタの引数には半径を与える。球体の表面材質はTriangleMethodMaterialで定め、引数としてDefaultMaterialManager.getDefaultTextureメソッドでデフォルトのテクスチャをつくって与えた。素材は物体のMesh.materialプロパティに定める。
物体は、View.sceneプロパティから得られるSceneオブジェクトに、Scene.addChild()メソッドで加える。3次元空間の表示領域を描くには、必ずView.render()メソッドを呼出さなければならない。
- var sphere;
- function initialize() {
- sphere = createSphere(300);
- view.scene.addChild(sphere);
- view.render();
- view.render();
- }
- function createSphere(radius) {
- var defaultTexture = DefaultMaterialManager.getDefaultTexture();
- var material = new TriangleMethodMaterial(defaultTexture);
- var sphere = new PrimitiveSpherePrefab(radius)
- .getNewObject();
- sphere.material = material;
- return sphere;
- }
|
これで3次元空間の中に球体がつくられる(図003)。以下のコード001にJavaScriptコードをまとめた。
図003■3次元空間に球体が置かれた
コード001■3次元空間に球体をつくって加える
- var View = require("awayjs-display/lib/containers/View");
- var PrimitiveSpherePrefab = require("awayjs-display/lib/prefabs/PrimitiveSpherePrefab");
- var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
- var DefaultMaterialManager = require("awayjs-renderergl/lib/managers/DefaultMaterialManager");
- var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
- var view;
- var sphere;
- var timer;
- function initialize() {
- view = createView(240, 180);
- sphere = createSphere(300);
- view.scene.addChild(sphere);
- view.render();
- view.render();
- }
- function createView(width, height, backgroundColor) {
- var defaultRenderer = new DefaultRenderer();
- var view = new View(defaultRenderer);
- view.width = width;
- view.height = height;
- return view;
- }
- function createSphere(radius) {
- var defaultTexture = DefaultMaterialManager.getDefaultTexture();
- var material = new TriangleMethodMaterial(defaultTexture);
- var sphere = new PrimitiveSpherePrefab(radius)
- .getNewObject();
- sphere.material = material;
- return sphere;
- }
|
神と同じく「光りあれ」と光をつくる。3次元表現で使われる光源はいくつかある。その中でも基本となるのは「平行光源」(directional light)だ。太陽の光のように同じ向き(平行)に進み、距離によって強さが変わらない(図004右上)。
図004■3次元表現で使われる光源の種類
*Tcpp's fileより引用
平行光源はDirectionalLightクラスで定める。もっとも、太陽光だけでは、月のように光の当たっていない部分は暗闇になってしまう。地球上では「環境光」(ambient light)があることで、陰にも光が及ぶ。そこで、DirectionalLightオブジェクトをつくって返す関数(createDirectionalLight())は、環境光の強さを引数に受取り、DirectionalLightオブジェクトのLightBase.ambientプロパティに与えた。
光源は物体の表面素材に与える。そこで、球体をつくる関数()の引数に光源のオブジェクトを加えた。表面素材を照らす光源は、MaterialBase.lightPickerプロパティにStaticLightPickerオブジェクトで与える。StaticLightPicker()コンストラクタに渡す引数は,光源の配列だ。
- function initialize() {
- var directionalLight = createDirectionalLight(0.25);
// sphere = createSphere(300);
- sphere = createSphere(300, directionalLight);
- }
// function createSphere(radius) {
- function createSphere(radius, light) {
- material.lightPicker = new StaticLightPicker([light]);
- }
- function createDirectionalLight(ambient) {
- var light = new DirectionalLight();
- light.ambient = ambient;
- return light;
- }
|
これで、3次元空間に置かれた球体が、平行光源で照らされる(図005)。JavaScriptコードは、コード002にまとめた。
図005■球体が平行光源で照らされた
コード002■3次元空間の球体に光を当てる
- var View = require("awayjs-display/lib/containers/View");
- var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
- var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
- var PrimitiveSpherePrefab = require("awayjs-display/lib/prefabs/PrimitiveSpherePrefab");
- var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
- var DefaultMaterialManager = require("awayjs-renderergl/lib/managers/DefaultMaterialManager");
- var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
- var view;
- var sphere;
- function initialize() {
- var directionalLight = createDirectionalLight(0.25);
- view = createView(240, 180);
- sphere = createSphere(300, directionalLight);
- view.scene.addChild(sphere);
- view.render();
- view.render();
- }
- function createView(width, height) {
- var defaultRenderer = new DefaultRenderer();
- var view = new View(defaultRenderer);
- view.width = width;
- view.height = height;
- return view;
- }
- function createSphere(radius, light) {
- var defaultTexture = DefaultMaterialManager.getDefaultTexture();
- var material = new TriangleMethodMaterial(defaultTexture);
- var sphere = new PrimitiveSpherePrefab(radius)
- .getNewObject();
- sphere.material = material;
- material.lightPicker = new StaticLightPicker([light]);
- return sphere;
- }
- function createDirectionalLight(ambient) {
- var light = new DirectionalLight();
- light.ambient = ambient;
- return light;
- }
|
06 テクスチャとカメラ
物体にテクスチャを貼ると、質感が出てくる。そのサンプルコードは、前出「Away3D TypeScriptではじめる3次元表現」第3回「ライブラリとクラスの読込みが変わった」をご覧いただきたい。さらに、間もなく公開される第4回「床の追加とカメラのパン・チルト」で、平面の床を加えて、さらにインタラクティブにカメラの位置や角度を変える(サンプル001)。
サンプル001■物体にテクスチャを貼ってインタラクティブにカメラを動かす
作成者: 野中文雄
作成日: 2014年12月12日