2 minutes
❎ Direct3D 11 Graphics Pipeline - 3. Vertex Shader 스테이지
이전 글: ❎ Direct3D 11 Graphics Pipeline - 2. Input-Assembler 스테이지
Vertex Shader(VS)란, IA에서 넘겨준 정점 하나를 받아 GPU 공간에서 의미 있는 위치 / 속성으로 변환하여 다음 단계로 넘기는 프로그램
- 중요한 것은 정점 하나를 받아 처리하여 넘겨주는 정점 단위 독립 실행 프로그램이라는 점!
모든 렌더링에서 반드시 실행되며, 이후 단계들이 도형을 만들 수 있도록 정점의 기본 정보를 준비하는 단계
HLSL에서 전형적인 형태 예시
struct VSInput { float3 pos: POSITION; float2 uv: TEXCOORD0; // 해당 Primitive에 입힐 텍스처 내 좌표 uint iid: SV_InstanceID; };- 이 구조체가 정점 1개에 해당
1. 좌표 변환
VS의 가장 핵심적인 책임
정점 데이터는 보통 Local 공간에 있으며, GPU가 화면에 그리려면 다음과 같은 변환을 거쳐야 함
Local -> World -> View -> Projection -> Clip Space
이 변환을 수행하는 것이 VS
참고로 Clip 공간으로의 모든 변환을 VS에서 수행함
변환 코드 예시
VS는 최소한 반드시
SV_POSITION을 출력해야 함struct VSOutput { float4 pos: SV_POSITION; };- 이 값이 없으면 Rasterizer가 동작할 수 없고, 화면에 아무것도 출력되지 않음
cbuffer Transform: register(b0) {
float4x4 WorldViewProj;
};
VSOutput VSMain(VSInput input) {
VSOutput o;
o.pos = mul(float4(input.pos, 1.0), WorldViewProj);
return o;
}
2. 정점 속성 전달 및 생성
VS는 정점의 위치 외에도 공간 변환 결과, 색상, Instance ID 기반 offset 등 필요한 속성을 선택 및 (필요 시) 계산하여 다음 단계로 넘김
VS의 출력 대부분은 Rasterizer에서 보간됨
Pixel Shader는 정점 3개에서 나온 값을 픽셀 단위로 보간된 값으로 받음
때문에 VS 출력을 PS를 위한 준비 단계라고도 볼 수 있음
3. VS의 실행 모델
VS는 정점 1개 당 1번 실행되고, 정점 간 서로 영향이 없으면서 순서 개념도 없기 때문에 수천 개의 VS가 동시에 실행됨
VS는 순수 함수에 가깝기 때문에 전역 상태 변경이나 다른 정점 접근, 동적 메모리 할당 등을 수행하지 않음
IA는 정점의 입력 형태를 만들고, VS는 정점에 의미를 부여하는 단계!
버퍼 없는 렌더링?
IA에서 보았듯이, D3D 11은 정점 버퍼 없이도 렌더링이 가능함
VS는 입력이 VS 안에서 계산한 결과든, IA에서 넘어온 버퍼든 상관 없이 계산해서
SV_POSITION만 잘 출력해주면 됨