일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- I/O장치
- 멀티프로세서
- 락
- 그리디알고리즘
- DirectX 12
- 스케줄링
- 렌더링 파이프라인
- 영속성
- 디자인패턴
- DirectX12
- OS
- 병행성
- 동적계획법
- 병행성 관련 오류
- 타입 객체
- 파일시스템 구현
- 프로그래머스
- 알고리즘
- 쓰레드
- 다이나믹프로그래밍
- 자료구조
- 백준
- Direct12
- codility
- directx
- 멀티쓰레드
- 그리디 알고리즘
- 운영체제
- 컨디션 변수
- 다이나믹 프로그래밍
- Today
- Total
기록공간
[DirectX 12] 렌더링 파이프라인 - 3 본문
테셀레이션 단계들
테셀레이션은 주어진 메시의 삼각형들을 더 잘게 쪼개서 새로운 삼각형들을 만드는 과정을 말한다. 새 삼각형들을 새로운 위치로 이동함으로써 원래 메시에 없는 세부적인 특징을 만들어 낼 수 있다.
테셀레이션은 여러 장점이 있다.
1. 카메라에 가까운 삼각형들에는 테셀레이션을 적용해서 세부도를 높이고, 먼 삼각형들에는 테셀레이션을 적용하지 않는 방식의 세부 수준(Level-Of-Detail, LOD)을 구현할 수 있다. 이렇게 하면 관찰자가 실제로 볼 수 있는 부분에만 많은 삼각형을 사용하게 되므로 효율적이다.
2. 적은 수의 삼각형들로 이루어진 메시를 메모리에 담아두고 즉석으로 삼각형을 추가하여 메모리를 절약할 수 있다.
3. 애니메이션이나 물리 처리 같은 연산들을 단순한 저 다각형 메시에 대해 수행하고, 테셀레이션 된 고 다각형 메시는 렌더링에만 사용함으로써 계산량을 줄일 수 있다.
테셀레이션 단계들은 Direct3D 11에서 새로 도입되었다. 이 단계들은 기하구조를 GPU에서 테셀레이션하도록 수단을 제공한다. Direct3D 11 이전에는 이를 구현하려면 CPU에서 삼각형들을 분할하여 새로운 기하구조를 만들고, 그것을 GPU에 올려 렌더링해야 했다. CPU에서 이러한 계산과 GPU 메모리에 정보를 올리는 과정은 비용이 많이 든다. 그래서 Direct3D 11 이전에는 테셀레이션을 많이 쓰지 않았다. 하지만 Direct3D 11이 제공하는 API를 이용하면 테셀레이션이 전적으로 하드웨어에서 일어난다.(단 하드웨어가 Direct3D 11 이상을 제공해야 한다)
테셀레이션 단계들은 꼭 필요한 단계가 아니기 때문에 생략이 가능하다. 또한 수학적인 내용이 많이 들어가 이해가 까다로울 수 있다. 그래서 테셀레이션은 보통 DirectX를 배울때 후반부에 공부하게 된다.
기하 셰이더 단계
기하 셰이더 단계도 선택적인 단계이기 때문에 생략이 가능하다. 이것 또한 후반부에 공부하게 되므로, 여기서는 간단하게 소개만 한다. 기하 셰이더는 하나의 기본 도형을 입력받아 그것을 임의로 변형한다. 예를 들어 삼각형 목록을 그리는 경우 기하 셰이더에는 삼각형을 정의하는 (Vertex Shader 단계를 거친) 정점 세 개가 입력된다. 기하 셰이더의 주된 장점은 기하구조를 GPU에서 생성하거나 파괴할 수 있다는 것이다. 예를 들어 입력 기하구조를 여러 개의 기하구조로 확장할 수도 있고, 입력 기하구조를 조건에 따라 폐기할 수도 있다. 기하 셰이더의 흔한 용도는 점이나 선분을 사각형으로 확장하는 것이다.
또한 기하 셰이더의 출력은 스트림 출력 단계를 통해 메모리의 버퍼에 저장해 두고 나중에 활용하는 것이 가능하다. (이는 고급 기법이다)
절단
완전히 시야 절두체 바깥에 있는 기하구조는 폐기해야 하며, 절두체의 경계면과 교차하는 기하구조는 절두체 내부의 것만 남도록 잘라내야 한다. 이를 절단(clipping) 연산이라고 부른다. 다음은 이 개념을 2차원으로 나타낸 것이다.
시야 절두체를 여섯 개의 평면(상하좌우, Near, Far)을 경계로 하는 영역이라고 생각할 수 있다. 다각형을 하나의 평면으로 절단한다는 것은, 다각형 중 평면의 양의 공간(밑 그림 n부분)에 있는 부분을 남기고 음의 공간에 있는 부분은 폐기하는 것을 뜻한다. 볼록 다각형을 평면으로 절단하면 항상 볼록 다각형이 남는다.
이 절단 연산은 하드웨어가 수행해 준다. 이 절단 알고리즘의 자세한 내용은 서덜런드-호지먼 절단 알고리즘(Sutherland_Hodgeman clipping algorithm)을 살펴보자. (영문)
래스터화 단계
래스터화기 단계(rasterizer stage)라고도 하는 래스터화 단계의 주 임무는 투영된 3차원 삼각형으로부터 픽셀 색상들을 계산하는 것이다.
뷰포트 변환
원근 투영변환을 마치고 나면 하드웨어에서 원근 나누기를 수행해서 정규화된 좌표공간으로 변환된다. 이 공간은 점들의 2차원 x, y 좌표 성분들이 후면 버퍼의 한 직사각형 영역으로 변환된다. 그 직사각형 영역이 바로 뷰포트이다.
뷰포트 변환을 마치고 나면 x, y 성분은 픽셀 단위의 값이 된다. 일반적으로 뷰포트 변환 시 z 성분은 깊이 버퍼링에 사용해야 하기 때문에 변경되지 않는다. 그러나 MinDepth와 MaxDepth를 변경하여 깊이 값에 영향을 줄 수는 있다. 이 값들은 반드시 0 ~ 1 이여야 한다.
후면 선별
하나의 삼각형에는 면이 두 개 있다. 두 면을 구분하기 위해 Direct3D에서는 다음과 같은 방법을 사용한다.
삼각형 정점들이 v0, v1, v2의 순서로 감긴다고 할 때, 삼각형의 법선은 다음과 같이 정의된다. 이 법선이 가리키는 방향이 삼각형의 앞쪽(front side)에 해당하고, 그 반대 방향은 삼각형의 뒤쪽(back side)이다. 삼각형의 앞쪽이 관찰자에게 보이는 면이고, 뒤쪽은 관찰자에게 안 보이는 면이 된다. 이 법선은 어떻게 판별할까?
v1 - v0 벡터와 v2 - v0 벡터를 외적 하면 그 삼각형의 법선벡터를 구할 수 있다. 위 삼각형의 경우는 그 결과물이 앞쪽을 가리킨다. 그 이유는 현재 정점 v0, v1, v2가 시계 방향으로 배치되어 있기 때문이다. 이 삼각형을 반대서 바라본다면, 이 정점 배치는 반시계 방향이 된다. 그럴 경우 이 삼각형의 법선 벡터는 아까와 반대의 값이 나온다. 결국 바라보는 방향에서의 정점 배치에 따라 법선 벡터의 방향이 달라지고 그 방향을 기준으로 삼각형이 전면에 있는지 후면에 있는지를 결정한다.
물체를 구성하는 삼각형들의 법선이 항상 물체의 바깥쪽을 향하도록 물체의 모형을 만든다고 가정하자. 그러면 카메라에는 다면체의 후면 삼각형들이 보이지 않는다. 후면 삼각형들은 모두 전면 삼각형들에 가려지기 때문이다. 그래서 후면 삼각형은 그릴 필요가 전혀 없으므로 파이프라인에서 후면 삼각형을 골라서 폐기하는 공정을 후면 선별(backface culling)이라고 부른다. 후면선별을 하면 파이프라인이 처리해야 할 삼각형의 수가 절반으로 줄어들 수 있다.
정점 특성의 보간
뷰포트 변환을 거친 후에는 정점의 특성들을 삼각형을 덮는 각 픽셀에 대해 보간해야 한다. 다음은 레스터화기에서 픽셀의 색상을 보간하는 예이다. 각 정점의 색상이 있으면 삼각형에서 비어있는 각 픽셀에 대해서 보간을 해준다.
픽셀 셰이더 단계
픽셀 셰이더(pixel shader, PS)는 프로그래머가 작성하고 GPU가 실행하는 프로그램이다. 픽셀 셰이더는 각각의 픽셀에 대해 실행된다. 기본적으로 픽셀 셰이더는 보간된 정점 특성들을 입력받아서 하나의 색상을 출력한다. 픽셀 셰이더는 그냥 고정된 상수 색상을 돌려주는 것에서부터 조명, 반사, 그림자 효과 등 더 복잡한 작업을 수행하는 것까지 아주 다양하다.
출력 병합기 단계
픽셀 셰이더가 생성한 픽셀 단편들은 렌더링 파이프라인 출력 병합기(output merger, OM) 단계로 입력된다. 이 단계에서 일부 픽셀 단편들이 폐기될 수 있다. (깊이 혹은 스텐실 판정에 의해)
폐기 되지 않은 픽셀 단편들은 후면 버퍼에 기록된다. 혼합(Blending)도 이 단계에서 일어난다. 혼합 또는 블렌딩은 새 픽셀이 후면 버퍼의 기존 픽셀을 완전히 덮어쓰는 것이 아니라 두 픽셀을 일정한 공식에 따라 섞은 결과를 기록하는 것을 말한다. 혼합은 반투명과 같은 특수 효과를 내는 데에 쓰인다.
'DirectX > 기초' 카테고리의 다른 글
[DirectX 12] Direct3D 그리기 연산(정육면체) - 2 (0) | 2020.04.30 |
---|---|
[DirectX 12] Direct3D 그리기 연산(정육면체) - 1 (0) | 2020.04.28 |
[DirectX 12] 렌더링 파이프라인 - 2 (8) | 2020.04.09 |
[DirectX 12] 렌더링 파이프라인 - 1 (0) | 2020.04.07 |
[DirectX 12] Direct3D 초기화 - 3 : 시간 측정 (타이머) (0) | 2020.03.23 |