[AwayJS] ライト (1) ~DirectionalLight~

AwayJSを使って、ライトについて調べてみるよ。 :boy:

awayjs_light1

DirectionalLight を調べてみたよ。 :cake:

AwayBuilder, Prefab3D を用いて、@rect 先生 :hakase: の「note.x | [Papervision3D]ねぎ振り完了」からダウンロードさせていただいたColladaデータとテクスチャをAWD形式に変換した。 :doki:

DirectionalLight のパラメータの値を変えてみてね。 :bouzu:
ライトの向きも動かせるようにしてみたよ。 :bear:
dat.GUI を使ってみたよ。 :girl:

Main.ts
/// <reference path="libs/awayjs-core/build/awayjs-core.d.ts" />
/// <reference path="libs/awayjs-stagegl/build/awayjs-stagegl.d.ts" />
/// <reference path="libs/awayjs-renderergl/build/awayjs-renderergl.d.ts" />
/// <reference path="libs/awayjs-display/build/awayjs-display.d.ts" />
/// <reference path="libs/awayjs-methodmaterials/build/awayjs-methodmaterials.d.ts" />
/// <reference path="libs/awayjs-parsers/build/awayjs-parsers.d.ts" />
/// <reference path="libs/createjs/tweenjs.d.ts" />
/// <reference path="../../libs/dat-gui.d.ts" />


import ContextGLProfile = require("awayjs-stagegl/lib/base/ContextGLProfile");
import DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
import View = require("awayjs-display/lib/containers/View");
import Scene = require("awayjs-display/lib/containers/Scene");
import Camera = require("awayjs-display/lib/entities/Camera");
import DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
import StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
import Vector3D = require("awayjs-core/lib/geom/Vector3D");
import RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
import DisplayObjectContainer = require("awayjs-display/lib/containers/DisplayObjectContainer");
import Mesh = require("awayjs-display/lib/entities/Mesh");
import PrimitivePlanePrefab = require("awayjs-display/lib/prefabs/PrimitivePlanePrefab");
import TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
//import ShadowSoftMethod = require("awayjs-methodmaterials/lib/methods/ShadowSoftMethod");
import ShadowHardMethod = require("awayjs-methodmaterials/lib/methods/ShadowHardMethod");
import AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
import LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
import AssetEvent = require("awayjs-core/lib/events/AssetEvent");
import URLRequest = require("awayjs-core/lib/net/URLRequest");
import IAsset = require("awayjs-core/lib/library/IAsset");
import AssetType = require("awayjs-core/lib/library/AssetType");
import AWDParser = require("awayjs-parsers/lib/AWDParser");

class Main {

  private renderer:DefaultRenderer;
  private view:View;
  private scene:Scene;
  private camera:Camera;
  private timer:RequestAnimationFrame;
  private light:DirectionalLight;
  private negimiku:DisplayObjectContainer;
  private hand:DisplayObjectContainer;
  private arm:Mesh;
  private negi:Mesh;
  private plane:Mesh;
  private materials:Array<TriangleMethodMaterial>;
  private radius:number = 500;
  private angle:number = - 90;
  private degree:number = 0;
  private depression:number = 30;
  private radian:number = Math.PI/180;
  private center:Vector3D = new Vector3D();
  private dataPath:string = "assets/negimiku.awd";
  private gui:dat.GUI;

