사전 정점 속성
개념

정점 속성

gabury1고친 사람 github-actions[bot]

정점 속성은 도형의 꼭짓점마다 달라지는 값을 그래픽 카드까지 실어 나릅니다. 꼭짓점 하나가 처리될 때 그 몫의 값만 한 벌씩 꺼내져 들어갑니다. 무엇을 실을지는 그리는 쪽이 정합니다.

쉽고 빠른 이해

정점 속성은 꼭짓점 하나에 딸린 값을 그래픽 카드까지 나르는 통로입니다. 삼각형의 꼭짓점 셋을 각각 빨강·초록·파랑으로 칠하고 싶다면 그 색 셋이 정점 속성으로 들어갑니다.

이게 없으면 점마다 다른 값을 줄 방법이 없습니다. 도형 하나에 값 하나만 줄 수 있으면 색도 표면이 향한 방향도 도형 전체에서 하나로 고정됩니다.

어떻게 도나:

  1. 값을 꼭짓점 순서대로 메모리에 늘어놓습니다
  2. 그 덩이를 어디서부터 몇 개씩 끊어 읽을지 미리 일러 둡니다
  3. 꼭짓점 하나가 돌 때마다 그 몫이 한 벌씩 꺼내져 셰이더로 들어갑니다

대가는 나르는 양입니다. 속성을 하나 더 붙이면 꼭짓점 하나가 차지하는 메모리가 늘고, 그리기 한 번에 읽어야 할 양도 꼭짓점 수만큼 곱해져 커집니다.

상세

이 절은 정점 속성이 무엇을 나르는지부터 봅니다. 그다음 그 값이 메모리에 어떤 모습으로 놓이는지, 덩이를 읽는 방법을 무엇으로 일러 주는지, 꼭짓점을 지난 값이 어떻게 되는지를 차례로 따라갑니다.

꼭짓점에 붙는 이름표

행사장에 들어가는 사람마다 이름표를 답니다. 이름표에는 이름과 소속과 좌석 번호가 적혀 있고, 안내원은 그 종이만 보고 이 사람을 어디로 보낼지 정합니다. 다만 이름표는 사람이 들고 오는 것이고, 꼭짓점의 값은 미리 한 덩이로 모아 두었다가 순서대로 꺼내 쓴다는 것이 다릅니다.

정점은 도형을 이루는 점 하나입니다. 삼각형 하나는 정점 셋으로 이뤄지고, 사람 모형 하나는 정점 수만 개로 이뤄집니다.

정점 속성은 그 점 하나에 딸려 있는 값입니다. 점이 어떤 성질을 갖는지를 적어 둔 값이라 속성이라고 부릅니다.

위치 말고 무엇이 붙나

거의 모든 꼭짓점이 위치 하나는 갖습니다. 어디에 찍을지를 모르면 아무것도 그릴 수 없기 때문입니다.

그 밖에 무엇이 붙을지는 무엇을 그리려는지가 정합니다. 빛을 계산하려면 표면이 어느 쪽을 향하는지가 필요하고, 그 방향을 법선이라고 부릅니다.

무늬 그림을 입히려면 그림의 어느 지점을 가져다 쓸지 적은 좌표가 필요합니다. 이 좌표를 텍스처 좌표라고 부릅니다.

꼭짓점마다 달라야 하는 값이면 무엇이든 속성이 될 수 있습니다. 뼈대를 따라 휘는 사람 모형은 어느 뼈에 얼마나 끌려갈지를 적은 값을 꼭짓점마다 붙이는데, 이렇게 모형을 휘게 하는 방식을 스키닝이라고 부릅니다.

꼭짓점마다 다른 값과 그리기 내내 같은 값

셰이더가 읽는 값이 전부 속성인 것은 아닙니다. 가르는 기준은 그 값이 꼭짓점마다 달라지느냐입니다.

갈래 언제 달라지나 예
정점 속성 꼭짓점마다 위치 · 표면이 향한 방향 · 꼭짓점 색
유니폼 그리기 한 번 동안 안 바뀐다 카메라를 담은 숫자 덩이 · 흐른 시간

