Flash/Away3D

얼사마 2011. 4. 11. 18:09

모든 물체는 빛에 의해 영향을 받게 된다.

빛 때문에 단색의 물체도 음영이 발생하게 되고, 이 때문에 형태를 알아 볼 수 있게 된다.

 

먼저 Lighting이 전혀 적용되지 않은, ColorMaterial로만 맵핑된 오브젝트들을 보자.



얼핏 보면, 2d 인지 3d인지 구분이 안된다.

이제부터 이 화면에 빛을 통해서 공간감을 만들어 보겠다.

 

DirectionalLight

3D 공간상에 위치하지 않으며, 특정한 각도로 Scene의 모든 오브젝트에 같은 양의 빛을 적용시키는 Light이다.

쉽게, 태양을 연상하면 되겠다. (아침, 점심, 저녁...)

 

DirectionalLight Class 정의

away3d.lights.DirectionalLight.DirectionalLight(xDir:Number=0, yDir:Number=-1, zDir:Number=1)

 

  • 파라미터 설명
    • xDir : x축 방향의 벡터값으로, + 일 경우 좌에서 우측으로, - 일 경우 반대 방향
    • yDir : y축 방향의 벡터값으로, + 일 경우 아래에서 위로, - 일 경우 반대 방향
    • zDir : z축 방향의 벡터값으로, + 일 경우 전면에서 후면으로, - 일 경우 반대 방향

 

예제 코드

var leftLight:DirectionalLight = new DirectionalLight();

leftLight.direction = new Vector3D(0.5,-0.3,0.5);  // scene에서 전면/상단/좌측에서 후면/하단/우측 방향으로 향하는

leftLight.color = 0xffffff;  // 빛의 색상

leftLight.specular = 0.5;  // 빛이 반짝이는 세기

leftLight.diffuse = 1;  // 빛이 확산되는

this._scene.addChild(leftLight);

 

var boxMaterial:ColorMaterial = new ColorMaterial(0x00ff00);

boxMaterial.lights = [leftLight];  // Material lights 적용

var box:Cube = new Cube(boxMaterial, 100,200,300);

box.y = 50;

this._scene.addChild(box);


만들어진 DirectionalLight, 위와 같이 각 Material object에 적용하면 아래와 같은 화면을 볼 수 있다.



위의 스크린샷을 보면, 확실히 공간감이 살아났다.

각 오브젝트의 실제 모양새가 분명이 드러나 보인다.

하지만, 코드상으로 보자면 이 화면은 빛이 단 하나밖에 없는 깜깜한 암실의 모습이나 다를바가 없다.

화면상의 모든 오브젝트의 우측 하단이 본래의 색과 상관없이 완전 검은 색으로 나타난다.

 

바닥의 역할을 하고 있는 Plane에는 라이트를 적용하지 않았다.

 

대게의 경우는 지표면과 다른 물체에 의한 빛의 반사와 확산이 일어나게 된다.

따라서 아래의 코드를 추가해 보자.

 

var rightLight:DirectionalLight = new DirectionalLight();

rightLight.direction = new Vector3D(-1,0.3,-0.3);  // 위의 leftLight 반대 방향의

rightLight.color = 0xffffff;

rightLight.specular = 0;

rightLight.diffuse = 0.3;  // 빛의 확산 정도를 leftLight보다 작게 설정

this._scene.addChild(rightLight);

 

var boxMaterial:ColorMaterial = new ColorMaterial(0x00ff00);

boxMaterial.lights = [leftLight,rightLight];  // 모든 오브젝트에 적용

var box:Cube = new Cube(boxMaterial, 100,200,300);

box.y = 50;

this._scene.addChild(box);


위와 같이 반대 방향의 약한 빛을 추가하고 나면,

아래와 같은 화면을 볼 수 있다.

 



 

이제 오브젝트의 전체적인 색이 제대로 표현이 된다.

 

3D 관련한 툴 사용이나, 개발을 해보신 분들은 잘 아시겠지만.

모델링, 맵핑 못지 않게 중요한 것이 라이팅(Lighting)이다.

라이트를 어떻게 사용하느냐에 따라, 그 느낌은 천차만별...

 

 

PointLight

3D 공간상의 특정 지점에 위치하여, 전방위적으로 빛을 발산하는 성격을 가진 Light이다.