  constructor() {
    this.renderer = new DefaultRenderer(false, ContextGLProfile.BASELINE);
    this.renderer.antiAlias = 4;
    this.view = new View(this.renderer);
    this.scene = this.view.scene;
    this.camera = this.view.camera;
    this.light = new DirectionalLight();
    this.scene.addChild(this.light);
    this.setup();
    //this.initialize();
    window.onresize = (evt:UIEvent) => this.resize(evt);
    this.resize();
    this.timer = new RequestAnimationFrame(this.render, this);
    this.timer.start();
    this.materials = new Array<TriangleMethodMaterial>();
    AssetLibrary.enableParser(AWDParser);
    AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, (evt:AssetEvent) => this.loaded(evt));
    AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, (evt:LoaderEvent) => this.complete(evt));
    AssetLibrary.load(new URLRequest(this.dataPath));

    var slider:Slider = new Slider();
    this.gui = new dat.GUI();
    var slider1 = this.gui.add(slider, "ambient", 0, 1);
    var slider2 = this.gui.add(slider, "diffuse", 0, 1);
    var slider3 = this.gui.add(slider, "specular", 0, 1);
    var slider4 = this.gui.add(slider, "direction", 0, 360);
    slider1.onChange((value:number) => this.change1(value));
    slider2.onChange((value:number) => this.change2(value));
    slider3.onChange((value:number) => this.change3(value));
    slider4.onChange((value:number) => this.change4(value));
  }

  private setup():void {
    this.view.backgroundColor = 0x333333;
    this.camera.x = 0;
    this.camera.y = 0;
    this.camera.z = - this.radius;
    this.light.direction = new Vector3D(0, -1, 0.4);
    this.light.ambient = 0.3;
    this.light.diffuse = 1;
    this.light.specular = 0;
  }
  private loaded(evt:AssetEvent):void {
    var asset:IAsset = evt.asset;
    var material:TriangleMethodMaterial;
    switch (asset.assetType) {
      case AssetType.CONTAINER :
        this.negimiku = <DisplayObjectContainer> asset;
        break;
      case AssetType.MATERIAL :
        material = <TriangleMethodMaterial> asset;
        this.materials.push(material);
        break;
      case AssetType.MESH :
        switch (asset.name) {
          case "R_arm" :
            this.arm = <Mesh> asset;
            break;
          case "negi" :
            this.negi = <Mesh> asset;
            break;
        }
        break;
    }
  }
  private complete(evt:LoaderEvent):void {
    this.initialize();
  }
  private initialize():void {
    var lightPicker:StaticLightPicker = new StaticLightPicker([this.light]);

    var pmaterial = new TriangleMethodMaterial(0x666666);
    pmaterial.lightPicker = lightPicker;
    var method:ShadowHardMethod = new ShadowHardMethod(this.light);
    method.alpha = 0.5;
    pmaterial.shadowMethod = method;
    this.plane = <Mesh> new PrimitivePlanePrefab(300, 300, 1, 1, true, true).getNewObject();
    this.plane.material = pmaterial;
    this.plane.y = - 184;
    this.scene.addChild(this.plane);

    for (var n:number = 0; n < this.materials.length; n++) {
      var material:TriangleMethodMaterial = this.materials[n];
      material.lightPicker = lightPicker;
      material.alpha = 1;
      material.alphaThreshold = 0.9;
    }
    this.negimiku.rotationX = 90;
    this.negimiku.transform.scale = new Vector3D(12.6, 12.6, 12.6);
    this.scene.addChild(this.negimiku);
    this.negimiku.y = - 50;
    this.hand = new DisplayObjectContainer();
    this.negimiku.addChild(this.hand);
    this.hand.addChild(this.arm);
    this.hand.addChild(this.negi);
    this.jump();
    this.swingHand();
  }
  private jump():void {
    createjs.Tween.get(this.negimiku, {override: false, paused: false, loop: true, useTicks: true})
      .to({"y": 50}, 30, createjs.Ease.circOut)
      .to({"y": -50}, 30, createjs.Ease.circIn)
    ;
  }
  private swingHand():void {
    createjs.Tween.get(this.hand, {override: false, paused: false, loop: true, useTicks: true})
      .to({"rotationX": -40}, 9, createjs.Ease.quadOut)
      .to({"rotationX": 0}, 9, createjs.Ease.quadIn)
      .to({"rotationX": 20}, 6, createjs.Ease.quadOut)
      .to({"rotationX": 0}, 6, createjs.Ease.quadIn)
    ;
  }
  private render(dt:number):void {
    createjs.Tween.tick(16, false);

    this.angle += 0.5;
    this.degree += 1;
    var dip:number = this.depression*Math.sin(this.degree*this.radian);
    this.camera.x = this.radius*Math.cos(this.angle*this.radian)*Math.cos(dip*this.radian);
    this.camera.y = this.radius*Math.sin(dip*this.radian);
    this.camera.z = this.radius*Math.sin(this.angle*this.radian)*Math.cos(dip*this.radian);
    this.camera.lookAt(this.center);
    this.view.render();
  }
  private resize(evt:UIEvent = null):void {
    this.view.width = window.innerWidth;
    this.view.height = window.innerHeight;
  }

  private change1(value:number):void {
    this.light.ambient = value;
  }
  private change2(value:number):void {
    this.light.diffuse = value;
  }
  private change3(value:number):void {
    this.light.specular = value;
  }
  private change4(value:number):void {
    var angle:number = (value + 270)%360;
    var dx:number = 0.4*Math.cos(angle*this.radian);
    var dz:number = 0.4*Math.sin(angle*this.radian);
    this.light.direction = new Vector3D(dx, -1, dz);
  }
}

class Slider {

  public ambient:number = 0.3;
  public diffuse:number = 1;
  public specular:number = 0;
  public direction:number = 180;

  constructor() {
  }

}

window.onload = function() {
  new Main();
}

build.txt
src/Main.ts
-target ES5
-module commonjs
-outDir bin

build.txt 上で、[Command + B] して、ビルド。

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0">
<title>[AwayJS] ライト (1)</title>
<script type="text/javascript" src="js/awayjs-core.min.js">/script>
<script type="text/javascript" src="js/awayjs-stagegl.min.js">/script>
<script type="text/javascript" src="js/awayjs-renderergl.min.js">/script>
<script type="text/javascript" src="js/awayjs-display.min.js">/script>
<script type="text/javascript" src="js/awayjs-methodmaterials.min.js">/script>
<script type="text/javascript" src="js/awayjs-parsers.min.js">/script>
<script type="text/javascript" src="js/createjs/easeljs-0.8.1.min.js">/script>
<script type="text/javascript" src="js/createjs /tweenjs-0.6.1.min.js">/script>
<script type="text/javascript" src="js/dat.gui.min.js">/script>
<script type="text/javascript" src="Main.js">/script>
<style type="text/css">
  html { overflow:hidden; }
  body { margin:0; padding:0; }
</style>
</head>
<body style="background-color:#333333;">
</body>
</html>

:caution: AwayJSでの注意点
影をつけるには、DirectionalLight を Scene に addChild()する必要がある。


:banana: [TypeScript] AwayJSを始めよう! 参照。


[修正] (14/12/17 Wed 15:24)
CreateJS 0.8.0 にバージョンアップ。
[修正] (14/12/27 Sat 20:00)
HTML記述を変更。
[修正] (15/09/20 Sun 23:32)
CreateJS 0.8.1 にバージョンアップ。