공사중

[SB] 전체적인 흐름 짚어보기 본문

개발 | OpenGL/OpenGL Super Bible

[SB] 전체적인 흐름 짚어보기

행운개발자 LuckyDeveloper 2019. 2. 26. 20:38

openGL이란?

openGL의 GL은 Graphics Library를 의미합니다. openGL은 애플리케이션이 그 하부에서 동작하는 장치의 그래픽스 서브시스템에 접근하고 제어하기 위해 사용하는 인터페이스입니다. 서브시스템에 대한 인터페이스를 표준화하면 다양한 플랫폼에 대해서 고민하는 것이 아니라, 흥미로운 컨텐츠를 개발 하는데 집중할 수 있습니다. 이렇게 표준화된 Application Programming Interface를 API라고 부르고 openGL은 API입니다.

openGL의 목표

openGL의 목표는 애플리케이션과 그 하부의 그래픽스 서브시스템의 추상화 레이어를 제공하는 것입니다. 이 말은 그래픽스 서브시스템을 구성하는 그래픽스 프로세스 유닛(GPU)의 제작사가 어디인지, 어떻게 동작하는지, 성능이 어떤지 알 필요가 없다는 것을 의미합니다.

추상화 수준은 충분히 낮아서 프로그래머들이 기반 하드웨어에 접근하고 최대한 활용(고급 그래픽스 하드웨어의 기능을 사용)할 수 있도록 만들어저야하며, 원하는 모델에 적합한 프로그램을 쉽도록 해야합니다. 저 개인적으로는 하드웨어를 잘 다루어 본 적이 없어서 좀 어렵게 느껴집니다. 하지만 충분히 함수의 설명을 읽어보면 어떤 기능을 하는 것인지 알 수 있습니다.

데이터 전달 순서

프로그램을 구성하는 명령어 집합들은 openGL에게 보내져서 하부의 그래픽스 하드웨어(GPU)로 전달됩니다. 전달된 명령어들은 순차적으로 진행되는 것이 아니라 동시다발적으로 진행됩니다. 따라서 한 픽셀을 결정하는 과정은 다른 픽셀의 값이 결정되는 과정에 영향을 주거나 받지 않습니다. 이것을 파이프라인 분할과 병렬화라고 합니다.

쉐이더란?

현재 GPU에서 실행되는 프로그램은 Shader라는 것에 의해서 실행됩니다. Shader는 다수의 쉐이더 코어들로 이루어져있습니다. 쉐이더 코어는 프로그래밍이 가능한 작은 프로세서입니다. 각 코어는 상대적으로 처리량이 낮고, 쉐이더의 명령어 하나를 수행하기 위해서 여러 클록 사이클을 돌아야합니다. 하지만 수십에서 수천개의 코어들이 모여서 그럴듯한 성능을 만들어냅니다.

스테이지

그래픽스 시스템은 여러 스테이지로 나뉩니다.
  1. 버텍스 패치
  2. 버텍스 쉐이더
  3. 테셀레이션 컨트롤 쉐이더
  4. 테셀레이션
  5. 테셀레이션 이벨류에이션 쉐이더
  6. 지오메트리 쉐이더
  7. 래스터라이제이션
  8. 프래그먼트 쉐이더
  9. 프레임버퍼 동작
노란색으로 된 부분은 고정 함수 스테이지이고, 초록색으로 된 부분은 프로그래밍이 가능한 스테이지입니다. 프로그래밍이 가능한 부분에서 우리가 작성한 셰이더를 사용되는 스테이지입니다. 앞으로 각각의 스테이지들을 업로드할 계획입니다.

짧게보는 역사

08년에 openGL은 두 가지 프로파일로 분리되었습니다. 하나는 코어프로파일, 나머지는 호환성 프로파일입니다. 전자는 현대 그래픽스 하드웨어로 가속하지 못하는 많은 기존의 기능을 제거한 것이고, 후자는 OpenGL Version 1.0까지의 모든 버전과 하위 호환성을 유지합니다. 따라서 전자는 후자보다 양이 크게 줄어들었습니다. 동일한 기능을 하는 코드를 작성했을 때 전자가 후자보다 빠르며, 후자에는 남아있지만 전자에서는 사라진 기능들은 그만한 이유가 있기 때문에 사라진 것입니다. 따라서 앞으로 배울 모든 내용들은 코어 프로파일에 관한 것이며 호환성 프로파일은 이제 언급하지 않을 것입니다.

Primitive, pipeline, pixel

이전 포스트에서 알아봤듯이 openGL은 여러 단계은 스테이지를 순차적으로 진행합니다. 하지만 각 데이터들이 처리되는 방식은 순차방식아니라 파이프라인을 사용한 병렬적 처리 방식입니다. 각 단계 안에서 버퍼나 텍스쳐와 같은 파일로부터 추가적인 데이터를 받아 처리하고 최종 파이프라인으로 전달합니다. 이런 일련의 과정을 랜더링이라고 부릅니다.
랜더링의 기본 단위는 primitive라고 부릅니다. 세 가지 기본 렌더링 가능 primitive는 점, 선, 삼각형입니다. 우리의 눈에 보이는 결과는 모두 이들의 조합이라고 볼 수 있습니다. 복잡한 surface를 수 많은 삼각형으로 분할하고 openGL에 보내서 Rasterization(아래 그림)을 진행합니다. Rasterization은 3차원으로 표현된 삼각형을 화면에 그려질 일련의 픽셀로 변환하는 전용 하드웨어입니다.



Vertex

당연하게도 openGL은 3차원 공간에서 그림을 그릴 수 있습니다. 3차원 공간에서 삼각형을 그릴 때는 x,y,z 좌표를 가지는 3개의 점이 필요합니다. 이 각각의 점들을 Vertex라고 부릅니다. 점, 선, 삼각형은 각각 1,2,3개의 vertex로 이루어져있는 것입니다.

프론트엔드와 백엔드

그래픽스 파이프라인은 프론트엔드와 백엔드로 나누어집니다. 프론트에서는 vertex들을 rasterizer에 보내는 역할을 합니다. 이를 Primitive Assembly라고도 합니다. 이전 포스팅의 스테이지를 참고해서 보시면, 지오메트리 셰이더의 결과물이 Rasterization에 입력되는 것을 알 수 있습니다. Rasterization의 입력은 Geometry, 출력은 pixel입니다. 이 출력은 백엔드로 전달됩니다. 백엔드에서는 깊이 및 스텐실테스트, 프래그먼트 쉐이딩, 블랜딩, 출력 이미지 갱신등이 이루어집니다.