OpenGL 파이프라인

aqu.kwon·2022년 1월 4일
1

그래픽

목록 보기
2/2
post-thumbnail

학습한 내용을 정리해둔 글입니다. 잘못된 내용이나 오타가 있다면 댓글로 남겨주세요.

OpenGL 공식 파이프라인

여기서 중점적으로 보아야할 부분으로 간추려보면 다음과 같다.

  1. Vertex Puller (Vertex Specification) : primitive의 경계(점, 선이나 테두리)를 정의하는 점들의 ordered list를 만든다. 이 list가 어떻게 해석되고 처리되는지는 이후의 단계에서 결정된다. 색상, 텍스처 좌표 등과 같은 다른 점 속성을 정의할 수 있다.

  2. Vertex Shader : GLSL로 작성하여 위에서 정의한 점 데이터를 조작한다. Scene에서 각 점의 최종 위치를 GPU를 통해 계산한다.

  3. Tessellation : optional 단계이며 primitive가 테셀레이션 된다. 하나의 삼각형이 있다면 더 부드러운 삼각형 메쉬로 나누어지는 과정이 여기서 일어난다.

  4. Geometry Shader : optional 단계이며 input primitive를 가져와서 0개 이상의 output primitive를 생성한다. 즉, primitive를 제거하거나 단일 입력에 대해 많은 primitive를 출력하여 테셀레이션할 수 있다. 또한, primitive를 다른 유형으로 바꿀 수도 있다.

  5. Vertex Post Processing : 이 단계에 대한 제어는 매우 제한적인 고정된 기능 단계이다. 쉐이더 기반 점 처리 이후 다음 단계들을 거친다.
    1) Transform Feedback : Vertex shader 혹은 Geometry shader를 통해 유저가 데이터를 변환할 수 있게 해준다.
    2) Primitive assembly : 이전 단계에서 출력된 점 데이터를 수집하고 일련의 primitive로 구성한다.
    3) Clipping : 화면에 걸쳐져 있는 primitive를 여러개의 primitive로 나눈다.
    4) Face culling : 삼각형이 보여지는 앞면이 아닌 뒷면이 화면을 향하고 있을때 삼각형이 그려지지 않도록 한다.

  6. Rasterization : Fragment를 출력한다.

  7. Fragment Shader : optional 단계이지만 대부분의 경우 사용되는 단계이다. GLSL로 작성된 프로그램은 각 Fragment의 최종적인 색깔을 계산한다.

  8. Per-Fragment(Per-Sample) Operations : Scissor Test, Stencil Test, Depth Test와 같이 유저가 활성화한 Test를 진행한다.

Transformation 파이프라인

Primitive 좌표의 일련의 수학적 변형에 중점을 둔 파이프라인

크게 3단계로 나뉜다.

  • ModelView Transformation : 점들을 Model space에서 View space로 이동시킨다.
  • Projection Transformation : 점들을 View space에서 정규화된 Projection space로 이동시킨다.
  • Viewport Transformation : 점들을 NDC(Normalized device coordinate)에서 Viewport(screen) space로 이동시킨다.

ModelView & Projection Transformation : Vertex shader에서 처리를 한다.
Viewport Transformation : Fragment shader 처리 이후에 실행된다.

ModelView Transformation 행렬

변환 과정은 행렬 연산을 통해서 처리되는데, 특히 모델의 점 좌표 변환은 이동, 크기 조정, 회전 행렬에 의해서 결정된다.

  • 이동 행렬 (Translation Matrix)
  • 크기 조정 행렬 (Scaling Matrix)
  • 회전 행렬 (Rotation Matrix)
    • x축 회전
    • y축 회전
    • z축 회전

OpenGL에서는 GLM 헤더 라이브러리를 이용해서 쉽게 변환 행렬을 사용할 수 있다.

예제 코드)

/* Rotating axis */
const static glm::vec3 up(0, 1, 0);
const static glm::vec3 right(1, 0, 0);
const static glm::vec3 backward(0, 0, 1);

/* matrix calculation */
glm::mat4 model = glm::translate(glm::mat4(1.0), position)
                * glm::scale(glm::mat4(1.0), scale)
                * glm::rotate(glm::mat4(1.0), rotation.x, right)
                * glm::rotate(glm::mat4(1.0), rotation.y, up)
                * glm::rotate(glm::mat4(1.0), rotation.z, backward);
profile
안녕하세요! 아쿠의 개발노트입니다

0개의 댓글