Vertex Shader는 그래픽 파이프라인의 프로그래밍 가능한 단계로, 3D 모델의 각 정점을 독립적으로 처리합니다. Khronos Group, 2025에 따르면, 버텍스 셰이더는 정점 속성(좌표, 법선, 색상 및 텍스처 좌표)을 입력으로 받아 정의된 로직에 따라 변환합니다. Vertex Shader는 각 정점에 대해 독립적으로 실행되므로 GPU의 수천 개 코어에서 계산을 효율적으로 병렬화할 수 있습니다.
핵심 사항
Vertex Shader는 그래픽 파이프라인의 프로그래밍 가능한 단계로, 3D 모델의 각 정점을 개별적으로 처리합니다. 정점(vertex)은 xyz 좌표, 법선, 색상 및 UV 텍스처 좌표와 같은 속성을 포함하는 3차원 공간의 점입니다.
변환이 고정 알고리즘에 따라 수행되던 고정 기능 파이프라인(fixed-function pipeline)과 달리, Vertex Shader는 개발자에게 정점 변환에 대한 완전한 제어권을 제공합니다. 이를 통해 절차적 애니메이션, 모델 변형, 골격 스키닝 및 GPU 측의 모든 수학적 변환을 구현할 수 있습니다.
OpenGL ES 그래픽 파이프라인은 입력 데이터에서 최종 이미지까지 일련의 단계로 구성됩니다. Vertex Shader는 정점 어셈블리 단계 이후, 래스터화 단계 이전에 위치합니다. CPU에서 정점 버퍼를 통해 전송된 각 정점은 Vertex Shader를 정확히 한 번 통과하며, 결과는 프리미티브 어셈블리를 위해 다음 단계로 전달됩니다.
| 파이프라인 단계 | 목적 |
|---|---|
| Vertex Specification | VBO에서 정점 데이터 및 속성 전송 |
| Vertex Shader | 각 정점 처리, 좌표 변환 |
| Tessellation | 하위 프리미티브로 지오메트리 선택적 세분화 |
| Geometry Shader | 프리미티브 선택적 생성 또는 제거 |
| Rasterization | 채우기를 위한 프리미티브를 프래그먼트로 변환 |
Vertex Shader는 CPU 코드에서 구성된 정점 속성 포인터를 통해 정점 버퍼(VBO)에서 정점 속성을 수신합니다. 개발자는 GLSL(OpenGL Shading Language) 또는 이에 상응하는 언어로 셰이더 코드를 작성하며, GPU 드라이버가 특정 칩에 대한 기계 명령어로 컴파일합니다.
각 정점에 대해 Vertex Shader는 순차적으로 세 가지 작업을 수행합니다: 입력 속성 읽기 → 개발자가 정의한 변환 적용 → 출력 변수에 결과 쓰기. 최소 필수 출력은 클립 공간의 정점 위치(gl_Position)입니다. 기타 모든 출력 데이터(색상, 법선, 텍스처 좌표)는 보간되어 다음 단계(Fragment Shader)로 전달됩니다.
#version 300 es
in vec3 aPosition;
in vec2 aTexCoord;
uniform mat4 uMVP;
out vec2 vTexCoord;
void main() {
gl_Position = uMVP * vec4(aPosition, 1.0);
vTexCoord = aTexCoord;
}
Vertex Shader는 지오메트리 변환과 관련된 광범위한 그래픽 파이프라인 작업을 해결합니다. 각 작업은 벡터와 행렬에 대한 수학적 연산을 통해 구현되며, 수천 개의 정점에 대해 동시에 병렬로 실행됩니다.
가장 기본적이고 일반적인 작업은 정점 좌표를 model, view, projection(MVP) 행렬로 곱하는 것입니다. MVP 행렬은 정점을 로컬 모델 공간에서 클립 공간으로 변환하며, 이후 파이프라인의 자동 단계에서 정규화되어 화면 좌표로 변환됩니다.
애니메이션 캐릭터의 경우 Vertex Shader는 골격 애니메이션(스키닝)을 구현합니다. 각 정점은 특정 가중치로 여러 뼈에 바인딩됩니다. Vertex blending(바인딩된 뼈의 변환 가중 합계)을 통해 골격이 움직일 때 캐릭터의 피부를 부드럽게 변형할 수 있습니다.
Vertex Shader는 CPU 개입 없이 시간 또는 기타 uniform 매개변수에 따라 지오메트리를 수정할 수 있습니다. 파동 변형, Perlin 노이즈 변위 및 물결 효과 등 이러한 모든 효과는 RAM에서 지오메트리를 다시 로드하지 않고 버텍스 셰이더에서 구현됩니다.
두 셰이더 유형 모두 그래픽 파이프라인의 프로그래밍 가능한 단계이지만, Vertex Shader와 Fragment Shader는 근본적으로 다른 작업을 해결하고 이미지 처리의 다른 단계에서 작동합니다.
| 특성 | Vertex Shader | Fragment Shader |
|---|---|---|
| 입력 데이터 | VBO의 정점 속성 | VS에서 보간된 데이터 |
| 호출 횟수 | 정점 수 | 프래그먼트 수 |
| 주요 작업 | 지오메트리 변환 | 픽셀 색상 계산 |
| 계산 부하 | 지오메트리 복잡성 | 화면 해상도 |
| 텍스처 액세스 | 제한적(texture lookup 통해) | 전체 액세스 |
주요 차이점은 호출 빈도입니다. Vertex Shader는 정점당 한 번 호출되는 반면, Fragment Shader는 각 프래그먼트(픽셀)마다 호출됩니다. 고해상도 장면에서 Fragment Shader 호출 수는 Vertex Shader 호출 수보다 수천 배 많으므로 픽셀 셰이더 최적화가 더욱 중요해집니다.
Vertex Shader 성능은 실시간 애플리케이션, 특히 전력 소비가 제한된 모바일 개발에서 매우 중요합니다. 주요 성능 요소는 정점 수, 셰이더 코드 복잡성 및 GPU 메모리 대역폭입니다.
Vertex Shader의 부하를 줄이기 위해 다음과 같은 접근 방식이 사용됩니다. Level of Detail (LOD) — 카메라가 객체에서 멀어질 때 모델의 단순화된 버전으로 전환합니다. Instancing — 단일 드로우 콜에서 서로 다른 변환 행렬로 동일한 지오메트리를 여러 번 그립니다.
// 인스턴싱을 지원하는 Vertex Shader
in vec3 aPosition;
in mat4 aInstanceMatrix;
uniform mat4 uViewProjection;
void main() {
vec4 worldPos = aInstanceMatrix * vec4(aPosition, 1.0);
gl_Position = uViewProjection * worldPos;
}
Vertex Shader는 다양한 그래픽 API에서 유사한 로직을 가지고 있지만 구문과 명명 규칙이 다릅니다. OpenGL ES 3.0용 GLSL과 iOS 및 macOS용 Metal Shading Language에서 기본 버텍스 셰이더의 구현을 살펴보겠습니다.
#version 300 es
in vec4 position;
in vec3 normal;
in vec2 texcoord;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
out vec3 vNormal;
out vec2 vTexCoord;
out vec3 vPosition;
void main() {
vec4 mvPosition = modelViewMatrix * position;
vPosition = mvPosition.xyz;
vNormal = normalMatrix * normal;
vTexCoord = texcoord;
gl_Position = projectionMatrix * mvPosition;
}
#include <metal_stdlib>
using namespace metal;
struct VertexIn {
float3 position [[attribute(0)]];
float3 normal [[attribute(1)]];
};
struct VertexOut {
float4 position [[position]];
float3 worldNormal;
};
vertex VertexOut
vertexMain(VertexIn in [[stage_in]],
constant float4x4& mvp [[buffer(1)]]) {
VertexOut out;
out.position = mvp * float4(in.position, 1.0);
out.worldNormal = in.normal;
return out;
}
자주 묻는 질문
Vertex Shader는 3D 모델의 각 정점을 처리하고 해당 좌표를 화면 좌표로 변환하는 GPU 프로그램입니다. 모델을 점들의 그물망으로 상상해보세요. 버텍스 셰이더는 정의된 수학적 규칙에 따라 이 점들을 이동시킵니다.
Vertex Shader는 정점을 처리하고 지오메트리를 담당하는 반면, Fragment Shader는 각 픽셀의 색상을 결정합니다. 전자는 각 정점(수천 개)마다 호출되고, 후자는 각 픽셀(수백만 개)마다 호출됩니다.
Vertex Shader는 그래픽 API에 해당하는 언어로 작성됩니다: OpenGL ES용 GLSL, iOS/macOS용 Metal Shading Language, Direct3D용 HLSL. 개념적으로 모두 정점에 대해 동일한 작업을 수행합니다.
버텍스 셰이더의 복잡성은 FPS에 직접적인 영향을 미칩니다: 정점당 더 많은 명령어 = 더 긴 처리 시간. 최적화에는 LOD를 통한 정점 수 감소, 인스턴싱 사용 및 셰이더 코드의 조건부 분기 최소화가 포함됩니다.
주요 게임 작업: MVP 행렬을 통한 좌표 변환, 애니메이션 캐릭터의 스키닝, 의상과 머리카락의 절차적 변형, 표정 간 모핑 및 GPU 애니메이션이 적용된 파티클 효과.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.