- 이번 챕터에서는 총 두가지 이론을 다룰 것이다.
- 평평한 2차원 모니터 화면을 통해서 3차원 세상을 보고 있다는 환상의 주요 요소
- 색상을 수학적으로, 그리고 Direct3D 코드 안에서 표현하고 다루는 방법
3차원의 환상
- 3차원 세계의 깊이와 부피를 2차원 평면으로 나타내는 방법은 이미 충분히 연구되어 왔다.
- 소실점(Vanishing Point)
- 시각 평행선들이 수렴하는 점.
- 물체 겹침(Object Overlay)
- 불투명한 물체가 그 뒤에 있는 물체의 일부 또는 전체를 가리는 현상.
- 조명, 셰이딩
- 광원으로 인한 밝기 변화를 적용함으로써 부피를 표현
- 그림자
- 그림자는 장면에서 광원이 있는 위치를 말해준다.
- 또한 물체의 위치를 대략적으로 제시하기도 한다.
- 소실점(Vanishing Point)
모형의 표현
- Direct3D Application에서는 일반적으로 Solid의 3차원 물체를 삼각형 Mesh로 Approximation한다.
- 실제 세상의 그 어떤 3차원 물체라도 삼각형 mesh로 표현이 가능하다.
- 일반적으로, 근사하는데 사용한 삼각형이 많을수록 요구되는 처리 능력이 높아진다.
- 따라서 사용자의 Hardware 성능에 근거하여 적절한 균형점을 찾아야 한다.
- 삼각형 외에 섬이나 점도 물체를 근사하는데 유용하다.
- 예를 들어 곡선은 한 Pixel 굵기의 짧은 선분들로 근사가 가능하다.
- 모든 3차원 물체를 삼각형 mesh로 표현이 가능하지만, 이를 일일이 나열하는 작업은 매우 성가시다.
- 그래서 간단한 모형이 아닌 이상 모형을 생성, 조작할 때에는 3D Modeler를 사용한다.
- 3D Studio Max, LightWave 3D, Maya, Softimage, Blender 등
색상 표현의 기초
- 컴퓨터 모니터는 Pixel마다 Red, Green, Blue 색의 빛을 섞어서 방출한다.
- 모니터가 방출하는 RGB의 세기에는 상한과 하한이 존재한다.
- 보통 [0, 1]의 정규화된 값을 사용한다.
- 0은 빛이 전혀 ㅇ벗는 것이고, 1은 세기가 최대인 것이다.
- 예를 들어 (0.25, 0.67, 1.0)은 25%의 Red, 67%의 Green, 100%의 Blue가 혼합되었다는 의미이다.
- 이는 하나의 색상을 하나의 3차원 색상 Vector (r, g, b)로 나타낼 수 있음을 의미한다.
색상 연산
- Vector 연산 중 몇가지 연산은 색상 Vector에도 그대로 적용이 가능하다.
- 덧셈, 뺄셈, 스칼라 곱 등은 그대로 적용이 된다.
- 반면 Dot Product, Cross Product와 같은 연산은 의미를 퇴색한다.
- 색상 Vector만의 연산도 존재한다.
- 변조(Modulation) 혹은 성분별 곱셈(Componentwise multiplication)이라고도 한다.
- Modulation은 주로 조명 공식에 쓰인다.
- 색상 연산은 성분이 [0, 1] 범위 바깥으로 나갈 수 있다.
- 하지만 1.0이 최대 세기이므로 이보다 큰 성분은 1.0으로 clamping 해야 한다.
- 마찬가지로 음의 세기도 0.0으로 clamping 해야 한다.
128비트 색상
- 보통 RGB 외에 A(Alpha)라는 성분을 색상 Vector에 추가하는 경우가 많다.
- Alpha는 색상의 불투명도를 나타내는데, 이는 색상 혼합에 유용하다.
- Alpha를 색상 Vector에 추가함으로서 하나의 색상은 각 성분 별 32bit float형으로 총 128bit로 표현된다.
- 수학적으로는 하나의 4차원 Vector이므로, 코드상에서도 그냥 XMVector를 이용한다.
- 그러면 XNA Math 라이브러리의 Vector 함수들로 연산 할 때 SIMD의 이득을 취할 수 있다
- 색상 Vector의 Modulate에 대해서는 XNA Math 라이브러리의 다음 함수를 사용한다.
XMVECTOR XM_CALLCONV XMColorModulate(FXMVECTOR C1, FXMVECTOR C2);
32비트 색상
- 각 성분당 1Byte를 할당해서 32bit로 하나의 색상을 표현할 수도 있다.
- 성분 당 0에서 255로 16,777,216가지의 색을 표현하는 것이 가능하다.
- XNA Math 라이브러리는 이를 위해 다음 구조체를 제공한다.
struct XMCOLOR {
union {
struct {
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
uint32_t c;
};
void XMCOLOR();
void XMCOLOR(
const XMCOLOR &
);
XMCOLOR & operator=(
const XMCOLOR &
);
void XMCOLOR(
XMCOLOR &&
);
XMCOLOR & operator=(
XMCOLOR &&
);
XM_CONSTEXPR XMCOLOR(
uint32_t Color
);
void XMCOLOR(
float _r,
float _g,
float _b,
float _a
);
void XMCOLOR(
const float *pArray
);
void operator uint32_t();
XMCOLOR & operator=(
const uint32_t Color
);
};
- 32bit 색상을 128bit 색상으로 바꿀 때는 각 성분을 255로 나누면 된다.
- 반대로 128bit 색상을 32bit 색상으로 바꿀 때는 각 성분을 255를 곱하면 된다.
- 단, 32bit 색상은 4개의 8bit 색상 성분을 하나의 32bit 정수형 자료형(ex. unsigned int)에 넣은 형태이다.
- 때문에 추가적인 비트 연산이 필요하다. 이는 XMCOLOR도 해당된다.
- 이에 대해서 XNA Math 라이브러리는 다음 함수를 제공한다.
XMVECTOR XM_CALLCONV XMLoadColor(
const XMCOLOR *pSource
);
- 반대로 XMVECTOR 색상을 XMCOLOR로 변환하는 함수도 제공한다.
void XM_CALLCONV XMStoreColor(
XMCOLOR *pDestination,
FXMVECTOR V
);
- 하지만 이 함수들과 XMColor는 DirectX11이나 DirectXPackedVector.h에 존재한다.
- DirectX12 예시에서는 XNA Math가 아니라 DirectXMath.h를 사용하는데, 이 안에 흔적을 찾을 수 없었다.
- 아무래도 DirectX12에 와서는 일반 XMUInt4를 사용하는 것 같다.
struct XMUINT4
{
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
XMUINT4() = default;
XMUINT4(const XMUINT4&) = default;
XMUINT4& operator=(const XMUINT4&) = default;
XMUINT4(XMUINT4&&) = default;
XMUINT4& operator=(XMUINT4&&) = default;
XM_CONSTEXPR XMUINT4(uint32_t _x, uint32_t _y, uint32_t _z, uint32_t _w) : x(_x), y(_y), z(_z), w(_w) {}
explicit XMUINT4(_In_reads_(4) const uint32_t *pArray) : x(pArray[0]), y(pArray[1]), z(pArray[2]), w(pArray[3]) {}
};
XMVECTOR XM_CALLCONV XMLoadUInt4(_In_ const XMUINT4* pSource);
void XM_CALLCONV XMStoreUInt4(_Out_ XMUINT4* pDestination, _In_ FXMVECTOR V);
- 다시 돌아와, 128bit 색상은 Pixel Shader와 같이 다수의 색상 연산이 진행되는 곳에 쓰인다.
- 정밀도를 위한 비트가 많으므로 산술 오차가 과도하게 누적되는 일이 없기 때문이다.
- 하지만 최종적인 Pixel 색상은 일반적으로 Back Buffer에 32bit로 저장된다.
- 현재의 물리적 디스플레이 장치들은 고해상도 색상의 장점을 취하지 못한다.
'내용정리 > DirectX12' 카테고리의 다른 글
08. Direct3D의 초기화 - 기본지식 2 (0) | 2020.07.24 |
---|---|
09. 렌더링 파이프라인 2 (1) | 2020.07.14 |
08. Direct3D의 초기화 - 기본지식 1 (0) | 2020.07.13 |
20.07.01 일지 (0) | 2020.07.01 |
07. DirectX12 template 프로젝트 분석 06(完) - 20.06.26 (0) | 2020.06.26 |