둘을 가르는 까닭은 나르는 양입니다. 카메라 위치처럼 모든 꼭짓점에 똑같은 값을 속성으로 만들면 같은 숫자를 꼭짓점 수만큼 복사해 올려야 합니다.

메모리에 놓이는 모습

정점 속성은 낱개로 넘어가지 않습니다. 꼭짓점 순서대로 늘어놓은 한 덩이를 미리 그래픽 카드 메모리에 올려 두고, 그릴 때 그 덩이를 읽습니다. 이 덩이를 정점 버퍼라고 부릅니다.

늘어놓는 방법은 크게 둘입니다. 한 꼭짓점의 값들을 나란히 붙여 두고 다음 꼭짓점을 잇거나, 속성마다 덩이를 따로 만듭니다.

block-beta
columns 4
  A["위치 0"] B["색 0"] C["위치 1"] D["색 1"]
  E["위치 0"] F["위치 1"] G["색 0"] H["색 1"]

첫 줄이 섞어 담은 것이고 둘째 줄이 갈라 담은 것입니다. 섞어 담으면 한 꼭짓점에 필요한 값이 메모리에서 붙어 있어 한 번 읽을 때 같이 딸려 옵니다.

갈라 담으면 한쪽만 고쳐 올리기가 쉬워집니다. 위치만 매 장면 바꾸고 색은 손대지 않는 모형이 그렇습니다.

덩이를 읽는 방법을 일러 주는 네 가지

덩이만 올려 두면 그래픽 카드는 그것을 숫자 나열로만 봅니다. 어디서부터 몇 개씩 끊어 읽어야 하는지를 속성마다 따로 일러 줘야 합니다.

무엇을 정하나 무슨 뜻인가
성분 개수 값 하나가 숫자 몇 개로 이뤄지나. 위치는 셋, 무늬 좌표는 둘
성분 타입 그 숫자가 어떤 모양으로 적혀 있나. 소수인가 정수인가
시작 위치 덩이의 처음에서 몇 바이트 뒤에 이 속성의 첫 값이 있나
간격 한 꼭짓점의 값에서 다음 꼭짓점의 같은 값까지 몇 바이트를 건너뛰나

간격을 따로 일러 주는 까닭은 섞어 담기 때문입니다. 위치 다음에 색이 끼어 있으면 다음 위치는 바로 뒤가 아니라 색을 건너뛴 곳에 있습니다.

정수로 적어 둔 값을 소수로 바꿔 받는 방법도 있습니다. 색처럼 0과 1 사이면 충분한 값은 작은 정수로 적어 두면 메모리를 덜 씁니다. 읽어 들일 때 그 정수 범위를 0과 1 사이로 펴 주는 것을 정규화라고 부릅니다.

셰이더가 속성을 받는 모습

정점 셰이더는 꼭짓점 하나마다 한 번씩 도는 프로그램입니다. 정점 속성은 이 프로그램의 입력으로 들어옵니다.

glsl
attribute vec3 aPos;   // (0.0, 0.5, 0.0)
attribute vec3 aColor; // (1.0, 0.0, 0.0)

오른쪽 주석은 첫 꼭짓점이 돌 때 두 변수가 쥔 값입니다. 다음 꼭짓점이 돌면 같은 변수에 그 꼭짓점 몫의 값이 들어옵니다.

이름 앞에 붙은 표시가 이 변수를 속성으로 받겠다는 뜻입니다. 표시하는 낱말은 셰이더를 적는 언어마다 다릅니다.

꼭짓점을 나눠 쓰면 속성이 갈라진다

이웃한 삼각형은 꼭짓점을 나눠 씁니다. 같은 점을 두 번 적는 대신 번호로 가리키면 메모리가 줄고, 그 번호 목록을 인덱스 버퍼라고 부릅니다.

나눠 쓰는 순간 제약이 하나 생깁니다. 한 꼭짓점은 속성을 한 벌만 가질 수 있습니다.

상자의 모서리가 이 제약에 걸립니다. 모서리에서 만나는 두 면은 향한 방향이 다른데, 두 면이 꼭짓점을 나눠 쓰면 그 점의 방향은 하나뿐입니다.

