개발/Graphics

OpenGL Super Bible 그래픽스 공부하기 - 3. 파이프라인 따라가기 - 4) 프리미티브 어셈블리, 클리핑, 래스터라이제이션

huiyu 2018. 1. 21. 14:12

OpenGL Super Bible 그래픽스 공부하기 - 1. OpenGL 기본개념이해
OpenGL Super Bible 그래픽스 공부하기 - 2. 첫번째 OpenGL 프로그램
OpenGL Super Bible 그래픽스 공부하기 - 2-3. 처음 그리는 삼각형
OpenGL Super Bible 그래픽스 공부하기 - 3. 파이프라인 따라가기 - 1) 쉐이더간 데이터 전달
OpenGL Super Bible 그래픽스 공부하기 - 3. 파이프라인 따라가기 - 2) 테셀레이션
OpenGL Super Bible 그래픽스 공부하기 - 3. 파이프라인 따라가기 - 3) 지오메트리 쉐이더

Part 3 파이프라인 따라가기 - 4) 프리미티브 어셈블리, 클리핑, 래스터라이제이션

3.5 프리미티브 어셈블리, 클리핑, 래스터라이제이션

  - 파이프라인의 프론트엔드(버텍스 쉐이딩, 테셀레이션, 지오메트리 쉐이딩)가 수행된 후엔 파이프라인의 고정함수가 작업 수행
  1) 프리미티브 어셈블리 : 버텍스들을 라인과 삼각형으로 그룹화
  2) 클리핑 : 보이는 영역 클리핑, 보이는 영역이란 보통 윈도우나 화면을 위미하지만 뷰포트라 불리는 더 작은 영역일 수 도 있다.
  3) 래스터라이저 : 어떤 픽셀들이 프리미티브에 의해 가려지는지 결정, 그 픽셀들의 목록을 프래그먼트 쉐이더로 전달


3.5.1 클리핑
 - 버텍스들이 버텍스 쉐이더를 떠날 때 그 위치는 클립공간에 있다고 한다. 이는 위치를 나타내는 좌표계 중 하나이다.
 - 이전 쉐이더에서 gl_Position 변수에 저장할 때 다입은 vec4 타입이었다. 이는 모두 4요소 벡터이다. 이것이 바로 동차좌표(Homogeneous Coordinate)라고 한다.
 * 동차좌표 : n차원의 공간을 n+1좌표로 나타내는 좌표계, 3차원 공간을 4요소 변수로 표현한다. 4차원으로 표현함으로써 이동,크기,회전을 담은 4x4행렬을 행렬의 곱으로 표현이 가능하다.

 - 이전에 4요소 동차 좌표로 저장을 해두었지만, 클리핑은 카테시안 공간에서 수행된다.
  *카테시안 공간, 카테시안 좌표(=직교 좌표계) 말이 어렵다.. 카테시안은 일반적으로 학교다닐 때 배운 직교좌표계를 의미한다.
   3차원은 x,y.z 이며 2차원은 x,y로 표현한다.

 - 직교좌표계에서 수행하므로 이전에 받은 4차원 벡터를 원근 나눗셈을 수행한다. 이는 그 위치를 마지막 요소인 w로 나누는 작업을 의미.
  * 지금까지 모든 예제는 w를 1.0으로 설정, 즉 나눗셈에 대한 효과가 없어 동차 공간의 버텍스를 직교 공간으로 투영하는 효과가 있다고 한다. 1이 아닌 값에 대한 설명은 후반부에 나온다고 한다.

-> 원근 나눗셈 이후의 결과 위치는 정규화된 디바이스 공간에 위치하게 된다.
  x: -1.0 ~ 1.0,   y : -1.0 ~ 1.0,  z: 0.0 ~1.0, 이 공간이 사용자에게 보이는 영역이며, 바깥은 무시된다.
 * 모든 평면은 좌표 공간을 둘로 나눈다. 안쪽과 바깥쪽(그래서 반공간, half-space라고 한다). 클리핑을 통해 나뉜 여섯면 중 버텍스가 안쪽에 위치하면 그리고, 바깥쪽에 위치하면 모두 버려진다.

3.5.2 뷰포트 변환
 - 클리핑 후 모든 버텍스의 좌표는 정규화된 디바이스 좌표를 갖게 된다. (x: -1.0 ~ 1.0,   y : -1.0 ~ 1.0,  z: 0.0 ~1.0)
 - 하지만, 실제 그릴 대상 윈도우는 좌하단(0,0)이고, 영역이 (w-1, h-1)인 좌표를 갖고 있다.
 ->이러한 지오메트리를 윈도우 속으로 넣기위해 뷰포트변환을 수행한다.
   *이 변환은 스케일과 오프셋을 적용하여 버텍스들을 디바이스 좌표에서 윈도우 좌표로 이동시키는 일을 수행한다.
    -> glViewport(), glDepthRange()를 통해 설정 가능, 아래와 같은 식을 수행한다.

3.5.3 컬링(Culling)

 - 삼각형을 처리하기 전 선택으로 거치는 스테이지
 - 삼각형이 정면을 향해 있는지 아니면 뷰어와 반대 방향인지 결정, 이를 토대로 계속 그릴지 결정
 - 만약 뷰어와 같은 방향을 향한다면 정면방향, 그렇지 않으면 후면 방향이 된다.
 - 삼각형이 정면인지 후면인지 결정하기 위해 윈도우 공간에서 양의면적을 결정한다. 삼각형의 면적을 결정하는 방법은 두 모서리의 외적을 계산 하는 것이다.
 -> 만약 면적의 양이 값이면 정면, 음의 값이면 후면 방향이다.
 -> glFrontFace()함수를 통해 dir 값을 GL_CW, GL_CCW로 설정 가능(시계, 반시계)

- 기본적으로 OpenGL은 방향에 상관없이 모든 삼각형을 렌더링한다.
 컬링을 활성화 하기 위해선 glEnable()함수의 cap인자를 GL_CULL_FACE로 설정하면 된다.
 그리지 않을 타입을 변경하기 위해선, glCullFace()함수의 face인자를 GL_FRONT, GL_BACK, GL_FRONT_AND_BACK으로 설정하면 된다.
 * 점과 선은 면적을 갖지 않으므로 컬링이 수행되지 않는다.

3.5.4 래스터라이제이션(Rasterization)

 - 프래그먼트들이 어떤 선이나 삼각형에 의해 채워지는 지 결정
 - 반공간 기반 방식 사용, 이는 병렬화 구현에 적합
 - 윈도우 좌표상에서 삼각형에 대한 바운딩 박스 구하고 그 안의 모든 프래그먼트가 삼각형 안쪽에 있는지 바깥쪽에 있는지 검사.


728x90
반응형