サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

Away3D 14/11/05: スカイボックスをつくる

ID: FN1412001 Technique: HTML5 and JavaScript Library: Away3D

Skyboxクラス
継承 Skybox → DisplayObject → NamedAssetBase → EventDispatcher → Object
実装 IEntity   IMaterialOwner
ディレクトリ awayjs-display/lib/entities/Skybox
Skybox()コンストラクタ
文法 Skybox(material)
概要 Skyboxインスタンスをつくる。
引数 material − スカイボックスを描く素材のMaterialBaseオブジェクト。
SkyboxMaterialクラス
継承 SkyboxMaterial → MaterialGLBase → MaterialBase → NamedAssetBase → EventDispatcher → Object
ディレクトリ awayjs-renderergl/lib/materials/SkyboxMaterial
SkyboxMaterial()コンストラクタ
文法 SkyboxMaterial(cubeMap, smooth, repeat, mipmap)
概要 SkyboxMaterialインスタンスをつくる。
引数

cubeMap − スカイボックスに用いるCubeTextureBaseオブジェクト。

smooth − テクスチャを滑らかにするかどうかのブール値。デフォルト値はtrue

repeat − テクスチャをタイル状に並べるかどうかのブール値。デフォルト値はfalse

mipmap − テクスチャにミップマップを用いるかどうかのブール値。デフォルト値はfalse


説明

スカイボックスは、3次元空間を取り巻く背景画像のテクスチャでつくられます。6面のテクスチャで、3次元空間の物体とカメラを、箱のように囲みます(図001)。すると、カメラで周囲を見たときに、それらのテクスチャが遠景のように映るということです。

図001■スカイボックスをつくる6面のテクスチャ
  図001+y
+y: posY
   
図001-x
-x: negX
図001+z
+z: posZ
図001+x
+x: posX
図001-z
-z: negZ
  図001-y
-y: negY
   

6つのテクスチャはつぎのようなJSONファイルで、それぞれがどの面になるのかを定めます。"id"はxyz軸の正負を示す名前で、"image"にファイルのパスを与えます。そして、それらを納めた配列に"data"というプロパティ名をつけます。

{
  "data":[
     {
        "id":"posX",
        "image":x軸正のテクスチャ
     },
     {
        "id":"negX",
        "image":x軸負のテクスチャ
     },
     {
        "id":"posY",
        "image":y軸正のテクスチャ
     },
     {
        "id":"negY",
        "image":y軸負のテクスチャ
     },
     {
        "id":"posZ",
        "image":"z軸正のテクスチャ
     },
     {
        "id":"negZ",
        "image":z軸負のテクスチャ
     }
  ]
}

JASONファイルをAssetLibraryクラスで正しく読込むと、素材データとしてキューブマップのCubeTextureBaseオブジェクトが得られます。このオブジェクトをSkyboxMaterial()コンストラクタの引数に渡し、つくられたインスタンスをさらにSkybox()コンストラクタに与えれば、Skyboxインスタンスができます。

new Skybox(new SkyboxMaterial(CubeTextureBaseオブジェクト))

このSkyboxインスタンスを、Scene.addChild()メソッドで3次元空間に加えれば、スカイボックスのテクスチャが周囲を囲みます。


以下のコード001は、6面のテクスチャからスカイボックスをつくって3次元空間に定めます(図002)。そして、マウスポインタの位置に応じて、カメラの向きが水平および垂直に回ります(コード001のリンクをクリックすると、サンプルが開きます)。

図002■3次元空間につくられたスカイボックス
図2

