Output Merger
이전 포스팅에서는 Fragment shader에서 진행되는 대표적인 작업인 texturing 과 lighting에 대해서 알아보았다.
Fragment shader를 거치고 나면 각각의 fragment는 색상 값을 할당을 받게 된다. Fragment의 output은 RGBAZ fragment 라고도 한다(A : alpha, Z : depth). 그러면 이 색상은 곧 바로 스크린에 보여지는 것이 아니라 Output merger 단계를 거쳐야 한다. Output merger는 fragment를 스크린에 찍을건지 안찍을건지, 어떻게 변형시켜서 보여줄지를 결정한다.
fragment 색상은 어찌됐건 위 그림의 viewport(실제로 스크린에 보여질 영역) 안에서 계산이 된다.
Color & Depth Buffers
이제는 마지막 작업인 Output merger 에서 진행되는 작업에 대해 배워보자. Output merger에서는 마지막 내용들을 병합하여 출력한다.
즉, Viewport에 있는 object를 스크린에 어떻게 표현 하는지를 담당한다.
스크린에 보여질 영역을 보관하고 있는 버퍼는 3가지가 있다.
Color buffer, Depth buffer, Stencil buffer 총 3가지가 있고 이를 Frame buffer라고도 한다.
Color buffer는 이름 그대로 스크린에 나타날 픽셀들을 잠시 보관하는 곳이다.
viewport가 해상도를 w x h 로 가질 때, Color buffer는 w x h 해상도를 가지고 있을 것이다.
Depth buffer는 Color buffer에 저장된 픽셀들의 z값을 가지고 있는 것이다. 그리고 두 버퍼는 당연히 해상도가 같다.
Z-buffering
먼저 z 버퍼링은 물체들이 겹쳐 있을 때 (같은 x,y 값을 가진 물체가 여러개일 때) 어떤 object를 표현할까에 대한 것이다. GL은 깊이 버퍼(z 버퍼)를 제공하기 때문에 당연히 z값이 작은, 즉, 카메라(눈)과 가까이 있는 물체만 출력하게 된다.
위 Viewport의 앞 z 좌표는 0, 뒤는 1이다.
그리고 빨간, 파란 삼각형이 있고 평면에 나란하다. 파란 삼각형의 z 값은 0.5이고 빨간 삼각형의 z 값은 0.8이다.
이러한 가정 하에 빨간 삼각형을 먼저 그리고 그 다음에 파란 삼각형을 그리는 것을 생각해보자.
랜더링을 하기 위해서 z buffer와 color buffer를 초기화한다. 그러면 모든 원소들이 다 1.0 값(투명)을 갖는다. 그리고 Viewport 백그라운드의 색깔을 하얀색으로 가정하자. 그 다음에 빨간색 삼각형을 그려보자.
빨간색 삼각형이 산출한 모든 fragment마다 z값을, 현재의 z buffer의 fragment와 모두 비교한다. 0.8로 나온 것을 볼 수 있다. 그 말은 빨간색 fragment가 백그라운드 하얀색 픽셀보다 앞에 있다는 것이다. z값이 작기 때문이다.
마찬가지로 파란색 삼각형을 처리하면 빨간색 삼각형 위에 겹치는 부분이 있고, 파란색 fragment가 z값(0.5)이 작게 나올 것이다. 더 앞에 있기 때문이다.
파란색 삼각형을 먼저 처리해도 똑같이 그려진다. z 값을 통해서 알 수 있다.
어떤 것을 먼저 처리해도 상관 없다. 즉, 렌더링 순서는 중요한 것이 아니다. 이것이 Z Buffer의 장점이다.
이것이 Output merger가 수행하는 굉장히 중요한 연산이다.
Alpha Blending
하지만 물체가 완전히 불투명한 경우가 아니라면 어떨까?
물체의 투명도는 Fragment shader의 output인 RGBAZ 중, a값(알파값)을 통해 표현한다. 이렇게 a값이 주어진 경우 앞에 있는 물체 뿐 아니라 뒤 물체도 표현을 해야 한다. a값도 0과 1사이의 값을 가진다. 극단적으로 이상적으로 투명한 유리의 경우 a값이 1이 된다. 반대로 위에서 다룬 완전히 불투명한 물체의 경우 a값이 0이 된다.
a값이 0보다 크고 1보다 작은 투명/반투명한 물체들에 대해서는 어떻게 screen에 표현해야 할까?
C= aCf+(1-a)Cp 가 된다.
cf는 이름 그대로 fragment color 이다. 즉, rgb 색깔을 갖는다. Fragment shader에서 출력된 a 값이 계수로서 붙는다.
cp는 color buffer의 픽셀이다. 이것도 rgb 색깔을 갖는다. 여기에는 1-a 값이 계수로서 붙는다.
위 예제처럼 앞에 있는 (z=0.5)파란 삼각형의 a =0.5이고 뒤에 있는 빨간 삼각형의 a=1일 때, 표현되는 색상의 rgb값은 (0.5, 0, 0.5)가 된다.
z 버퍼링의 경우 처리 순서에 독립적이다. 어떤 object에 대해서도 순서는 중요하지 않고 단순히 z값이 가장 작은 물체를 찾으면 된다. 즉 일반적인 searching 문제가 된다. 하지만 transparent/ translucents 한 물체에 대해서는 순서가 중요하다. 물체가 여러개인 경우 순서에 따라 처리가 달라지기 때문이다.
때문에 뒤에 있는 물체부터 앞에 있는 물체의 순서대로 그려야 Alpha blending이 잘 처리된다.
C= aCf+(1-a)Cp 식을 쓸 수 있는 것은 뒤에서부터 물체 처리를 하기 때문이다.
즉, 이를 위해선 삼각형들의 정렬(sorting)이 필요하다. 적절한 알고리즘을 쓰면 된다.
지금까지 물체가 어떻게 object space에서 생성되고 이동하고 결합되고 스크린에 표현되는지에 대해 배웠다.
Ref.
Introduction to Computer Graphics with OpenGL ES (J. Han)
'☘️ Computer Graphics > Fundamental' 카테고리의 다른 글
CG - Screen space Object Manipulation (0) | 2022.07.22 |
---|---|
CG - Euler Transforms and Quaternion (0) | 2022.07.21 |
CG - Lighting (0) | 2022.07.19 |
CG - Image Texturing (0) | 2022.07.18 |
CG - Rasterizer (0) | 2022.07.16 |