쉽게, 전구를 연상하면 되겠다.

 

PointLight Class 정의

away3d.lights.PointLight.PointLight()

 

  • 파라미터 설명
    • PointLight 객체 생성 시, 특별한 파라미터를 요구하지 않는다.

 

예제 코드

var pointLight:PointLight = new PointLight();

pointLight.color = 0xff0000;  // 빛의 색깔

pointLight.radius = 200;  // 빛이 영향을 미치는 반경

pointLight.x = -50;  // 빛의 x 좌표

pointLight.y = 100;  // 빛의 y 좌표

pointLight.z = -200;  // 빛의 z 좌표

pointLight.diffuse = 1;  // 빛의 확산 정도

this._scene.addChild(pointLight);


PointLight, 전방위적으로 발산되는 빛이기 때문에

특정한 위치와 반경을 필요로 한다.

 

위에서 만들어진 PointLight를 모든 오브젝트에 적용하면 아래와 같은 화면을 볼 수 있다.

PointLight의 위치와 영향을 쉽게 볼 수 있도록, Plane에도 leftLight, rightLight, pointLight를 모두 적용하였다.




 

위의 스크린샷에서 볼 수 있듯이,

PointLight의 위치는 녹색 육면체 앞, 그리고 Plane의 상단에 위치한다. (제일 밝은 곳)

PointLight가 위치한 곳에서 멀어질 수록, 빛의 세기(영향)은 줄어든다.

 

 
 
 

Flash/Away3D

얼사마 2011. 4. 6. 17:33

Mipmap 이란?

퍼포먼스 향상을 위해, 텍스쳐로 사용되는 이미지를 미리 여러가지 사이즈로 만들어 놓은 후에, 오브젝트가 화면에 보이는 크기에 적절한 이미지 사용한다.



왼쪽의 가장 큰 이미지가 본래 이미지이며, 2^n * 2^n 사이즈를 가진다.

이 본래의 이미지의 가로 세로를 1/2 줄인 이미지를 만들고(우측 첫번째)

줄여진 이미지의 1/2를 또 줄인 이미지를 만드는 것을 반복하여,

1*1 이미지까지 생성한 후,

실제 렌더링시에, 위의 텍스쳐가 사용된 오브젝트가 화면에 보이는 사이즈를 고려하여 적절한 이미지를 선택하여 렌더링하게 된다.

 

이와 같은 mipmap 방식을 사용하지 않으면, 본래의 가장 큰 이미지를

오브젝트가 화면에 보이는 사이즈와 상관없이 사용하게 된다.

 

Away3D 4.0 에서는 mipmap 사용을 기본으로 하고 있으며,

따라서 모든 material의 사이즈는 가로 세로의 길이가 2 n승이 정사각형의 이미지여야 한다.

 

ColorMaterial

오브젝트에 단일 색상으로 맵핑하는 Material

 

ColorMaterial Class 정의

away3d.materials.ColorMaterial.ColorMaterial(color:uint, alpha:Number=1)

 

  • 파라미터 설명
    • color : 색상 값
    • alpha : 투명도

 

예제 코드

var floorMaterial:ColorMaterial = new ColorMaterial(0xff0000, 1);

var floor:Plane = new Plane(floorMaterial, 700, 700, 1, 1, false);

this._scene.addChild(floor);

 

BitmapMaterial

이미지의 BitmapData를 오브젝트에 맵핑하는 Material

 

BitmapMaterial Class 정의

away3d.materials.BitmapMaterial.BitmapMaterial(bitmapData:BitmapData=null, smooth:Boolean=true, repeat:Boolean=false, mipmap:Boolean=true)

 

  • 파라미터 설명
    • bitmapData : 표시할 이미지의 BitmapData instance
    • smooth : 텍스쳐에 smoothing 옵션 적용 여부
    • repeat : true일 경우, 타일 방식으로 맵핑되고, false일 경우, 해당 이미지 전체로 맵핑
    • mipmap : mipmapping 사용 여부

 

예제코드

var floorMaterial:BitmapMaterial = new BitmapMaterial(this._imageGround.bitmapData, true, false, true);

var floor:Plane = new Plane(floorMaterial, 700, 700, 1, 1, false);

this._scene.addChild(floor);

 

BitmapFileMaterial

동적으로 이미지 파일을 로드하여 맵핑하는 Material

 

BitmapFileMaterial Class 정의

away3d.materials.BitmapFileMaterial.BitmapFileMaterial(url:String="", checkPolicy:Boolean=false)

 

  • 파라미터 설명
    • url : 텍스쳐 이미지의 경로
    • checkPolicy : 로드하고자하는 이미지가 다른 도메인에 있다면, 해당 도메인의 crossdomain.xml 을 확인하기 위해서 true로 설정한다.

 

예제 코드

var sphereMaterial:BitmapFileMaterial = new BitmapFileMaterial('./imageAsset/material/objects/worldmap.png');

var sphere:Sphere = new Sphere(sphereMaterial, 100, 16, 12);

this._scene.addChild(sphere);

 

AnimatedBitmapMaterial

MovieClip bitmap으로 캐싱하여 맵핑하는 Material

 

AnimatedBitmapMaterial Class 정의

away3d.materials.AnimatedBitmapMaterial.AnimatedBitmapMaterial(movie:MovieClip=null, loop:Boolean=true, autoPlay:Boolean=false, index:uint=0, defaultBitmapData:BitmapData=null)

 

  • 파라미터 설명
    • movie : 애니메이션이 있는 MovieClip instance
    • loop : true일 경우, 무한 반복 플레이
    • autoPlay : 자동 플레이 여부
    • index : 애니메이션이 시작될 프레임 번호
    • defaultBitmapData : MovieClip instance AnimatedBitmapMaterial 생성 시에 할당할 수 없는 경우, 기본 bitmapData를 보여주고, 이후에 setFrames 또는 setMovie 시에 해당 애니메이션을 플레이

 

예제 코드

var movie:MovieClip = new SampleMovieClip() as MovieClip;

var boxMaterial:AnimatedBitmapMaterial = new AnimatedBitmapMaterial(movie, true, true, 0, null);

var box:Cube = new Cube(boxMaterial, 100,200,300);


위의 예제를 현재(revision.3124)버전에서 그대로 실행하면 에러가 난다.

AnimatedBitmapMaterial Class update function 에서

if(_nmCache[_index])  ==> if(_nmCache && _nmCache[_index])

와 같이 수정해 주어야 에러가 나지 않는다.

 

 

VideoMaterial

flv 파일을 스트리밍으로 가져와서 맵핑하는 Material

 

VideoMaterial Class 정의

away3d.materials.VideoMaterial.VideoMaterial(source:String, materialSize:int=256, loop:Boolean=true, autoPlay:Boolean=false, player:IVideoPlayer=null)

 

  • 파라미터 설명
    • source : flv 파일의 url
    • materialSize : flv 파일의 사이즈(2^n)
    • loop : 반복 재생 여부
    • autoPlay : 자동 재생 여부
    • player : IVideoPlayer interface implements custom player가 있다면, 해당 플레이어의 instance를 넘기면 해당 플레이어를 사용한다.

 

예제 코드

var cylinderMaterial:VideoMaterial = new VideoMaterial('http://files.fliiby.com/streamVideoNew.php?file=JTBFSyUyMWRr.flv&start=0&id=player&client=FLASH%20WIN%2011,0,0,58&version=4.2.95&width=790&token=JTA5TCUyN2ltaiU1Q0EuJUU5', 256, true, true);

var cylinder:Cylinder = new Cylinder(cylinderMaterial, 50, 100, 200, 16, 1, true, true, true);

this._scene.addChild(cylinder);

 

위 예제에서는 http stream이 필요한 관계로, 특정 http url을 사용하였다.

 

 

위의 Material02.기본오브젝트 생성에 추가로 적용하게 되면 아래와 같은 화면을 볼 수 있다.

 

 


 
 
 

Flash/Away3D

얼사마 2011. 4. 6. 14:13

Primitive Object

Away3D에서는 현재(4.0 alpha - Revision 3117) 기준 아래와 같은 6가지 타입을 제공한다.

  1. Plane (4각 평면)
  2. Cube (육면체)
  3. Sphere ()
  4. Cone (원뿔)
  5. Cylinder (원기둥)
  6. SkyBox (전체 배경)

 

