[GPU] 그래픽스 파이프라인 (Graphics Pipeline)

By | 2018-08-11

대부분 물체 (Mesh)는 3D 형태이지만 우리가 보는 모니터는 2D만을 디스플레이(표시) 할 수 있다. 그래서 OpenGL/Vulkan 등의 그래픽 파이프라인(Graphic Pipeline)은 3D 좌표를 모니터에 출력 가능한 2D 형태로 변경하는 작업이다. 출처 1에서는 Graphics Pipeline은 특정 물체 (Mesh)의 포인트 및 색감(Texture)등을 입력으로 받아서 픽셀(Pixel) 단위로 표시하는 작업의 순서라고 정의하였다. (The graphics pipeline is the sequence of operations that take the vertices and textures of your meshes all the way to the pixels in the render targets). 보통 OpenGL/Vulkan을 배우면 크게 3D 좌표를 2D 좌표로 변경하는 과정과 2D 좌표를 사용하여 픽셀 색상을 그리는 작업부터 공부를 하게 된다 (Vertex/Fragment Shader).

그림 1: Graphics Pipeline 순서도 (출처1)

그림 1과 같이 Graphics Pipeline은  7개의 동작으로 구성된다. 모든 동작이 필수는 아니다. 그림은 출처 1, 2를 기준으로 다시 그린 그림이다. 그림의 동작 중 파란색으로 표시된 부분은 Fixed Function을 의미한다. Fixed Function 동작을Programming 해서 바꿀 수 없는 부분으로 보통 고정된 동작만을 수행한다. 동작 중 노랑색으로 표시된 부분은 Programming 가능한 부분이다. 다시 말해서 동작을 프로그래머가 변경할 수 있다. 각 동작에 대해서 짧게 정리를 해보았다.

추가: OpenGL 1.X에서는 모든 동작이 Fixed Function이여서 프로그래머가 Shader을 작성하는 것이 가능하지 않았던 것으로 안다. Shader을 프로그래머가 작성 할 수 있게 되면서 프로그래머가 더 효율적으로 GPU를 사용하여 연산을 할 수 있게 되었다. Shader는 보통 OpenGL Shading Language (GLSL)로 작성되어 진다.

Graphics Pipeline 동작 순서

  • Input Assembler: 단어에서 의미한 것처럼 단순히 사용자의 Input을 정리(Collect)하는 부분이다. Input은 Vertex Data (꼭짓점) 등을 의미한다. 예를 들어 삼각형을 그리고 싶으면 3개의 꼭짓점을 Input으로 주게 된다. 여러 개의 삼각형을 그린다면 꼭짓점 3개와 삼각형을 그리기 위한 추가적인 위치(Index) 정보가 될 수도 있다.
  • Vertex Shader: Vertex Data를 2D 화면 (Screen Space)로 변경하는 부분이다. 쉽게 생각해서 Input으로 들어오는 Vertex Data는 보통 3차원 (X, Y, Z)로 구성된다. 하지만, 우리가 눈으로 보는 모니터는 2D 화면을 보여준다. 그래서 3D Vertex 정보를 2D로 보이게 하려고 Vertex 정보를 수정한다.
  • Tessellation Shader: Mesh (물체)의 Quality(화질: 내 생각에는 원과 같은 걸 삼각형으로 나누어서 부드럽게 만들기 위한 것)를 높이기 위해서 특정 Rule에 따라 더 작은 삼각형(보통 삼각형으로 알고 있다)으로 나눈다. 예를 들어 큰 삼각형 하나가 들어오면 더 작은 단위의 삼각형 100개 또는 그 이상으로 나누는 단계이다. 여기서 특정 Rule이라고 설명을 하는데 아직은 어떠한 Rule 존재하는지 잘 모르겠다.
  • Geometry Shader: 설명에 따르면 모든 Primitive (삼각형, 선, 점)을 지우거나 추가하는 부분이다. 요즘은 성능적인 문제로 인해서 거의 사용하지 않는다고 한다. 하지만, Intel 내장 GPU에서는 좋은 성능을 보인다고 한다. 이 부분 제일 이해가 안 된다. 출처 2에 Advanced 과정에 상세한 설명이 있다. 추후 공부를 하게 되면 더욱 상세히 정리해볼 계획이다.
  • Rasterization Stage: 2D Screen Space로 변경된 포지션을 사용하여 Mesh (물체)를 Fragment (픽셀과 다른 의미)로 나누는 단계이다 (솔직히 글만 보면 무슨 의미인지 잘 모르겠다. 그림 등을 보고 적당히 추측했다). 위 그림처럼 삼각형에 들어가는 부분과 들어가지 않는 부분을 Fragment 단위로 나눈다. 이 부분에서 모니터 화면에 표시되지 않는 부분이나, 다른 Object/Mesh (물체) 뒤에 있어서 보이지 않는 Fragment 등을 제거하는 작업도 수행한다. Framebuffer에 이전의 Fragment Data 값들이 존재할 수 있다. 이 전에 존재하던 Framebuffer 값들과 비교해서 Framebuffer에 새로운 데이터로 Overwrite를 할 수 있다. 출처 3에 Rasterization에 대한 더 상세한 정보가 제공된다.
  • Fragment Shader: Rasterization에서 살아남은 Fragment의 색상 및 Depth 값을 계산하는 부분이다. 색상을 계산하기 위해서 빛 등을 고려해야 하는 부분이다. 복잡한 색상을 구현하기 위해서는 많은 수학적 지식이 필요한 부분이다. OpenGL을 배우면 금방 이해를 할 수 있다.
  • Color Blending: 이 단계 전까지는 Fragment와 Pixel을 같은 단위라고 생각했다. 아마도 Fragment가 Pixel보다 큰 단위인 것 같다. Fragment의 색상들을 비교하여 최종 색을 결정하는 단계이다. 한 픽셀 포인트에 대해 여러개의  Fragment 정보가 존재하면 두 개의 정보를 기준으로 Pixel 색상을 결정한다. 예를 들어 투명도에 따라 색상의 값들이 변경될 수 있다.

