PVを久々に新しいバージョンにアップしたらいろんな機能が追加されているのでビックリ。

その中でも、ライト(光源)というものがあったのでビックリ。


1:CellMaterial

2:EnvMapMaterial

3:FlatShadeMaterial(フラットシェーディング)

4:GouraundMaterial(グローシェーディング)

5:PhongMateria(フォンシェーディング)


1に関しては証明の当たり具合を段々と設定するマテリアルとのこと。

2は「Bitmapを照明に割り当てることができるマテリアル」らしい。

3はべったりと面に照明を割り当てるマテリアル

4はグラデーション風に適用されるマテリアル

5はグラデーション風に適用されるマテリアルだが光沢の不自然さを改善するとのこと


そうすると5のPhongMaterialが一番自然な感じなのかな?


今回は5の「PhongMaterial」で実験 実験ではCubeマテリアルで作成して各面にPhongMaterialを設定


必要なクラス

import org.papervision3d.materials.shadematerials.PhongMaterial(PhongMaterialをインポート)

import org.papervision3d.lights.PointLight3D;(PointLight3Dをインポート)


ライト作成

//light
light = new PointLight3D();
light.z = 0;
light.x = 1000;
light.y = 1000;


ライトの座標位置はまだよく分かっていないので適当



PhongMaterial作成(今回はめんどいのでCube作成とまとめて作成しています。)

cube = new Cube(new MaterialsList( { all:new PhongMaterial(light, 0xFFFFFF, 0x0099CC, 10) } ), 100, 100, 100, 1, 1, 1);


上記の赤い部分がPhongMaterialの作成部分。


PhogMaterialの第一引数は「light(LightObject3D)」つまりは作成したライト


第2引数は「LightColor」つまりライトの色・・まぁライトは大体白だったりするのかな


第3引数は「ambientColor」つまりライトがかかっていない部分・・マテリアル本体の色(自分で検証してみただけなので実際はどうだか・・・)


第4引数は「 specularLevel:uint」つまりライトの広がりの強さ・・みたいな感じかな・・・・


例えば、 specularLevelが1だと全体的にライトが大きいが100とかだと広がりが小さいので一点に集中している感じになる 大体10くらいがいい感じなのかな~


とまぁライトに関してはこの位でとりあえず終了。


全体的な流れとしては、ライトを作成したらPhongMaterialの引数に割り当てることでオッケ~



全体のスクリプト  ShadeMaterialTEST.as


package {
import fl.transitions.Photo;
import flash.display.*;
import flash.events.*;
import org.papervision3d.core.math.Sphere3D;
//
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.*;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.shadematerials.PhongMaterial; //シェーダーマテリアル
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
//
import org.papervision3d.lights.PointLight3D; //ライト機能
//
import caurina.transitions.*;
import caurina.transitions.properties.CurveModifiers;
CurveModifiers.init();
/**
* ...
* @author $(DefaultUser)
*/
public class ShadeMaterialTEST extends Sprite{
private var camera:Camera3D;
private var vp:Viewport3D;
private var render:BasicRenderEngine;
private var scene:Scene3D;
//ライト
private var light:PointLight3D;
//格納用オブジェクト
private var storage:DisplayObject3D;
//各種変数
private static const NUM_CUBES:uint = 4; //一辺の個数
private static const DISTANCE:uint = 200;//配置間隔
//初期位置保存配列
private var initXYZ:Array = new Array();
//
private var ObjList:Array = new Array();
//
private var cube:Cube;
//
public function ShadeMaterialTEST() {
//ステージ設定
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
//
init();
}
//----
//初期設定
//----
private function init():void {
scene = new Scene3D();
camera = new Camera3D();
render = new BasicRenderEngine();
vp = new Viewport3D(0, 0, true, false);
addChild(vp);
//cameraの設定
camera.focus = 500;
camera.zoom = 1;
camera.x = 0;
camera.y = 500;
camera.z = -1000;
camera.target = DisplayObject3D.ZERO; //座標原点(0,0,0)に固定
//light
light = new PointLight3D();
light.z = 0;
light.x = 1000;
light.y = 1000;
//
//3Dオブジェクト格納用
storage = new DisplayObject3D();
scene.addChild(storage);
//
//Cubeの配置
for (var i:int = 0; i < NUM_CUBES; i++) { //Z座標
for (var j:int = 0; j < NUM_CUBES ; j++) {//Y座標
for (var k:int = 0; k < NUM_CUBES; k++) { //X座標
cube = new Cube(new MaterialsList( { all:new PhongMaterial(light,0xFFFFFF,0x998899,100) } ), 100, 100, 100, 1, 1, 1);

//配置調整
var adjust:Number = (NUM_CUBES - 1) * DISTANCE / 2;
cube.x = k * DISTANCE - adjust;
cube.y = j * DISTANCE - adjust;
cube.z = i * DISTANCE - adjust;
//
ObjList.push(cube);
initXYZ.push( { x:cube.x, y:cube.y, z:cube.z } );
//格納用オブジェクトに追加
storage.addChild(cube);
}
}
}
//
addEventListener(Event.ENTER_FRAME, LoopAction);
stage.addEventListener(MouseEvent.CLICK, doClick);
stage.addEventListener(MouseEvent.DOUBLE_CLICK, doDoubleClick);
stage.doubleClickEnabled = true;
}

private function doDoubleClick(e:MouseEvent):void {
for (var i:int = 0; i < ObjList.length;i++){
Tweener.addTween(ObjList[i], {
x:initXYZ[i].x,
y:initXYZ[i].y,
z:initXYZ[i].z,
_bezier:[{x:Math.random()*1000, y:Math.random()*1000}],
rotationY:360,
time:0.6,
delay:(i - 1) * 0.08,
transition:"easeInOutCubic" } );
}
}

private function doClick(e:MouseEvent):void {
for (var i:int = 0; i < ObjList.length;i++){
Tweener.addTween(ObjList[i], {
x:Math.random() * 2000,
y:Math.random() * 2000,
z:Math.random() * 15000,
_bezier:[{x:Math.random()*stage.stageWidth, y:Math.random()*stage.stageWidth}],
rotationY:360,
time:0.6,
transition:"easeInOutCubic" } );
}
}

private function LoopAction(e:Event):void {
//Cubeオブジェクトを回転
for (var i:int = 0; i < ObjList.length; i++) {
ObjList[i].rotationY += 1;
}
//storage.pitch(1);//X軸
//storage.yaw(0.2);//y軸
//storage.roll(1);//z軸
//
render.renderScene(scene, camera, vp);
}
}

}