Camera Setting

기본 오브젝트를 배치해보기 전에, 우선 카메라의 위치를 잡도록 한다.

광원 효과(Lights)가 없고 ColorMaterial을 사용하는 경우,

카메라의 위치, 오브젝트의 배치에 따라 올바르게 렌더링이 되고 있는지 알 수 없는 화면이 나타날 때도 있기 때문이다.

 

this._camera.moveBackward(500);  // 카메라를 뒤(z값이 작아지는 방향)로 움직임.
this._camera.moveRight(500);  //
카메라를 우측(x값이 커지는 방향)으로 움직임.
this._camera.moveUp(500);  //
카메라를 상단(y값이 커지는 방향)으로 움직임.
this._camera.lookAt(new Vector3D(0,0,0));  //
위와 같이 이동한 카메라가 (0,0,0) 지점을 바라보도록 셋팅.

 

위와 같이 하면 카메라가 위쪽에서 비스듬하게 아래쪽을 바라보는 모양새가 된다.

 

 

Plane 생성하기

 

Plane Class 정의

away3d.primitives.Plane.Plane(material:MaterialBase=null, width:Number=100, height:Number=100, segmentsW:uint=1, segmentsH:uint=1, yUp:Boolean=true)

 

  • 파라미터 설명
    • material : Plane 오브젝트의 재질
    • width : 가로 크기
    • height : 세로 크기
    • segmentsW : 가로 방향의 세그먼트 개수
    • segmentsH : 세로 방향의 세그먼트 개수
    • yUp : true일 경우, XY 평면으로 생성, false일 경우, XZ 평면으로 생성
      • 쉽게 풀어서 설명하자면, true일 경우 (벽 같은) 세워진 평면이 생성되고, false일 경우 (바닥 같은) 누운 평면이 생성된다.

 

예제 코드

var floorMaterial:ColorMaterial = new ColorMaterial(0xff0000);  // Plane의 재질이 될 Material을 생성
var floor:Plane = new Plane(floorMaterial, 700, 700, 1, 1, false);  //
바닥에 누운 평면을 생성
this._scene.addChild(floor);  //
평면이 렌더링 될 수 있도록, Scene에 추가

 

위와 같이 코드를 작성하고 실행해 보면,

빨간색의 사각 평면이 3차원 공간에 비스듬히 보이는 장면을 볼 수 있다.

 

 

Cube 생성하기

 

Cube Class 정의

away3d.primitives.Cube.Cube(material:MaterialBase=null, width:Number=100, height:Number=100, depth:Number=100, segmentsW:uint=1, segmentsH:uint=1, segmentsD:uint=1, tile6:Boolean=true)

 

  • 파라미터 설명
    • material : Plane 오브젝트의 재질
    • width : 가로 크기 (x)
    • height : 세로 크기 (y)
    • depth : 깊이 (z)
    • segmentsW : 가로 방향의 세그먼트 개수
    • segmentsH : 세로 방향의 세그먼트 개수
    • segmentsD : 깊이 방향의 세그먼트 개수
    • tile6
      • true : 텍스쳐 이미지가 2x3으로 나뉘어 육면체의 각 면을 맵핑
      • false : 텍스쳐 이미지 전체가 각 면에 동일하게 맵핑

 

예제 코드

var boxMaterial:ColorMaterial = new ColorMaterial(0x00ff00);
var box:Cube = new Cube(boxMaterial, 100,200,300);
box.y = 50;
this._scene.addChild(box);

 

 

Sphere 생성하기

 

Sphere Class 정의

away3d.primitives.Sphere.Sphere(material:MaterialBase=null, radius:Number=50, segmentsW:uint=16, segmentsH:uint=12, yUp:Boolean=true)

 

  • 파라미터 설명
    • material : Plane 오브젝트의 재질
    • radius : 구의 반경
    • segmentsW : 수평 방향의 세그먼트 개수
    • segmentsH : 수직 방향의 세그먼트 개수
    • yUp
      • true : 극점의 방향이 y축으로 생성
      • false : 극점의 방향이 z축으로 생성

 

예제 코드