2D 좌표와 Pixel(픽셀)의 차이

  • 2D 좌표와 픽셀은 의미상으로 차이가 존재한다. 2D 좌표는 특정 포인트를 정확하게 표시하는 방법이고, 픽셀은 화면에 표시되는 대략적인 좌표를 의미하는 것이다. 대략 이해한 바에 따르면 2D 좌표는 물체의 정확한 위치를 의미하는 것이고, 픽셀은 모니터에 위치하는 하나의 Dot을 의미하는 것 같다.

Pixel vs. Fragment

  • 정확하게 비교를 한 곳이 없는 건지 영어를 못 해서 제대로 해석을 못 하는 건지 찾기가 쉽지가 않다. 출처 4에 따르면 Pixel은 단순히 Screen에 보이는 하나의 Dot을 의미한다. 반면 Fragment는 Framebuffer에 Write(쓰기)를 위해서 그보다 많은 정보를 담고 있다고 한다. 예를 들어 Depth, Alpha (투명도), Stencil, 등 다양한 정보를 모두 포함한 것을 Fragment라고 한다. 그래서 내가 느끼기에는 Pixel이란 우리가 보는 모니터에 보이는 Dot 하나 하나를 의미한다. 예를 들어 RGBA 정보를 표시하는 하나의 Dot이 Pixel이다. Fragment는 특정 물체를 그리는 과정에서 포함하고 있는 모든 정보를 의미하는 것 같다. 위 그림에서 볼 수 있듯이 Fragment는 Pixel의 집합일 수도 있고 Pixel 하나에 다양한 정보를 포함하면 Fragment가 될 수도 있는 것 같다. 만약 공부하다가 더 명확하게 이해가 되면 수정을 하겠다.

출처

  1. https://vulkan-tutorial.com/Introduction
  2. https://learnopengl.com/
  3. https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage
  4. https://gamedev.stackexchange.com/questions/8977/what-is-a-fragment-in-3d-graphics-programming

One thought on “[GPU] 그래픽스 파이프라인 (Graphics Pipeline)

  1. Admin Post author

    궁금해서 여기저기 물어보고 다녔는데 우선 화면에 출력되는 Pixel과 Pipeline에서 말하는 Pixel은 약간 다른 개념인 것 같다. 파이프라인에서 말하는 Pixel은 Fragment와 같은 개념인 것 같다. 결과적으로 Pipeline에서 Fragment는 Depth, RGBA, Stencil과 같은 모든 정보를 Pixel 단위로 가지고 있는 것 같다. Pipeline에서 연산이 끝나고 해당 결과물이 모니터 화면에 출력되는데 모니터에 표시되는 Dot 하나하나 또한 Pixel이라고 하는 것 같다.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *