텍스처 작업을 시작한 후에는
drawTriangles()
의 uvtData 매개 변수를 사용할 수 있습니다. 이 매개 변수를 사용하면 비트맵 채우기를 위한 UV 매핑을 설정할 수 있습니다.
UV 매핑은 객체에 텍스처를 적용하기 위한 방법으로, U 가로(x) 값과 V 세로(y) 값을 사용합니다. 이 두 값은 픽셀 값이 아니라 백분율을 기준으로 합니다. 0U 및 0V는 이미지의 왼쪽 위 모서리이고 1U 및 1V는 오른쪽 아래 모서리입니다.
비트맵 이미지상의 UV 0 및 1 위치
삼각형의 벡터에 UV 좌표를 지정하면 벡터를 이미지 상의 각 위치와 연결할 수 있습니다.
비트맵 이미지에 있는 삼각형 영역의 UV 좌표
UV 값은 삼각형의 점과 일관되게 유지됩니다.
삼각형의 정점이 이동하면서 개별 점의 UV 값이 동일하도록 비트맵이 왜곡된 모양
비트맵과 연결된 삼각형에 ActionScript 3D 변형이 적용될 때 비트맵 이미지는 UV 값을 기준으로 삼각형에 적용됩니다. 따라서 행렬 계산을 사용하는 대신 UV 값을 설정하거나 조정하여 3차원 효과를 만듭니다.
Graphics.drawTriangles()
메서드는 3차원 변형을 위해 T 값이라는 선택적 정보를 사용하기도 합니다. uvtData의 T 값은 3D 원근, 보다 구체적으로는 연결된 정점의 비율 인수를 나타냅니다. UVT 매핑에서는 UV 매핑에 원근 교정을 추가로 사용합니다. 예를 들어 객체가 3D 공간에서 시점으로부터 멀리 떨어져 있어 "원래" 크기의 50%로 나타날 경우 해당 객체의 T 값은 0.5가 됩니다. 3D 공간에서는 객체를 나타내기 위해 삼각형을 그리므로 z축 상에서의 객체 위치가 객체의 T 값을 결정합니다. T 값을 결정하는 수식은 다음과 같습니다.
T = focalLength/(focalLength + z);
이 수식에서 focalLength는 초점 거리나 보기에 제공되는 원근 정도를 지정하는 계산된 "화면" 위치를 나타냅니다.
초점 거리 및 z 값
-
A.
-
시점
-
B.
-
화면
-
C.
-
3D 객체
-
D.
-
focalLength 값
-
E.
-
z 값
T 값은 기본 모양의 크기를 조절하여 해당 모양이 더 멀리 있는 것처럼 보이게 하는 데 사용됩니다. 이 값은 일반적으로 3D 점을 2D 점으로 변환하는 데 사용되는 값입니다. UVT 데이터의 경우에는 원근이 적용된 삼각형 내의 점 사이에서 비트맵 크기를 조절하는 데도 이 값이 사용됩니다.
UVT 값을 정의할 때 T 값은 정점에 대해 정의된 UV 값을 직접적으로 따릅니다. T 값이 포함된 경우
uvtData
매개 변수의 세 값(U, V 및 T)은 모두
vertices
매개 변수(x 및 y)의 두 값 모두와 일치합니다. UV 값만 사용할 경우 uvtData.length == vertices.length입니다. T 값이 포함된 경우 uvtData.length = 1.5*vertices.length입니다.
다음 예제에서는 UVT 데이터를 사용하여 3D 공간에서 평면을 회전하는 방법을 보여 줍니다. 이 예제에서는 ocean.jpg라는 이미지를 BitmapData 객체에 할당할 수 있도록 ocean.jpg 이미지와 "도우미" 클래스인 ImageLoader를 사용하여 해당 이미지를 로드합니다.
다음은 ImageLoader 클래스의 소스입니다. 이 코드를 ImageLoader.as라는 파일에 저장하십시오.
package {
import flash.display.*
import flash.events.*;
import flash.net.URLRequest;
public class ImageLoader extends Sprite {
public var url:String;
public var bitmap:Bitmap;
public function ImageLoader(loc:String = null) {
if (loc != null){
url = loc;
loadImage();
}
}
public function loadImage():void{
if (url != null){
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
var req:URLRequest = new URLRequest(url);
loader.load(req);
}
}
private function onComplete(event:Event):void {
var loader:Loader = Loader(event.target.loader);
var info:LoaderInfo = LoaderInfo(loader.contentLoaderInfo);
this.bitmap = info.content as Bitmap;
this.dispatchEvent(new Event(Event.COMPLETE));
}
private function onIoError(event:IOErrorEvent):void {
trace("onIoError: " + event);
}
}
}
다음은 삼각형, UV 매핑 및 T 값을 사용하여 이미지가 소실점 쪽으로 점점 작아지고 회전하는 것처럼 보이도록 만드는 ActionScript입니다. 이 코드를 Spinning3dOcean.as라는 파일에 저장하십시오.
package {
import flash.display.*
import flash.events.*;
import flash.utils.getTimer;
public class Spinning3dOcean extends Sprite {
// plane vertex coordinates (and t values)
var x1:Number = -100, y1:Number = -100, z1:Number = 0, t1:Number = 0;
var x2:Number = 100, y2:Number = -100, z2:Number = 0, t2:Number = 0;
var x3:Number = 100, y3:Number = 100, z3:Number = 0, t3:Number = 0;
var x4:Number = -100, y4:Number = 100, z4:Number = 0, t4:Number = 0;
var focalLength:Number = 200;
// 2 triangles for 1 plane, indices will always be the same
var indices:Vector.<int>;
var container:Sprite;
var bitmapData:BitmapData; // texture
var imageLoader:ImageLoader;
public function Spinning3dOcean():void {
indices = new Vector.<int>();
indices.push(0,1,3, 1,2,3);
container = new Sprite(); // container to draw triangles in
container.x = 200;
container.y = 200;
addChild(container);
imageLoader = new ImageLoader("ocean.jpg");
imageLoader.addEventListener(Event.COMPLETE, onImageLoaded);
}
function onImageLoaded(event:Event):void {
bitmapData = imageLoader.bitmap.bitmapData;
// animate every frame
addEventListener(Event.ENTER_FRAME, rotatePlane);
}
function rotatePlane(event:Event):void {
// rotate vertices over time
var ticker = getTimer()/400;
z2 = z3 = -(z1 = z4 = 100*Math.sin(ticker));
x2 = x3 = -(x1 = x4 = 100*Math.cos(ticker));
// calculate t values
t1 = focalLength/(focalLength + z1);
t2 = focalLength/(focalLength + z2);
t3 = focalLength/(focalLength + z3);
t4 = focalLength/(focalLength + z4);
// determine triangle vertices based on t values
var vertices:Vector.<Number> = new Vector.<Number>();
vertices.push(x1*t1,y1*t1, x2*t2,y2*t2, x3*t3,y3*t3, x4*t4,y4*t4);
// set T values allowing perspective to change
// as each vertex moves around in z space
var uvtData:Vector.<Number> = new Vector.<Number>();
uvtData.push(0,0,t1, 1,0,t2, 1,1,t3, 0,1,t4);
// draw
container.graphics.clear();
container.graphics.beginBitmapFill(bitmapData);
container.graphics.drawTriangles(vertices, indices, uvtData);
}
}
}
이 예제를 테스트하려면 이 두 클래스 파일을 "ocean.jpg"라는 이미지와 동일한 디렉토리에 저장하십시오. 원본 비트맵이 3D 공간에서 먼 곳으로 소실되고 회전하는 것처럼 보이도록 변형되는 방식을 볼 수 있습니다.