var sphereMaterial:BitmapFileMaterial = new BitmapFileMaterial('./imageAsset/material/objects/worldmap.png');
var sphere:Sphere = new Sphere(sphereMaterial, 100, 16, 12);
sphere.y = 100;
sphere.x = -150;
sphere.z = -150;
this._scene.addChild(sphere);

 

Sphere의 예제에서는 BitmapFileMaterial을 사용했다.

해당 경로의 이미지를 동적으로 로드하여,

로드가 완료되면 해당 BitmapFileMaterial을 사용하는 오브젝트에 바로 반영시켜준다.

 

위 예제에서 BitmapFileMaterial로 로드하는 이미지는 2^n * 2^n 의 사이지를 가지는 이미지를 사용하여야 한다.

이에 관련한 내용은 후에 다시 다룬다

 

 

Cone 생성하기

 

Cone Class 정의

away3d.primitives.Cone.Cone(material:MaterialBase=null, radius:Number=50, height:Number=100, segmentsW:uint=16, segmentsH:uint=1, closed:Boolean=true, yUp:Boolean=true)

 

  • 파라미터 설명
    • material : Plane 오브젝트의 재질
    • radius : 원뿔에서 밑면 원의 반경
    • height : 원뿔의 높이
    • segmentsW : 수평 방향의 세그먼트 개수
    • segmentsH : 수직 방향의 세그먼트 개수
    • yUp
      • true : 원뿔의 뿔 꼭지점이 y축으로 생성
      • false : 원뿔의 뿔 꼭지점이 z축으로 생성

 

예제 코드

var coneMaterial:ColorMaterial = new ColorMaterial(0x0000ff);
var cone:Cone = new Cone(coneMaterial, 50, 100, 16, 1, true, true);
cone.x = 80;
cone.y = 50;
cone.z = -100;
this._scene.addChild(cone);

 

 

Cylinder 생성하기

 

Cylinder Class 정의

away3d.primitives.Cylinder.Cylinder(material:MaterialBase=null, topRadius:Number=50, bottomRadius:Number=50, height:Number=100, segmentsW:uint=16, segmentsH:uint=1, topClosed:Boolean=true, bottomClosed:Boolean=true, yUp:Boolean=true)

 

  • 파라미터 설명
    • material : Plane 오브젝트의 재질
    • topRadius : 원기둥의 상단 원 반경
    • bottomRadius : 원기둥의 하단 원 반경
    • height : 원기둥의 높이
    • segmentsW : 수평 방향의 세그먼트 개수
    • segmentsH : 수직 방향의 세그먼트 개수
    • topClosed : true일 경우 상단이 면으로 막히게 되고, false 경우 뚫림
    • bottomClosed : true일 경우 하단이 면으로 막히게 되고, false 경우 뚫림
    • yUp
      • true : y축에 평행한, 세워진 원기둥 생성
      • false : z축에 평행한, 누운 원기둥 생성

 

예제 코드

var cylinderMaterial:ColorMaterial = new ColorMaterial(0xff00ff);
var cylinder:Cylinder = new Cylinder(cylinderMaterial, 50, 100, 200, 16, 1, true, true, true);
cylinder.x = 120;
cylinder.y = 100;
cylinder.z = 100;
this._scene.addChild(cylinder);

 

 

SkyBox 생성하기

 

SkyBox Class 정의

away3d.primitives.SkyBox.SkyBox(cubeMap:CubeMap)

 

  • 파라미터 설명
    • cubMap : SkyBox 육면체의 각 면의 텍스쳐 맵

 

예제 코드

var skyboxMap:CubeMap = new CubeMap();
skyboxMap.positiveY = this._skyboxTop.bitmapData;
skyboxMap.negativeY = this._skyboxBottom.bitmapData;
skyboxMap.negativeX = this._skyboxSide1.bitmapData;
skyboxMap.positiveZ = this._skyboxSide2.bitmapData;
skyboxMap.positiveX = this._skyboxSide3.bitmapData;
skyboxMap.negativeZ = this._skyboxSide4.bitmapData;
var skybox:SkyBox = new SkyBox(skyboxMap);
this._scene.addChild(skybox);

 

본 예제에서는, 각면을 인지할 수 있는 이미지를 embed하여,

embeded Bitmap을 사용하였다.

 

 

위의 Primitive object 모두 생성하여 실행하면 아래와 같은 화면을 볼 수 있다.