텍스처 좌표
고친 사람 github-actions[bot]
텍스처 좌표는 그림의 어느 부분을 물체 표면의 어디에 붙일지 정합니다. 3차원 모델의 정점마다 하나씩 붙어 다닙니다. 값은 가로와 세로 두 개이고, 그림의 한쪽 끝이 0, 반대쪽 끝이 1 입니다.
쉽고 빠른 이해
텍스처 좌표는 그림의 어느 지점을 표면의 어느 지점에 붙일지 적어 둔 값입니다. 상자 모델의 한 모서리에 (0, 0) 을 적어 두면 그림의 왼쪽 아래 구석이 그 모서리에 옵니다.
그림은 네모난 격자이고 모델의 표면은 제멋대로 생겼습니다. 둘을 이어 줄 대응이 없으면 화면의 어느 점에 그림의 어느 색을 칠할지 정할 수 없습니다.
어떻게 도나:
- 모델을 만들 때 정점마다 좌표 한 쌍을 적어 둡니다
- 삼각형 안쪽 점의 좌표는 세 꼭짓점의 값을 섞어 구합니다
- 그 좌표로 그림에서 색을 읽어 화면에 칠합니다
대가는 대응을 사람이 손으로 정해 줘야 한다는 것입니다. 굽은 표면을 평평한 그림에 맞추는 일이라 무늬가 늘어나거나 끊긴 자국이 남습니다.
상세
지구본에 종이 지도를 붙이는 일을 떠올려 봅시다. 종이는 평평하고 공은 둥글어서 그냥 대면 안 맞습니다. 지도의 어느 점을 공의 어느 점에 맞출지 미리 정해 두어야 하고, 그러고도 어딘가는 늘어나거나 접힙니다.
텍스처 좌표는 텍스처 안의 한 지점을 가리키는 값 한 쌍입니다. 텍스처는 표면에 입힐 그림을 격자로 담아 둔 자원이고, 그 격자의 칸 하나를 텍셀이라고 부릅니다. 3차원 모델은 삼각형을 이어 붙여 만드는데, 그 삼각형의 꼭짓점 하나가 정점입니다. 삼각형 하나를 화면에 그릴 때 각 정점이 그림의 어느 지점에서 색을 가져올지, 그것을 텍스처 좌표가 정합니다.
이 값이 없으면 그림을 표면에 못 붙입니다. 그림은 네모반듯한 격자인데 모델의 표면은 굽고 꺾여 있어서, 둘 사이에 저절로 맞아떨어지는 대응이 없기 때문입니다. 텍스처 좌표는 그 대응을 정점마다 하나씩 적어 둔 표에 해당합니다.
두 축과 0 에서 1 까지의 범위
가로축을 u, 세로축을 v 라고 부릅니다. 그래서 실무에서는 이 값을 UV(UV coordinates, 유브이 좌표)라고 부릅니다. OpenGL 쪽에서는 같은 두 축을 s 와 t 로 적습니다. 이름만 다르고 뜻은 같습니다.
값은 0 에서 1 사이로 적습니다. u 가 0 이면 그림의 한쪽 가로 끝, 1 이면 반대쪽 가로 끝입니다. v 도 같은 방식으로 세로 양 끝을 가리킵니다.
칸 번호 대신 0 에서 1 사이의 값을 쓰는 까닭은 그림 크기에 안 묶이기 위해서입니다. 이렇게 크기와 무관한 값으로 바꿔 두는 것을 정규화라고 합니다. 같은 모델에 512칸짜리 그림을 입히든 2048칸짜리를 입히든 좌표는 손대지 않고 씁니다.
아래는 정사각형 그림 한 장에서 좌표 몇 개가 어디를 가리키는지 적은 표입니다.
| u | v | 그림에서 가리키는 지점 |
|---|---|---|
| 0 | 0 | 한쪽 구석 |
| 1 | 0 | 가로로 반대쪽 구석 |
| 0.5 | 0.5 | 한가운데 |
| 1 | 1 | 대각선 반대쪽 구석 |
표의 값은 그림의 크기와 상관없이 같습니다. 그림이 커지면 한 칸이 차지하는 좌표 폭만 줄어듭니다.
원점이 어느 모서리인가
0 이 왼쪽 아래인지 왼쪽 위인지는 하나로 굳어 있지 않습니다. 그래픽 규격마다 다르게 둡니다. 한쪽은 v 가 커질수록 위로 올라가고, 다른 쪽은 v 가 커질수록 아래로 내려갑니다.
그래서 한 도구에서 만든 모델을 다른 도구로 옮기면 무늬가 위아래로 뒤집혀 보이는 일이 흔합니다. 세로만 뒤집히고 가로는 멀쩡하다면 대개 이 차이입니다.
고치는 방법은 v 를 1 - v 로 바꿔 넣는 것입니다. 모델에 적어 둔 좌표를 고치거나, 그림을 읽는 코드에서 그때그때 뒤집습니다.
정점에서 프래그먼트까지
정점 하나에는 위치 말고도 여러 값이 같이 붙습니다. 이런 값을 정점 속성이라고 부릅니다. 텍스처 좌표도 그중 하나라서 법선이나 정점 색과 나란히 정점에 실려 다닙니다.
그런데 삼각형 안쪽은 정점이 아닙니다. 화면에 찍히는 점 하나하나는 세 꼭짓점 사이 어딘가에 놓입니다. 그래서 그 점의 텍스처 좌표는 세 꼭짓점의 값을 거리에 따라 섞어서 만듭니다. 이렇게 사이값을 만드는 일을 보간이라고 합니다.
삼각형을 화면의 점들로 쪼개는 단계는 래스터화라고 하고, 그렇게 나온 점 하나는 프래그먼트라고 부릅니다. 프래그먼트마다 보간된 텍스처 좌표가 하나씩 딸려 옵니다.
마지막으로 그 좌표를 들고 텍스처에서 색을 읽어 옵니다. 이 읽기를 샘플링이라고 합니다. 여기까지가 좌표 하나가 색 하나로 바뀌는 길입니다.
flowchart TD
V["정점 · 텍스처 좌표를 달고 있다"] --> R["래스터화 · 삼각형을 점들로 쪼갠다"]
R --> I["보간 · 점마다 좌표를 섞어 만든다"]
I --> S["샘플링 · 그 좌표로 텍스처에서 색을 읽는다"]
S --> P["화면에 그 색을 칠한다"]
사람이 적어 두는 것은 맨 위의 정점 좌표뿐입니다. 아래 네 단계는 그리는 동안 저절로 일어납니다.
아래 표는 꼭짓점 셋의 좌표가 이럴 때 삼각형 한가운데의 좌표가 어떻게 나오는지 보인 것입니다.
| 지점 | u | v |
|---|---|---|
| 꼭짓점 A | 0 | 0 |
| 꼭짓점 B | 1 | 0 |
| 꼭짓점 C | 0 | 1 |
| 세 꼭짓점의 한가운데 | 0.33 | 0.33 |
한가운데 값은 세 꼭짓점의 값을 똑같은 비중으로 섞은 것입니다. 한 꼭짓점에 가까운 점일수록 그 꼭짓점의 값이 더 많이 섞입니다. 섞는 비중을 정하는 값은 무게중심 좌표가 받습니다.
범위를 벗어난 좌표
좌표에 1 보다 큰 값이나 0 보다 작은 값을 적어도 됩니다. 그러면 그림 한 장을 넘어서는 지점을 가리키게 되는데, 그때 무엇을 돌려줄지는 미리 골라 둔 방식이 정합니다.
| 방식 | 1.5 를 받으면 | 고르는 경우 |
|---|---|---|
| 되풀이 | 0.5 로 봅니다 | 벽돌·타일처럼 같은 무늬를 이어 붙일 때 |
| 가장자리 고정 | 1 로 봅니다 | 그림 끝 색이 번지면 안 될 때 |
| 거울 되풀이 | 0.5 를 좌우로 뒤집어 봅니다 | 이어 붙인 자국을 감출 때 |
되풀이를 고르면 작은 그림 한 장으로 넓은 벽을 덮을 수 있습니다. 좌표를 0 에서 4 까지 주면 그림이 가로로 네 번 반복됩니다. 이 방식을 어디에 적어 두는지는 샘플러와 래핑 모드가 받습니다.
3차원 표면을 평면으로 펴는 일
모델은 입체이고 그림은 평면 한 장입니다. 입체의 모든 면에 좌표를 붙이려면 면들을 평면 위에 펼쳐 늘어놓아야 합니다. 이 작업이 UV 언래핑입니다.
flowchart TD
subgraph 모델["3차원 모델 · 정육면체의 세 면"]
F1["앞면"]
F2["옆면"]
F3["윗면"]
end
subgraph 평면["텍스처 한 장 · 0 에서 1 까지의 정사각형"]
U1["앞면 조각"]
U2["옆면 조각"]
U3["윗면 조각"]
end
F1 --> U1
F2 --> U2
F3 --> U3
그림은 정육면체의 면 셋만 그렸습니다. 면마다 텍스처 위의 한 조각을 배정받습니다. 조각과 조각을 가르려면 모델의 표면을 어딘가에서 잘라야 하고, 그 잘린 경계가 이음매입니다.
펼치는 방법은 하나로 정해져 있지 않아서 사람이 고릅니다. 이음매를 눈에 안 띄는 곳으로 보내고, 조각마다 늘어나는 정도를 고르게 맞추는 일이 이 작업의 대부분입니다. 조각이 실제 표면보다 작게 잡히면 그 부분은 같은 색을 여러 번 읽습니다. 그래서 무늬가 뭉개진 것처럼 보입니다. 조각 여럿을 한 장에 빈틈없이 배치한 것은 텍스처 아틀라스라고 부릅니다.
셰이더가 좌표를 받는 대목
셰이더는 GPU(Graphics Processing Unit, 그래픽 처리 장치)에서 도는 작은 프로그램입니다. 프래그먼트마다 한 번씩 돌면서 그 점에 칠할 색을 정합니다.
아래는 GLSL(OpenGL Shading Language, 오픈지엘 셰이딩 언어)로 적은 최소한의 예입니다. uv 는 보간되어 넘어온 텍스처 좌표이고, texture 는 그 좌표의 색을 읽어 오는 함수입니다.
in vec2 uv; // (0.25, 0.75)
out vec4 color;
void main() {
color = texture(tex, uv); // (0.8, 0.2, 0.1, 1)
}
돌려받는 값 네 개는 빨강·초록·파랑과 불투명도입니다. 셰이더가 한 일은 좌표를 그대로 넘긴 것뿐이고, 그 좌표 주변의 칸을 몇 개나 읽어 어떻게 섞을지는 텍스처 필터링과 밉맵이 받습니다.
좌표를 적어 두지 않고 그리는 방법
텍스처 좌표가 늘 있어야 하는 것은 아닙니다. 색을 그림에서 가져오지 않으면 좌표도 필요 없습니다. 정점마다 색을 직접 적어 두고 그 사이를 섞는 방식이 그렇습니다.
무늬를 그림 대신 계산식으로 만드는 방법도 있습니다. 나뭇결이나 구름 같은 무늬는 위치를 넣으면 색이 나오는 식으로 그릴 수 있습니다. 이렇게 그린 것을 절차적 텍스처라고 합니다.
그림 한 장을 입혀야 하는 순간부터는 좌표가 필요합니다. 사진에서 딴 재질, 손으로 그린 무늬, 표면의 요철을 적어 둔 노멀 맵은 전부 그림이라서 어디를 어디에 붙일지 정해 줘야 합니다. 한 표면을 어떻게 보이게 할지 정하는 설정 묶음을 머티리얼이라고 하는데, 그림 여러 장을 한 머티리얼에 묶어 쓸 때도 좌표는 대개 한 벌을 같이 씁니다.
관련 항목
텍스처 좌표를 싣고 다니는 기하 데이터
정점 · 정점 속성 · 메시 · 프리미티브 · 법선 · 탄젠트 · 정점 색
텍스처 좌표로 읽어 들이는 그림 자원
텍스처 · 텍셀 · 밉맵 · 노멀 맵 · 알베도 · 머티리얼 · 텍스처 아틀라스
좌표가 색으로 바뀌기까지 거치는 처리 단계
래스터화 · 프래그먼트 · 보간 · 무게중심 좌표 · 샘플링 · 셰이더
좌표를 읽는 방식을 정하는 설정
샘플러 · 래핑 모드 · 텍스처 필터링 · 이방성 필터링 · 밉 레벨
텍스처 좌표를 만들어 내는 작업
UV 언래핑 · 이음매 · 라이트맵 · 텍스처 베이킹 · 절차적 텍스처
좌표를 잘못 잡았을 때 화면에 나타나는 현상
텍스처 블리딩 · 모아레 · 에일리어싱 · 텍스처 늘어남
한 장면 안에서 나란히 쓰이는 다른 좌표계
윈도 좌표 · 정규화 장치 좌표 · 월드 좌표 · 모델 좌표 · 클립 좌표
텍스처 좌표를 규정하는 그래픽스 규격
다른 이름: texture coordinates · UV · UV 좌표 · 유브이 좌표 · st 좌표