일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- two pointer
- Stored Procedure
- 다익스트라
- MYSQL
- Hash
- Two Points
- SQL
- Dijkstra
- 스토어드 프로시저
- DP
- union find
- String
- Brute Force
- binary search
- 그래프
- Trie
- 이진탐색
Archives
- Today
- Total
codingfarm
4. 깊이 버퍼링(Depth Buffer) 본문
깊이문제 해결하기
카메라는 자신에게 가까운 물체가 멀리있는 물체를 덮는 방식으로 풍경이 보이게된다.
이런 깊이문제를 해결하는 방법은 크게 2가지다.
1. 거리 순서대로 그리기
- 장면의 물체를 먼것에서 가까운것 순서로 그리는 것
- 단점
- 물체를 그리는 순서를 정렬해야 한다
- 맞물린형태를 제대로 처리하기 힘들다(ex : 두 물체가 꽈배기 형태로 꼬인 경우)
2. 깊이 버퍼링(Depth Buffering)
- 관찰자를 기준으로 물체들 간의 거리차로 인해 서로 가리는지 여부를 판정하는 기법
- 깊이 버퍼링을 쓰면 그리는 순서에 관계없이 물체들이 제대로 가려진다.
- 깊이 버퍼(Depth Buffer)
- 관찰자를 기준으로 buffer내의 각 element쪽으로 바라볼때 제일 앞에있는 물체 까지의 상대적인 거리를 저장한다.
- 각 픽셀의 깊이 정보를 [0.0, 1.0] 범위의 값으로 담는다.
- 0.0 : 관찰자와 최대한 가깝다
- 1.0 : 관찰자와 최대한 멀다
- depth buffer의 element와 back buffer의 texel 들은 1:1로 대응된다.(같은 해상도를 가진다)
- 이미지 자료를 담지 않는 texture
- 앞서 Texture는 DXGI_FORMAT이라는 열거형으로 지정된 특정 형식(format)의 data element만 담을수 있다고 설명했다.
- depth buffer도 texture 이므로, 생성시 특정 data element format을 지정해야 한다
- depth buffer를 위한 texture data element format
- DXGI_FORMAT_D32_FLOAT_S8X24_UINT
- DXG_FORMAT_D32_FORMAT
- DXGI_FORMAT_D24_UNORM_S8_UINT
- DXGI_FORMAT_D16_UNORM
- 깊이 버퍼링의 작동방식에 대해 알아보자.
물체를 읽게되는 순서가 $P_3 \rightarrow P_1 \rightarrow P_2$ 라 가정하자. 물체를 읽을때마다 그 거리를 깊이버퍼에 갱신하는데, 물체까지의 거리가 깊이버퍼 값 보다 짧다면 깊이버퍼를 갱신하고, 후면버퍼에는 해당 물체를 새긴다. 하지만 물체까지의 거리가 깊이버퍼의 값 보다 멀다면 해당 물체는 무시하고 넘긴다.
즉, 이미 들어있던것보다 작은 경우에만 후면버퍼와 깊이 버퍼에 기록된다. 이런 방법을 통해 관찰자에 가장 가까운 픽셀이 렌더링되게 되는것이다.
깊이 판정은 특정 픽셀 위치에 기록될 픽셀들의 깊이들을 비교한다. 깊이 값을 비교했을 때 관찰자에게 가장 가까운 픽셀이 승자가 되어서 후면 버퍼에 기록된다.
stencil
- 고급주제이므로 11장에서 상세히 다룬다.
- 반드시 써야하는것은 아니지만, 사용해야 한다면 스텐실 버퍼는 항상 깊이 버퍼와 같은 텍스처에 포함된다
- 가령 32비트 형식 DXGI_FORMAT_D24_UNORM_S8_UINT 는 그 중 24비트를 깊이 버퍼에, 나머지 8비트를 스텐실 버퍼에 사용한다. 이 때문에 깊이 버퍼보다는 깊이$\cdot$스텐실 버퍼라는 용어가 더 정확하다.
Microsoft::WRL::ComPtr<ID3D12Resource> mSwapChainBuffer[SwapChainBufferCount]; Microsoft::WRL::ComPtr<ID3D12Resource> mDepthStencilBuffer; Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> mRtvHeap; Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> mDsvHeap; void D3DApp::OnResize() { assert(md3dDevice); assert(mSwapChain); assert(mDirectCmdListAlloc); // Flush before changing any resources. FlushCommandQueue(); ThrowIfFailed(mCommandList->Reset(mDirectCmdListAlloc.Get(), nullptr)); // Release the previous resources we will be recreating. for (int i = 0; i < SwapChainBufferCount; ++i) mSwapChainBuffer[i].Reset(); mDepthStencilBuffer.Reset(); // Resize the swap chain. ThrowIfFailed(mSwapChain->ResizeBuffers( SwapChainBufferCount, mClientWidth, mClientHeight, mBackBufferFormat, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH)); mCurrBackBuffer = 0; CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHeapHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart()); for (UINT i = 0; i < SwapChainBufferCount; i++) { ThrowIfFailed(mSwapChain->GetBuffer(i, IID_PPV_ARGS(&mSwapChainBuffer[i]))); md3dDevice->CreateRenderTargetView(mSwapChainBuffer[i].Get(), nullptr, rtvHeapHandle); rtvHeapHandle.Offset(1, mRtvDescriptorSize); } // Create the depth/stencil buffer and view. D3D12_RESOURCE_DESC depthStencilDesc; depthStencilDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; depthStencilDesc.Alignment = 0; depthStencilDesc.Width = mClientWidth; depthStencilDesc.Height = mClientHeight; depthStencilDesc.DepthOrArraySize = 1; depthStencilDesc.MipLevels = 1; // Correction 11/12/2016: SSAO chapter requires an SRV to the depth buffer to read from // the depth buffer. Therefore, because we need to create two views to the same resource: // 1. SRV format: DXGI_FORMAT_R24_UNORM_X8_TYPELESS // 2. DSV Format: DXGI_FORMAT_D24_UNORM_S8_UINT // we need to create the depth buffer resource with a typeless format. depthStencilDesc.Format = DXGI_FORMAT_R24G8_TYPELESS; depthStencilDesc.SampleDesc.Count = m4xMsaaState ? 4 : 1; depthStencilDesc.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0; depthStencilDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; depthStencilDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; D3D12_CLEAR_VALUE optClear; optClear.Format = mDepthStencilFormat; optClear.DepthStencil.Depth = 1.0f; optClear.DepthStencil.Stencil = 0; ThrowIfFailed(md3dDevice->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &depthStencilDesc, D3D12_RESOURCE_STATE_COMMON, &optClear, IID_PPV_ARGS(mDepthStencilBuffer.GetAddressOf()))); // Create descriptor to mip level 0 of entire resource using the format of the resource. D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; dsvDesc.Flags = D3D12_DSV_FLAG_NONE; dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsvDesc.Format = mDepthStencilFormat; dsvDesc.Texture2D.MipSlice = 0; md3dDevice->CreateDepthStencilView(mDepthStencilBuffer.Get(), &dsvDesc, DepthStencilView()); // Transition the resource from its initial state to be used as a depth buffer. mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mDepthStencilBuffer.Get(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_DEPTH_WRITE)); // Execute the resize commands. ThrowIfFailed(mCommandList->Close()); ID3D12CommandList* cmdsLists[] = { mCommandList.Get() }; mCommandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists); // Wait until resize is complete. FlushCommandQueue(); // Update the viewport transform to cover the client area. mScreenViewport.TopLeftX = 0; mScreenViewport.TopLeftY = 0; mScreenViewport.Width = static_cast<float>(mClientWidth); mScreenViewport.Height = static_cast<float>(mClientHeight); mScreenViewport.MinDepth = 0.0f; mScreenViewport.MaxDepth = 1.0f; mScissorRect = { 0, 0, mClientWidth, mClientHeight }; } | cs |
'computer graphics > DX12 book' 카테고리의 다른 글
4. 다중표본화(multisampling) (0) | 2021.01.11 |
---|---|
4. 자원과 서술자 / Descriptor Heap, RTV, DSV (0) | 2021.01.11 |
4. 교환 사슬(Swap Chain)과 더블 버퍼링(Double Buffering) (0) | 2021.01.11 |
4. 텍스처 형식 (0) | 2021.01.11 |
4. COM(Component Object Model) (0) | 2021.01.11 |
Comments