コード001■Skyboxオブジェクトをマウスで動かすカメラで表示する
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var Vector3D = require("awayjs-core/lib/geom/Vector3D");
  3. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  4. var AssetLoaderContext = require("awayjs-core/lib/library/AssetLoaderContext");
  5. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  6. var PerspectiveProjection = require("awayjs-core/lib/projections/PerspectiveProjection");
  7. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  8. var View = require("awayjs-display/lib/containers/View");
  9. var Skybox = require("awayjs-display/lib/entities/Skybox");
  10. var SkyboxMaterial = require("awayjs-renderergl/lib/materials/SkyboxMaterial");
  11. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  12. var EffectEnvMapMethod = require("awayjs-methodmaterials/lib/methods/EffectEnvMapMethod");
  13. var view;
  14. var camera;
  15. var timer;
  16. var baseUrl = "assets/skybox/";
  17. var imageSkybox = "snow_texture.cube";
  18. var zeroVector3D = new Vector3D();
  19. var centerX = 200;
  20. var centerY = 150;
  21. var lastMouseX = centerX;
  22. var lastMouseY = centerY;
  23. var cameraZ = -600;
  24. var sencitivity = 1 / 500;
  25. function initialize() {
  26.   view = createView(centerX * 2, centerY * 2, 0xFFFF00);
  27.   setupCamera(view.camera, cameraZ, 90);
  28.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  29.   loadAssets(baseUrl, imageSkybox);
  30.   document.onmousemove = getMousePosition;
  31.   timer = new RequestAnimationFrame(render);
  32.   timer.start();
  33. }
  34. function createView(width, height, backgroundColor) {
  35.   var defaultRenderer = new DefaultRenderer();
  36.   var view = new View(defaultRenderer);
  37.   view.width = width;
  38.   view.height = height;
  39.   view.backgroundColor = backgroundColor;
  40.   return view;
  41. }
  42. function loadAssets(base, image) {
  43.   var assetLoaderContext = new AssetLoaderContext();
  44.   assetLoaderContext.dependencyBaseUrl = base;
  45.   AssetLibrary.load(new URLRequest(base + image), assetLoaderContext);
  46. }
  47. function setupCamera(camera, z, fieldOfView) {
  48.   camera.z = z;
  49.   camera.lookAt(zeroVector3D);
  50.   camera.projection = new PerspectiveProjection(fieldOfView);
  51. }
  52. function onResourceComplete(eventObject) {
  53.   var assets = eventObject.assets;
  54.   var count = assets.length;
  55.   var url = eventObject.url;
  56.   for (var i = 0; i < count; i++) {
  57.     var asset = assets[i];
  58.     switch (url) {
  59.       case (baseUrl + imageSkybox):
  60.         setupSkybox(asset);
  61.         break;
  62.     }
  63.   }
  64. }
  65. function setupSkybox(cubeTexture) {
  66.   var skybox = new Skybox(new SkyboxMaterial(cubeTexture));
  67.   view.scene.addChild(skybox);
  68. }
  69. function render(timeStamp) {
  70.   var camera = view.camera;
  71.   var transform = camera.transform;
  72.   var rotationX = camera.rotationX;
  73.   transform.position = zeroVector3D;
  74.   camera.rotationY += (lastMouseX - centerX) * sencitivity;
  75.   rotationX += (lastMouseY - centerY) * sencitivity;
  76.   if (rotationX > 30) {
  77.     rotationX = 30;
  78.   } else if (rotationX < -30) {
  79.     rotationX = -30;
  80.   }
  81.   camera.rotationX = rotationX;
  82.   transform.moveBackward(-cameraZ);
  83.   view.render();
  84. }
  85. function getMousePosition(eventObject) {
  86.   lastMouseX = eventObject.clientX;
  87.   lastMouseY = eventObject.clientY;
  88. }

6面のテクスチャファイルは、HTMLドキュメントと同じ場所のassetsフォルダの中にskyboxというフォルダでまとめました。JSONファイルもこの中にsnow_texture.cubeというファイルで納めています。

JASONファイルを読込んで、スカイボックスをつくり、3次元空間に定める処理は、つぎに抜書きしたコードで行っています。素材を読込む関数(loadAssets())は、ベースURLとJSONファイルのパスを引数に受取ります(第42行目)。そして、ベースURLはAssetLoaderContextオブジェクトのAssetLoaderContext.dependencyBaseUrlプロパティに与えて、 AssetLibrary.load()メソッドでJSONファイルを読込みます(第43〜45行目)。そして、LoaderEvent.RESOURCE_COMPLETEイベントのリスナー関数(onResourceComplete())が素材データを取出し、別に定める関数(setupSkybox())に渡してスカイボックスを3次元空間に配置しています(第52〜68行目)。

  1. var baseUrl = "assets/skybox/";
  2. var imageSkybox = "snow_texture.cube";
  1. function initialize() {
  1.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  2.   loadAssets(baseUrl, imageSkybox);
  1. }
  1. function loadAssets(base, image) {
  2.   var assetLoaderContext = new AssetLoaderContext();
  3.   assetLoaderContext.dependencyBaseUrl = base;
  4.   AssetLibrary.load(new URLRequest(base + image), assetLoaderContext);
  5. }
  1. function onResourceComplete(eventObject) {
  2.   var assets = eventObject.assets;
  3.   var count = assets.length;
  4.   var url = eventObject.url;
  5.   for (var i = 0; i < count; i++) {
  6.     var asset = assets[i];
  7.     switch (url) {
  8.       case (baseUrl + imageSkybox):
  9.         setupSkybox(asset);
  10.         break;
  11.     }
  12.   }
  13. }
  14. function setupSkybox(cubeTexture) {
  15.   var skybox = new Skybox(new SkyboxMaterial(cubeTexture));
  16.   view.scene.addChild(skybox);
  17. }


作成者: 野中文雄
作成日: 2014年12月8日


Copyright © 2001-2014 Fumio Nonaka.  All rights reserved.