Software Development/Graphics

OpenGL Super Bible 그래픽스 공부하기 - 3. 파이프라인 따라가기 - 2) 테셀레이션

huiyu 2018. 1. 21. 11:39

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

Part 3 파이프라인 따라가기 - 2) 테셀레이션

 3.3 테셀레이션(Tessellation)

   - 고차 프리미티브(OpenGL에서는 패치)를 더 작고, 단순한 여러 개의 렌더링 가능한 프리미티브(삼각형)으로 분할하는 작업
   - 사각형, 삼각형, 선들을 더 많고 더 작은 점, 선, 삼각형 등으로 분할




  3.3.1 테셀레이션 컨트롤 쉐이더(Tessellation Control Shader, TCS)
    - 테셀레이션 첫번째 쉐이더
    - 테셀레이션 엔진에 보낼 테셀레이션 레벨 설정
    - 테셀레이션 이벨류에이션 쉐이더에 보낼 데이터 생성

* 테셀레이션 
  - 사전적의미 : 같은 모양의 조각들을 서로 겹치거나 틈이 생기지 않게 늘어놓아 평면이나 공간을 덮는 것을 말한다. 타일링, 타일깔기, 또는 쪽매붙임이라고도 한다. (출처 : 네이버사전, http://terms.naver.com/entry.nhn?docId=3340698&cid=55642&categoryId=55642)
  - 패치라고 불리는 고차 서피스를 점, 선, 삼각형으로 분할 하는 작업으로, 각 패치는 여러 제어점(Control Point)으로 만든다.

-> 패치당 제어점 개수는 변경이 가능,
  - glPatchParameteri()함수의 pname인자를 GL_PATCH_VERTICES로하고 value인자로 패치당 생성할 제어점 개수로 호출

1
void glPatchParameteri(GLenum pname, GLint value);
cs

 - 패치당 제어점 개수의 기본값은 3.
 - 테셀레이션이 활성화될 때, 테셀레이션 컨트롤 쉐이더는 제어점들의 그룹에 대해 배치로 수행
  이 때 각 패치의 크기는 패치당 버텍스 개수와 동일. 즉 버텍스들이 제어점으로 사용,
 버텍스쉐이더의 결과는 배치 형태로 테셀레이션 컨트롤 쉐이더의 입력으로 전달.
 *패치당 제어점 개수는 변경이 가능, 테셀레이션 컨트롤 쉐이더가 출력하는 제어점 개수가 소비하는 제어점 개수는 다를 수 있다.

레이아웃 지시어는 다음과 같이 사용, N은 패치당 제어점 개수

1
layout (vertices = N) out;
cs


* 테셀레이션 컨트롤 쉐이더는
  1)_출력 제어점의 값을 계산하는 일과
  2)_테셀레이션 엔진으로 보내는 결과 패치에 대한 테셀레이션 인자를 설정하는 일을 담당.(테셀레이션 레벨 설정)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#version 430 core
 
layout (vertices = 3) out;
 
void main(void)
{
    if (gl_InvocationID == 0)
    {
        gl_TessLevelInner[0= 5.0;
        gl_TessLevelOuter[0= 5.0;
        gl_TessLevelOuter[1= 5.0;
        gl_TessLevelOuter[2= 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
cs

 - layout (vertices = 3 ) out : 출력 제어점 개수를 3으로 설정, 입력 제어점의 디폴트 개수와 동일
 - gl_out[] = gl_in[] : 입력을 출력으로 복사, 
 - gl_TessLevelInner, gl_TessLvelOuter : 내부 및 외부 테셀레이션 레벨을 5로 설정
  * gl_TessLevelInner:내부 테셀레이션의 정도, 내부의 바둑반모양을 얼마나 나눌지? 정도
  * gl_TessLvelOuter : 외부 테셀레이션의 정도, 배열의 0,1,2는 각 요소의 변을 의미
 - gl_InvocationID : gl_in과 gl_out 배열의 인덱스, 패치 내의 제어점에 대한 0기반 인덱스


 3.3.2 테셀레이션 엔진(Tessellation Engine)

 - OpenGL 파이프라인의 고정함수, 패치로 표현되는 고차 서피스를 점, 선, 삼각형 같은 작은 프리미티브로 분할하는 역할 수행

 * 테셀레이션 컨트롤 쉐이더는 입력된 제어점을 처리하고, 패치를 분할하기 위한 테셀레이션 인자(레벨)을 설정한다. 테셀레이션 엔진이 출력 프리미티브를 생성한 뒤, 해당 버텍스들은 테셀레이션 이벨류에이션 쉐이더로 전달된다.

 * 테셀레이션 엔진은 테셀레이션 이벨류에이션 쉐이더 호출에 사용될 인자를 생성
 * 테셀레이션 이벨류에이션 쉐이더는 결과 프리미티브를 변환하여 라스터라이제이션 가능한 상태로 만든다.

*버텍스 쉐이더->테셀레이션(TCS->Tessellation Engine->TES)->라스터라이제이션


 3.3.3 테셀레이션 이벨류에이션 쉐이더 (Tessellation Evaluation Shader, TES)

 - 테셀레이션 엔진은 생성한 프리미티브에 대해 여러 출력 버텍스가 생성된다, 이를 테셀레이션 이벨류에이션 쉐이더로 전달
 - TES는 테셀레이터에 의해 생성된 각 버텍스에 대해 한번씩 호출하므로 테셀레이션 레벨이 높으면 TES가 많이 수행되어 성능에 주의해야 한다.

1
2
3
4
5
6
7
8
9
10
#version 430 core
 
layout (triangles, equal_spacing, cw) in;
 
void main(void)
{
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
                   gl_TessCoord.y * gl_in[1].gl_Position +
                   gl_TessCoord.x * gl_in[2].gl_Position);
}
cs

 - layout (triangles, equal_spacing, cw) : 테셀레이션 사용 모드 설정, 삼각형을 사용하며(triangle), 폴리곤 가장자리를 따라 동일한 간격으로 버텍스 생성(equal_spacing), 시계방향 버텍스 감기 순서 사용(cw)
 - gl_TessCoord : 테셀레이터가 생성한 버텍스의 무게중심 좌표
 - gl_in[].gl_Position : TCS의 gl_out구조체와 매칭, 원본 입력 삼각형 패치와 출력이 동일


728x90