| 용어 | 설명 |
|---|---|
| Depth Buffer (Z-Buffer) | 각 픽셀이 화면에 출력되기까지의 깊이 값을 저장하는 버퍼 |
| Stencil Buffer | 특정 조건에서만 픽셀을 출력하도록 제한하는 마스크용 버퍼 |
| DepthStencilView (DSV) | Depth/Stencil Buffer를 Output-Merger 단계에서 사용하는 뷰 객체 |
| DXGI_FORMAT_D24_UNORM_S8_UINT | 24비트 Depth + 8비트 Stencil 데이터를 저장하는 포맷 |
| OMSetRenderTargets | GPU Output-Merger 단계에 RenderTarget과 DepthStencilView를 동시에 설정 |
| ClearDepthStencilView | 이전 프레임의 깊이 및 스텐실 값을 초기화하여 새로운 프레임 시작 시 클리어 |
// Graphics.h 내부
ComPtr<ID3D11Texture2D> _depthStencilTexture;
ComPtr<ID3D11DepthStencilView> _depthStencilView;
void CreateDepthStencilView();
_depthStencilTexture: 픽셀마다 깊이 값을 저장할 2D Texture_depthStencilView: 해당 Texture에 접근하기 위한 View 객체void Graphics::Init(HWND hwnd)
{
_hwnd = hwnd;
CreateDeviceAndSwapChain(); // 디바이스, 컨텍스트, 스왑체인 생성
CreateRenderTargetView(); // 렌더링 결과를 담을 RenderTarget 생성
CreateDepthStencilView(); // 깊이 정보를 기록할 DepthStencil 생성
SetViewport(); // 출력 뷰포트 설정
}
void Graphics::CreateDepthStencilView()
{
// 1. Depth Texture 생성
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = static_cast<uint32>(GAME->GetGameDesc().width);
desc.Height = static_cast<uint32>(GAME->GetGameDesc().height);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; // 깊이: 24bit, 스텐실: 8bit
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
HRESULT hr = DEVICE->CreateTexture2D(&desc, nullptr, _depthStencilTexture.GetAddressOf());
CHECK(hr);
// 2. DepthStencilView 생성
D3D11_DEPTH_STENCIL_VIEW_DESC viewDesc = {};
viewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
viewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MipSlice = 0;
hr = DEVICE->CreateDepthStencilView(_depthStencilTexture.Get(), &viewDesc, _depthStencilView.GetAddressOf());
CHECK(hr);
}
✔ 핵심 설명
DXGI_FORMAT_D24_UNORM_S8_UINT은 깊이값 24비트 + 스텐실 8비트를 지원하는 포맷으로 일반적인 DepthStencil용 포맷이다.CreateTexture2D는 실제 깊이값을 담을 메모리를 생성하는 함수이고,CreateDepthStencilView는 이 Texture를 DepthStencil 용도로 GPU에 넘겨주는 View 객체를 만드는 함수이다.void Graphics::RenderBegin()
{
_deviceContext->OMSetRenderTargets(1, _renderTargetView.GetAddressOf(), _depthStencilView.Get());
_deviceContext->ClearRenderTargetView(_renderTargetView.Get(), (float*)(&GAME->GetGameDesc().clearColor));
_deviceContext->ClearDepthStencilView(
_depthStencilView.Get(),
D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, // 깊이와 스텐실 모두 초기화
1.0f, // 초기 깊이값: 가장 먼 거리
0 // 초기 스텐실값: 보통은 0
);
✔ 주석 설명
OMSetRenderTargets로 Output-Merger에 세팅해야 한다.ClearDepthStencilView로 매 프레임마다 깊이 초기화 작업을 반드시 수행해야 한다.