본문 바로가기
DirectX/[Inflearn_rookiss] Part2: DirectX12

5. Depth Stencil Buffer/View

by 헛둘이 2023. 1. 17.

투영이란?

원근법에서는 깊이는 어떻든간에 비율로 보겠다는 것

그렇지만 깊이도 무시할 수 없다

깊이값에 따라 어떤 사물은 가려지고 어떤 사물은 그려지기 때문

 

DX12에서는 깊이값에 따라 물체를 그려야 할지 말아야 할지를 결정함

(정확히는 물체보다는 픽셀 단위)

 

스텐실이란?

판에 구멍을 뚫고 잉크를 통과시켜 찍어내는 공판화 기법

 

*깊이 스텐실 버퍼에 float로 값을 넣는데, 스텐실을 안쓴다면 4바이트를 전부 깊이값으로 쓰고,

스탠실을 쓴다면 3바이트만 깊이로 쓰고 남은 1바이트는 스텐실 값으로 쓴다

 

*스텐실 작업은 이 1바이트 값을 이용해 스텐실 값 n을 가진 픽셀에 한해서 추가적인 작업을 진행한다

 

*DepthStencilBuffer/View를 추가해서 바뀌는 부분

1. DepthStencilBuffer 클래스 정의

void DepthStancilBuffer::Init(const WindowInfo& window, DXGI_FORMAT dsvFormat)
{
	_dsvFormat = dsvFormat;

	D3D12_HEAP_PROPERTIES heapProperty = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
	
	D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D(_dsvFormat, window.width, window.height);
	desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;

	// 매 프레임마다 밀어주는 값을 세팅하는 부분
	D3D12_CLEAR_VALUE optimizedClearValue = CD3DX12_CLEAR_VALUE(_dsvFormat, 1.f, 0);

	// 버퍼 할당
	DEVICE->CreateCommittedResource(
		&heapProperty,
		D3D12_HEAP_FLAG_NONE,
		&desc,
		D3D12_RESOURCE_STATE_DEPTH_WRITE,
		&optimizedClearValue,
		IID_PPV_ARGS(&_dsvBuffer));

	// 뷰를 하나만 활용한다고 해도 힙을 사용해야 한다
	D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
	heapDesc.NumDescriptors = 1;
	heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
	heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;

	DEVICE->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_dsvHeap));

	// 뷰를 가져와서 핸들을 가져온다.
	_dsvHandle = _dsvHeap->GetCPUDescriptorHandleForHeapStart();
	DEVICE->CreateDepthStencilView(_dsvBuffer.Get(), nullptr, _dsvHandle);

}

- Init 함수를 통해 초기값을 세팅해준다.

- D3D12_CLEAR_VALUE는 매 프레임마다 깊이 초기값을 세팅해주는 부분

- 1.0f으로 세팅해주면 그 픽셀은 아무것도 그려지지 않은 픽셀로 인식

- window를 인자로 받는 이유는 depth값은 화면의 픽셀값만큼 존재해야 함

- 따라서 나중에 화면 사이즈가 변경될 때 이 값도 변경되어야 해서 Game의 Resize에서도 호출해준다.

 

 

2. CommandQueue 클래스에 RenderBegin에서 OutputMerger에 RenderTarget이 뭔지 알려줄 때 DepthStencilBuffer도 알려줘서 묶어준다.

_cmdList->OMSetRenderTargets(1, &backBufferView, FALSE, &depthStencilView);

- OMSetRenderTargets의 마지막 인자로 DepthStencilBuffer를 가리키는 서술자 (Descriptor)가 들어감

 

_cmdList->ClearDepthStencilView(depthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);

- 이후 DepthStencilView를 클리어해준다. (RenderBegin이므로 값을 초기화)

 

3. Shader 클래스에서 pipelineDesc에 DepthStencilBuffer를 사용할 거라는 내용과 포맷을 전달한다

_pipelineDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
_pipelineDesc.DSVFormat = GEngine->GetDepthStencilBuffer()->GetDSVFormat();

 

 

 

'DirectX > [Inflearn_rookiss] Part2: DirectX12' 카테고리의 다른 글

7. Component  (0) 2023.01.18
6. Material  (0) 2023.01.18
4. Texture Mapping  (0) 2023.01.16
3. RootTable  (0) 2023.01.16
2. Constant Buffer & Root Signature  (0) 2023.01.15

댓글