OpenGL이란 실리콘 그래픽스사에서 만든 2차원 및 3차원 그래픽스 표준 API이다. 이 API는 약 250여개 가량의 함수를 호출하여 단순 기하 도형부터 복잡한 삼차원의 도형 및 장면을 생성할 수 있다. 현재는 가상현실, 비행 시뮬레이션, 컴퓨터 게임 분야 등에서 널리 사용중이다. 이번 OpenGL을 공부하며 최종적으로 3차원의 게임 프로젝트를 진행할 예정이다. 주의할 점은 OpenGL은 오른손 좌표계를 사용하며 열벡터이다.
위 사진은 OpenGL의 파이프라인을 보여준다. 이 중 이번 프로젝트를 위해 우리는 버텍스 셰이더와 프레그먼트 셰이더를 중점으로 다룰 것이다.
이 두 셰이더의 특징은 프로그래머가 직접 프로그래밍을 할 수 있다는 점이다.
게임 공간 속 모든 모델은 정점을 가지고 있고 그에 따른 픽셀 값을 가지며 색을 표현하여 최종적으로 2D 스크린으로 보여준다.
모델의 정점, 좌표값을 조작하며 노말값, 텍스처 좌표값 등을 조작할 수 있는 기능을 수행해 주는 것이 버텍스 셰이더이다.
모델의 색상, 재질, 라이팅, 깊이 값을 결정하는 것이 프레그먼트 셰이더이다. 우리는 이 셰이더에서 색상을 결정할 수 있다.
이 두가지 셰이더를 메인 프로그램과 따로 분리하여 작성한다.
든 정점 및 속성 정보를 배열로 지정하며 Vertex Buffer Object와 Vertex Array Object를 사용한다.
이 배열을 GPU에 보내어 저장하고 렌더링에 사용하는 것이다.
#version version_number //--- 사용 버전 선언
in type in_variable_name; //--- 변수 선언
out type out_variable_name;
uniform type uniform_variable_name;
void main(void) //--- 메인 함수: 인자값 없음
{
//--- 입력 값을 처리
//--- 필요한 그래픽 작업 수행
...
//--- 출력 변수 저장
out_variable_name = output data;
}
셰이더의 구조는 다음과 같으며 몇가지 특징이 있다.
1. C와 비슷한 기본 문법
2. 포인터의 개념이 없음 -> 동적 할당이 없음
3. C언어의 구조체 사용이 가능
4. 매트릭스나 벡터는 기본 형으로 함수에서 입력이나 반환으로 출력이 가능
#version 330 core
in vec3 vPos;
void main ()
{
gl_Position = vec4 (vPos.x, vPos.y, vPos.z, 1.0);
}
정점 셰이더는 그리기 명령어에 의해 Vertex Array Object로부터 속성을 설정한다.
버텍스 변환 혹은 텍스처 좌표 설정을 담당하는 곳이다.
#version 330 core
out vec4 FragColor;
void main ()
{
FragColor = vec4 (1.0, 0.0, 0.0, 1.0);
}
프래그먼트 셰이더는 레스터라이저 단계에서 생성된 프래그먼트를 일련의 색상과 깊이 값으로 처리한다.
색상을 설정하거나 조명을 설정한다.
mat3 m = mat3 (
1.1, 2.1, 3.1, //--- 첫번째 열
1.2, 2.2, 3.2, //--- 두번째 열
1.3, 2.3, 3.3, //--- 세번째 열
);
mat3 m = mat3 (1.0); //--- 대각선이 1.0이고 다른 요소들은 0.0인 3x3 행렬 = 단위행렬