Quick Syntax
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
}열벡터를 기준으로 projection * view * model * position을 사용합니다. CPU 배열의 저장 순서와 수학적 곱 순서는 별개이며, 둘을 함께 확인해야 합니다.
작은 행렬로 확인
GLSL의 mat4 * vec4를 사용하고 CPU 배열은 열 단위로 저장합니다. 다음 행렬은 x·y를 절반으로 줄인 뒤 x 방향으로 0.3만큼 이동합니다. 열 순서 배열의 인덱스 12가 x 이동 성분입니다.
const float transform[] = {
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.3f, 0.0f, 0.0f, 1.0f,
};
// program은 링크 성공한 프로그램이고 transform uniform을 실제 사용합니다.
glUseProgram(program);
GLint location = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(location, 1, GL_FALSE, transform);이 작은 2D 예제의 position은 vec2이고 uniform 이름은 transform입니다. 따라서 정점 셰이더는 다음처럼 선언합니다. 상단의 model·view·projection 예제와 섞지 않고 한 형태를 선택합니다.
#version 330 core
layout(location = 0) in vec2 position;
uniform mat4 transform;
void main() {
gl_Position = transform * vec4(position, 0.0, 1.0);
}position을 vec3로 선언한 셰이더에서는 vec4(position, 1.0)을 사용합니다. 원점은 (0.3, 0, 0, 1), 점 (1, 0, 0, 1)은 (0.8, 0, 0, 1)이 됩니다. 회전이 없는 작은 사례로 배치·곱·전치를 먼저 검증하면 카메라까지 합친 상태에서 원인을 추측할 필요가 줄어듭니다.
삼각형 예제의 실행 인수 1이 이 변환을 적용합니다. 새 소스를 조합할 때는 정점 셰이더의 uniform 선언·위치 조회·업로드를 함께 바꿉니다.
곱과 업로드의 조건
| 항목 | 선택과 의미 | 실수했을 때 |
|---|---|---|
P * V * M * p | 열벡터 기준으로 오른쪽 변환부터 적용 | 이동·회전 순서가 바뀜 |
transpose = GL_FALSE | 전달한 배열을 열 우선 행렬로 해석 | 행 우선 배열을 그대로 주면 다른 변환 |
count = 1 | 행렬 하나 업로드 | float 개수 16과 혼동 |
위치 -1 | 비활성·존재하지 않는 uniform 등에 해당 | 업로드가 무시되어 값이 바뀌지 않음 |
| 초기 행렬 uniform | 명시적 초기값이 없으면 0으로 시작 | 업로드 없이 사용하면 단위행렬이 아님 |
데스크톱 glUniformMatrix4fv는 전치 인수를 지원하지만, 이미 전치한 배열을 다시 전치해 업로드하지 않습니다. GLM의 일반적인 행렬 사용에서는 glm::value_ptr와 GL_FALSE를 함께 쓰며, glm/gtc/type_ptr.hpp를 포함합니다. GLM의 투영·깊이 범위 설정도 별도로 확인해야 하며 행렬 메모리만 맞춘다고 카메라 규약까지 맞는 것은 아닙니다.
점의 마지막 성분은 1, 방향 벡터는 0으로 두면 평행이동 적용 여부를 구분할 수 있습니다. 법선은 비균일 스케일에서 위치와 같은 행렬을 그대로 쓰지 않습니다. 이 수학적 이유는 행렬과 변환, 좌표 공간에 연결됩니다.
1.0 행렬 스택과 대응
레거시 고정 기능 환경의 다음 명령은 현재 MODELVIEW 행렬을 단위행렬로 만들고 T * S 순서로 누적합니다. 정점에는 크기 변경 뒤 이동이 적용됩니다.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.3f, 0.0f, 0.0f);
glScalef(0.5f, 0.5f, 1.0f);구형 코드의 glPushMatrix/glPopMatrix는 선택된 행렬 스택의 상태를 저장·복원합니다. 현대 Core에는 이 스택이 없으므로 CPU에서 행렬 값을 보관하고 필요한 draw 전에 uniform을 전달합니다. GL_MODELVIEW는 모델과 뷰를 합친 상태이며, 현대 셰이더에서 둘을 반드시 하나의 uniform으로 합쳐야 한다는 뜻은 아닙니다.
4.1의 glProgramUniformMatrix4fv는 프로그램을 직접 지정해 값을 갱신할 수 있습니다. 3.3 기본 경로의 glUseProgram·glUniformMatrix4fv와 호출 전제를 구분합니다. 어느 경로든 GL이 사용자 행렬의 의미나 카메라 방향을 자동으로 추론하지는 않습니다.
참고 링크
3 sources