Quick Syntax
// GL 3.3 Core 정점 셰이더
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 vertexColor;
out vec3 tint;
void main() {
gl_Position = vec4(position, 1.0);
tint = vertexColor;
}// 같은 프로그램의 프래그먼트 셰이더
#version 330 core
in vec3 tint;
layout(location = 0) out vec4 color;
void main() {
color = vec4(tint, 1.0);
}VAO의 속성 위치·타입, 단계 사이의 이름·타입, 최종 색 출력 위치는 서로 다른 연결 지점입니다.
세 연결 지점
정점 셰이더의 입력 location은 VAO 속성 슬롯입니다. CPU가 슬롯 1에 색을 연결했는데 셰이더는 다른 위치를 읽으면 데이터가 맞지 않습니다. 행렬 입력은 열별로 여러 연속 슬롯을 사용합니다.
정점 출력과 프래그먼트 입력은 링크할 때 서로 맞아야 합니다. 3.3 기본 통합 프로그램에서는 같은 이름·타입으로 선언하고, 인터페이스 블록을 쓰면 블록 이름·멤버 구성·순서를 맞춥니다. 프래그먼트 출력 location은 텍스처 유닛이나 정점 속성 슬롯이 아니라 draw buffer 연결입니다.
보간 선택
| 한정자 | 결과 | 사용 사례·경계 |
|---|---|---|
smooth | 원근 보정 보간, 실수형 입력의 기본 | UV·표면 색 등 |
noperspective | 화면 공간 선형 보간 | 화면 기준 거리·특수 효과 |
flat | 지정된 한 정점의 값을 사용 | 정수 ID·면별 값, 정수 입력은 flat 필요 |
centroid | 다중 샘플에서 프리미티브 내부의 보간 위치 | 경계에서 범위 밖 보간을 줄임 |
sample | 샘플별 입력, 지원 버전 필요 | MSAA에서 픽셀별과 다른 실행 비용 |
flat의 값이 항상 첫 정점에서 온다고 가정하지 않습니다. provoking vertex 규칙과 glProvokingVertex 설정을 확인합니다. 정수 material ID를 일반 색처럼 보간하려고 하면 문법·타입 계약부터 맞지 않습니다.
내장 변수와 쓰기 책임
gl_Position은 클립 공간 위치이며 투영 나누기 전 값입니다. 정점 셰이더에서 올바르게 써야 래스터화 단계가 위치를 알 수 있습니다. gl_FragCoord는 프래그먼트의 창 좌표 등이며 정점 좌표와 같지 않습니다. gl_FrontFacing으로 앞뒤 면을 구분할 수 있고 gl_FragDepth를 직접 쓰면 깊이 동작·최적화 조건을 함께 고려합니다.
조건 분기 한쪽에서 출력 값을 쓰지 않았다면 그 경로의 결과를 초기값 0으로 가정하지 않습니다. 모든 필요한 실행 경로에서 값을 정의합니다. 컴파일과 링크 로그는 프로그램 연결에 따라 따로 읽습니다.
링크 전 위치 지정
소스의 layout location을 사용하지 않는 경로에서는 링크 전에 API로 위치를 정할 수 있습니다. 다음은 program에 필요한 셰이더를 연결한 뒤의 구간입니다.
glBindAttribLocation(program, 0, "position");
glBindFragDataLocation(program, 0, "color");
glLinkProgram(program);
// 링크 상태·로그를 확인합니다.이미 링크한 뒤 위 바인딩만 바꾸면 현재 실행 코드의 위치가 즉시 바뀌지 않습니다. 다시 링크하고 위치·uniform 상태를 재확인합니다.
버전별 문법
2.x GLSL의 attribute·varying, 구형 gl_FragColor는 현대 Core의 in/out 선언과 구분합니다. 3.3에서 정점 입력·프래그먼트 출력 location을 지정할 수 있다고 모든 단계 간 변수에도 같은 위치 문법을 사용할 수 있는 것은 아닙니다. 단계 간 명시적 위치와 분리 프로그램은 4.1 계열 조건을 확인합니다. sample 보간은 GLSL 4.00 또는 대응 확장이 필요합니다.
참고 링크
4 sources