프로그래밍/공부

[Game] Uv 좌표

Sik.K 2023. 1. 22. 19:05

코딩을 통해 프로그램에서 이미지를 출력하고 하는 경우, Uv 좌표에 대한 개념을 이해하고 있어야 한다.

 

Uv 좌표란, 텍스처 이미지를 3차원 공간애 맵핑하기 위한 2차원 공간에서의 좌표를 의미한다.

 

이미지의 크기가 얼마나 크던 작던, 최소는 0, 0이고 최대 좌표는 1, 1의 좌표를 가진다.

 

이를 객체에 이미지를 씌울 때는 0과 1에 입히려는 이미지의 크기로 나눈 비율을 대입하여 이미지를 출력한다.

 

Uv 좌표, DirectX와 OpenGL

이를 간단하게 표현하기 위해 하나의 애니메이션을 재생한다고 가정해보자.

 

애니메이션은 대게 스프라이트 이미지를 이용해서 제작이 된다. 스프라이트 이미지란, 객체의 특정 애니메이션 행동을 나열한 하나의 이미지를 의미한다.

 

ex) 록맨의 달리기 스프라이트 이미지

 

객체에 위의 이미지를 입히고 달리기라는 애니메이션을 만든다면 객체의 이미지는 저 이미지들을 순서에 맞게 출력하게 된다. 연속된 출력은 마치 객체가 실제로 달리기를 하고 있는 것처럼 보이게 된다.

 

이게 애니메이션을 출력하는 기본 원리이다.

 

그렇다면 이미지를 어떻게 객체에 맵핑해야 할까.

 

초기에 이미지를 객체에 씌우게 되면 객체의 Uv는 최소가 0, 0 최대가 1, 1로 맵핑이 된다. 이를 그대로 출력하면 객체의 사이즈에 위의 사진이 모두 표시가 되는 것이다.

 

원하는 이미지만을 씌우기 위해 값을 조정할 필요가 있다.

 

저 스프라이트 이미지는 총 10장의 프레임으로 구성이 된다. 각 이미지별로 재생하기 위해선 원하는 프레임을 가로, 세로 전체 프레임 수에 맞게 나눈 값으로 Uv를 저장하면 원하는 프레임을 재생하게 된다.

 

가령 첫 번째 줄에서 세 번째에 위치한 이미지를 출력하고 싶을 때는 다음과 같이 설정하면 된다.

 

ObImage* player;
player = new ObImage(L"Character.png");

// 3은 재생하고자 하는 가로 축 프레임, 5는 가로의 전체 프레임 수, 1은 재생하고자하는 세로 축 프레임, 2는 세로의 전체 프레임 수
player->uv = Vector4(3/5, 1/2, 4/5, 1/2);

 

Uv는 각각 x와 y의 최소, 최대값을 표시해야 하기 때문에 네 개의 float 값을 가지는 벡터로 구성된다.

 

이를 응용하여 해당 자리에 변수를 넣고, 그 변수에 맞게 값을 입력하면 원하는 이미지를 그때 그때 재생할 수 있게 된다.