1. 3D Direct Application
1.1 Shadow Mapping
1.1.1 Shadow Mapping System
1.1.1.1 Shadow Map
- 그림자 매핑 알고리즘은 장면 깊이의 렌더링에 의존, 그러나 Texture 대상 렌더링의 일종
- 광원의 시점에서 본 장면의 깊이 값들을 깊이 버퍼에 기록
- 장면을 광원의 시점에서 렌더링하면 광원에 가장 가까운 픽셀 단편을 파악, 그런 단편들은 반드시 그림자 바깥에 존재
- 광원의 관점에서 본 장면 깊이를 저장하는데 도움을 주는 그림자 맵이라는 편의용 클래스를 사용
class ShadowMap;
- 클래스의 생성자는 지정된 크기의 Texture & View, Viewport를 생성
- 그림자 맵의 해상도가 높을수록 그림자의 품질이 좋아짐
- 장면을 렌더링하는 데 필요한 시간과 그림자 맵을 저장하는 데 필요한 메모리도 커진다는 점을 주의
_viewport.TopLeftX = 0.0f; _viewport.TopLeftY = 0.0f;
_viewport.Width = static_cast<float>(width); _viewport.Height = static_cast<float>(height);
_viewport.MinDepth = 0.0f; _viewport.MaxDepth = 1.0f;
D3D11_TEXTURE2D_DESC texDesc; ComPtr<ID3D11Texture2D> depthMap;
HR(device->CreateTexture2D(&texDesc, 0, depthMap.GetAddressOf()));
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
HR(device->CreateDepthStencilView(depthMap.Get(), &dsvDesc, _depthMapDSV.GetAddressOf()));
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
HR(device->CreateShaderResourceView(depthMap.Get(), &srvDesc, _depthMapSRV.GetAddressOf()));
- 그림자 매핑 알고리즘에서 두번의 렌더링 패스가 필요
- 광원의 시점에서 본 장면 깊이를 그림자 맵에 렌더링
- 카메라에서 본 장면을 후면 버퍼에 렌더링 하되, 그림자 맵을 셰이더의 한 입력으로 사용해서 장면에 그림자를 적용
ComPtr<ID3D11ShaderResourceView> ShadowMap::DepthMapSRV() { return _depthMapSRV; }
- 그림자 맵 렌더링을 위해 출력 병합기 단계를 준비하는 함수
- 렌더 대상을 NULL로 설정함으로써 색상 쓰기를 사실상 비활성화한다는 점을 주목
- 장면을 그림자 맵에 렌더링하는 것은 광원을 기준으로 한 장면의 깊이 값들을 얻는 것이므로 색상 쓰기는 필요X
- 깊이 전용 렌더링 패스는 모두 그리는 패스에 비해 훨씬 빠름
void ShadowMap::BindDsvAndSetNullRenderTarget(ComPtr<ID3D11DeviceContext> dc)
{
dc->RSSetViewports(1, &_viewport);
ID3D11RenderTargetView* renderTargets[1] = { 0 };
dc->OMSetRenderTargets(1, renderTargets, _depthMapDSV.Get());
dc->ClearDepthStencilView(_depthMapDSV.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
}
1.1.1.2 Orthographic Projection
- 지금까지 예제들은 원근투영 사용하여 생성, 원근투영은 물체가 시점에서 멀수록 작게 나타난다는 것
- 실제로 사람이 사물을 볼 때 느끼는 것과 일치, 그러나 원근투영말고 직교투영이라는 투영 방법도 존재
- 평행선은 투영 후에도 여전히 평행으로 보이는 것 분야에 흔히 쓰임, 직교투영은 그림자 매핑에서도 중요한 역할 수행
- 평행광이 드리우는 그림자를 본뜨기 위해 바로 직교투영이 필요
- 직교투영의 시야 공간을 나타내는 시야 입체는 축에 정렬된 상자 형태
1.1.1.3 Projective Texturing
- Texture를 임의의 기하구조에 투영해서 입히는 기법을 투영 Texture 적용 기법이라 부름
- 적용된 Texture가 실제로 기하구조에 투영된 것처럼 보이도록 각 픽셀마다 적절한 Texture 좌표를 생성
- 3차원 점 P에 투영될 텍셀에 해당하는 Texture 좌표가 P를 투영 창에 투영한 위치의 Texture 공간 기준 좌표에 해당
- 점 P를 광원 시점의 투영 창에 투영, 투영된 좌표를 NDC 공간으로 변환
- 광원에 놓인 영사기를 카메라로 간주하여 빛 영사기에 대한 시야 행렬, 투영 행렬을 생성
- 두 행렬은 본질적으로 세계 공간에서의 빛 영사기의 위치와 방향, 절두체를 결정
- 행렬 V는 좌표들을 세계 공간에서 빛영사기의 좌표계, 즉 광원 좌표계로 변환
- 광원 좌표계 기준의 좌표를 얻은 다음에는 투영 행렬과 동차 나누기를 통해 그 좌표를 광원의 투영 평면에 투영
- 투영된 좌표를 NDC 공간에서 Texture 공간으로 변환, 그 결과가 바로 투영 Texture 좌표
- NDC 공간에서 Texture 공간으로 변환은 좌표 변경 변환으로 수행
- 따라서 세계 행렬로 부터 VPT를 이용하여 직접 Texture 공간으로 변환
XMMATRIX V = ::XMMatrixLookAtLH(lightPos, targetPos, up);
XMMATRIX P = ::XMMatrixOrthographicOffCenterLH(l, r, b, t, n, f);
XMMATRIX T(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 45. 3D Direct Application - Mesh Basic Model (0) | 2023.07.04 |
---|---|
[Direct11] 44. 3D Direct Application - Shadow Mapping #2 (0) | 2023.07.03 |
[Direct11] 42. 3D Direct Application - Particle System #2 (0) | 2023.07.03 |
[Direct11] 41. 3D Direct Application - Particle System #1 (0) | 2023.07.03 |
[Direct11] 40. 3D Direct Application - Terrian Rendering #2 (0) | 2023.06.30 |