그래서 모서리를 각지게 보이려면 같은 위치에 점을 두 벌 두고 방향만 다르게 붙입니다. 모형 파일의 꼭짓점 수가 눈에 보이는 꼭짓점보다 많은 까닭이 대개 이것입니다.

꼭짓점 사이는 섞어서 채운다

셰이더를 지난 속성 값은 손대지 않은 모습으로 화면에 닿지 않습니다. 삼각형 안쪽의 칸마다 꼭짓점 셋의 값을 비율대로 섞은 값이 도착합니다. 이 섞는 계산을 보간이라고 부릅니다.

flowchart TD
    A["정점 버퍼 · 값을 늘어놓은 덩이"] --> B["개수 · 타입 · 시작 · 간격대로 끊어 읽는다"]
    B --> C["정점 셰이더 · 꼭짓점 하나마다"]
    C --> D["보간 · 꼭짓점 셋의 값을 섞는다"]
    D --> E["화면 칸 하나마다 도는 다음 프로그램"]

꼭짓점 셋을 빨강·초록·파랑으로 두면 삼각형 안쪽이 부드럽게 물드는 것이 이 때문입니다. 안쪽 칸이 세 꼭짓점에서 각각 얼마나 떨어졌는지를 보고 그 비율대로 색을 섞습니다.

그래서 속성은 꼭짓점 사이에서 부드럽게 변해도 되는 값에 맞습니다. 칸마다 급하게 달라져야 하는 값을 속성으로 나르면 결과가 어긋나 보입니다.

속성을 늘리면 커지는 비용

속성을 하나 더 붙이면 꼭짓점 하나가 차지하는 바이트가 늘어납니다. 꼭짓점이 수십만 개면 늘어난 몫도 수십만 번 곱해집니다.

그리기 한 번마다 그 덩이를 읽어야 하므로 메모리에서 계산 장치로 나르는 양이 커집니다. GPU(Graphics Processing Unit, 그래픽 처리 장치)가 계산을 아무리 빨리 해도 값이 도착하지 않으면 기다립니다.

그래서 꼭짓점에 미리 붙여 둘 값과 셰이더 안에서 구할 값을 나눠 잡습니다. 미리 붙여 두면 계산이 줄고 나르는 양이 늘어납니다. 셰이더에서 구하면 나르는 양이 줄고 계산이 늘어납니다.

관련 항목

정점 속성으로 자주 실리는 값

정점 위치 · 법선 · 텍스처 좌표 · 정점 색 · 탄젠트 · 본 인덱스 · 스킨 가중치

정점 속성을 담아 두는 메모리 객체

정점 버퍼 · 버퍼 객체 · 정점 배열 객체 · 인덱스 버퍼 · 버퍼 뷰 · 접근자

속성의 배치를 정하는 값

스트라이드 · 오프셋 · 성분 타입 · 정규화 · 인터리브 배치 · 메모리 정렬

정점 속성을 읽어 들이는 처리 단계

입력 어셈블러 · 정점 페치 · 정점 셰이더 · 그래픽스 파이프라인 · 드로 콜

정점 속성이 지난 값을 이어받는 처리

보간 · 배리잉 · 원근 보정 보간 · 프래그먼트 · 프래그먼트 셰이더

꼭짓점마다 달라지지 않는 셰이더 입력

유니폼 · 유니폼 버퍼 · 푸시 상수 · 텍스처 · 샘플러

정점 속성을 다루는 그래픽 API

OpenGL · WebGL · Vulkan · Direct3D · Metal · WebGPU

정점 속성을 실어 나르는 자산 포맷

glTF · OBJ · FBX · COLLADA · USD

정점 속성을 선언하는 셰이더 언어

GLSL · HLSL · WGSL · SPIR-V

정점 속성이 속하는 상위 분류

정점 · 메시 · 프리미티브 · 그래픽스 · 렌더링 · 지오메트리 처리

정점 속성을 늘렸을 때 커지는 비용

메모리 대역폭 · 정점 캐시 · 정점 수 · 레벨 오브 디테일 · GPU

다른 이름: vertex attribute · 버텍스 어트리뷰트