💡 3차원 장면의 기하학적 서술과 가상 카메라의 위치 및 방향이 주어졌을 때, 가상 카메라에 비친 모습을 2차원 이미지로 생성하는 일련의 과정
💡 메모리에서 기하 자료(정점, 인덱스)를 읽어 기하학적 도형을 조립
→ 정점 데이터를 입력 받아 점 버퍼와 인덱스 버퍼를 생성, 정점 버퍼에 전달해 도형을 그림
→ CPU에서 버퍼라고 부르는 메모리에 필요한 정보를 담아 GPU로 전달
입력된 정점의 정보를 토대로 도형을 형성하는 방식을 Direct3D에게 전달한다.
여러 설정값에 따라 기본도형인 선과 삼각형을 어떻게 그려지는지 다르다.
ex ) 점 목록, 선 띠, 선 목록, 삼각형 띠…
다양한 위상구조를 사용해 도형을 그려도 모형이 세밀하고 복잡할수록 중복되는 정점도 많아진다.
이는 '메모리 요구량이 커지고' 'GPU의 처리량이 증가'하는 이유로 비효율적인데, 이를 해결하기 위해 어떤 순서로 정점들을 이어서 삼각형을 그릴지 알려주는 "인덱스 목록"을 사용한다.
💡 IA에서 받은 정점들의 정보를 전달받아 출력하는 함수들을 실행
→ 변환, 조명, 변위 매핑같은 특수 효과를 이곳에서 수행
각각의 물체를 자기 자신의 중심을 기준으로 구축되는 것을 '로컬 좌표계', 보여지는 장면 전체의 좌표계를 기준으로 구축하는것을 '월드 좌표계' 라고 한다.
보통 좌표계 원점을 물체의 중심 가까이에 두고 정렬하고 이를 월드 좌표계로 투영해 이동, 회전 시키는 과정을 '월드 변환'이라 한다.
굳이 이렇게 로컬 좌표로 구성하고 월드 좌표로 변환하는데는 장점이 있는데,
1. 모형을 로컬 좌표계로 정의하는것이 중심이 원점과 일치하고 주축중 하나와 대칭이라 쉽고
2. 여러 씬에서 재사용되는 물체를 매번 재계산하는 것보다 씬마다 월드로 변환해 적용하는 것이 이득이다.
3. 비슷한 이유로 같은 씬에서 다른 방향, 위치, 회전값이 적용된 물체도 동일한 정점, 인덱스 목록만 가지고 각각의 회전, 위치, 크기를 정의하는 월드 변환을 통해 생성하는 '인스턴싱' 기법도 유효하다.
이렇게 변환을 거쳐 월드에 생성된 물체들을 가상의 카메라를 통해 관찰하는 듯 모니터에 비추는데, 이 카메라의 로컬 좌표를 'View Space, 시야 공간' 이라 부른다.
월드 행렬을 또 한번 시야 공간으로 좌표 변환 하면 '시야 행렬, View Matrix'가 생성된다.
월드 공간에서 시야 공간으로 변환하는 것을 '시야 변환'이라 하고 이때 쓰이는 행렬은 '시야 행렬'이라 부른다.
하지만 직접 쓰이는 행렬은 시야 행렬이 아니라 반대 방향의, 월드 공간에서 시야 공간으로의 변환 행렬인데 즉 시야 행렬의 역행렬이다.
XMATH 라이브러리에 시야 행렬을 계산하는 원리에 맞게 작성한 함수가 제공된다.
XMMAATRIX XMatrixLookAtLH(
FXMVECTOR EyePosition, // 입력 카메라 위치
FXMVECTOR FocusPosition, // 입력 대상 점 T
FXMVECTOR UpDirection); // 입력 월드 업 벡터
// 카메라가 월드 공간의 (3, -10, 3)에서 (3, 3, 3)을 바라보는 코드
XMVECTOR pos = XMVectorSet(3, -10, 3);
XMVector target = XMVectorZero();
XMVector up = XMVector(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
스크린에 그리는 눈, 카메라를 구성하는 요소가 하나 더 있는데 바로 흔히 '절두체'라 부르는 공간 영역이다.
스크린은 2D이기 때문에 3D 세계를 2D로 만드는 것을 '투영'이라 부르며 두가지 종류가 있고
원근(Perspective) 투영은 하나의 3차원 정점을 스크린에 해당하는 2D 평면과 만나는 점으로 변환하는 것이다.
그림과 같이 먼평면을 작게 만들어 가까운 평면으로 만든다는 의미로 머리가 없는 삼각형이라 해 절두체라 부르곤한다.
먼 평면의 점을 가까운 평면의 점으로 투영하면 투영 창의 크기가 종횡비에 의존하는 문제가 발생하는데
하드웨어가 투영 창의 크기가 관여하는 연산을 수행하려면 하드웨어가 종횡비를 알려줘야 한다.
이 의존성을 없애고 작업을 수월하게 만들기 위해 절두체의 투영 구간인 [ -r, r ] 구간을 [ -1, 1 ]로 비례시킨 점의 좌표를 정규화 디바이스 좌표, NDC라 부른다.
이 과정을 거쳐 만들어진 NDC 좌표에서는 투영 창의 크기가 고정되어 있기 때문에 하드웨어는 종횡비를 몰라도 된다.
하지만 프로그래머는 실제로 NDC 공간을 기준으로 한 투영 좌표를 신경 써야 한다.
깊이 성분도 마찬가지로 z 좌표를 [ 0, 1 ]로 정규화된 구간을 원하는데 이를 위해 '순서 보존 함수'를 만들 필요가 있다.
순서 보존 함수는 Z1 < Z2 면 g(Z1) < g(Z2)를 만족하는 상대적 관계가 유지되는 변환함수를 말한다.
한번의 비례 연산과 이동 연산을 거쳐 구해진 함수를 추가하면 원근 투영 행렬이 구해진다.
마찬가지로 XNA Math 라이브러리에 원근투영 행렬을 제공하는 함수가 있다.
XMMATRIX XMMatrixPerspectiveFovLH(
FLOAT FovAngleY, // 수직 시야각
FLOAT AspectRato, // 종횡비 = 너비 / 높이
FLOAT NearZ, // 가까운 평면까지의 거리
FLOAT FarZ); // 먼 평면까지의 거리
// 시야각 45도, 가까운 명면은 z = 3, 먼 평면은 z = 100에 둔 사용법
XMMATRIX P = XMMatrixPerspectiveFovLH( 0.25f * MathX::Pi, AspectRatio(), 3.0f, 100.0f);
float DirectX::AspectRatio() const
{
return static_cast<float>(mClientWidth) / mClientHeight;
}
메시의 삼각형들을 잘게 쪼개 새로운 삼각형들을 만드는 과정으로 만들어진 삼각형을 새로운 위치로 이동시켜 세밀한 메시를 만들어 낼 수 있다.
이 특징을 이용한 장점으로
1. 모델의 세부도를 높이고 LOD 메커니즘을 구현할 수 있고
2. Lowpoly 메시, 저은 수의 삼각형으로 이루어진 메시에 추가로 삼각형을 더할 수 있고
3. 애니메이션이나 물리 처리 같은 고연산에 Lowpoly 메시로 수행하고, 렌더링에만 계산을 추가할 수 있다.
DirectX11 이후로 추가 된 기능으로 이전엔 추가 과정을 거쳐 수행했기에 경제적이지 않았다.
→ 테셀레이션 구현을 위한 3단계 동작 3번째
하나의 온전한 기본 도형을 입력받아 임의로 변형시킨다.
기하구조를 생성하거나 파괴할 수 있으며 하나의 점이나 선분을 사각형으로 확장하는 용도로 많이 사용된다.
투영된 3차원 삼각형으로 픽셀 색상들을 계산하는 단계다.
공간 좌표들을 NDC 좌표로 변환 후, 이 NDC 좌표안에 있는 정점
→ 레스터화된 정보들을 개별 픽셀의 색상, 깊이 및 기타 속성등을 결정
→ 각 정점 쉐이더 출력의 보간된 결과를 입력으로 받아 조명, 텍스쳐, 재질 등의 효과를 적용해 최종 색상을 계산
→ PS의 출력값으로 깊이 및 블렌딩 작업에 따라 각 픽셀의 최종 모양을 결정
Grid 그리기 (0) | 2024.06.24 |
---|---|
정점, 인덱스를 이용한 렌더링 (0) | 2024.06.19 |
벡터 대수 (0) | 2024.06.08 |
장치 초기화 (0) | 2024.06.07 |
DirectX 11 ( 개요 ) (0) | 2024.06.07 |