[D3D] Depth Stencil View

vector·2025년 11월 21일
  • 깊이Depth와 스텐실Stencil 버퍼는 시각적 효과를 향상시키고, 렌더링 성능을 최적화하는 데 중요한 역할
  • 깊이와 스텐실 처리를 통해 더 사실적이고 복잡한 3D 환경을 구현할 수 있게 해줌

Depth (깊이 버퍼, Z-Buffer)

  • 각 픽셀이 카메라로부터 얼마나 떨어져 있는가(깊이값)을 저장하는 버퍼
  • 즉, "어떤 픽실이 더 앞에 있는가?"를 판단하여 Z-Text(깊이 테스트)를 수행

Depth Stencil View

  • 이전 프로젝트에서 깊이가 다른 물체 2개를 생성해보면, 뒤에 있는 오브젝트가 앞에 보이는 거처럼 보이는 경우가 있음

  • 깊이 정보를 제외한 정보값만을 가지고 물체를 생성해주었기 때문.

  • SpherePos는 Vec3(0.f, 0.f, 0.f)이고,
    CubePos는 Vec3(0.5f, 0.f, 2.f)이다.

  • Graphics에서 깊이 정보를 가지고 있는 변수를 선언해주고 초기화

Graphics.h

#pragma once

class Graphics
{
	DECLARE_SINGLE(Graphics);

public:
	void Init(HWND hwnd);

	void RenderBegin();
	void RenderEnd();

	ComPtr<ID3D11Device> GetDevice() { return _device; }
	ComPtr<ID3D11DeviceContext> GetDeviceContext() { return _deviceContext; }

private:
	void CreateDeviceAndSwapChain();
	void CreateRenderTargetView();
	void CreateDepthStencilView(); //(추가부분)
	void SetViewport();

private:
	HWND _hwnd = {};

	// Device & SwapChain
	ComPtr<ID3D11Device> _device = nullptr;
	ComPtr<ID3D11DeviceContext> _deviceContext = nullptr;
	ComPtr<IDXGISwapChain> _swapChain = nullptr;

	// RTV
	ComPtr<ID3D11RenderTargetView> _renderTargetView;

	// DSV (추가부분)
	ComPtr<ID3D11Texture2D> _depthStencilTexture;
	ComPtr<ID3D11DepthStencilView> _depthStencilView;

	// Misc
	D3D11_VIEWPORT _viewport = { 0 };
};

Graphics.cpp

void Graphics::Init(HWND hwnd)
{
	_hwnd = hwnd;

	CreateDeviceAndSwapChain();
	CreateRenderTargetView();
	CreateDepthStencilView();
	SetViewport();
}

void Graphics::RenderBegin()
{
	_deviceContext->OMSetRenderTargets(1, _renderTargetView.GetAddressOf(), _depthStencilView.Get()); // depth stencil view 추가 (깊이값 추가)
	_deviceContext->ClearRenderTargetView(_renderTargetView.Get(), (float*)(&GAME->GetGameDesc().clearColor));
	// depth stencil view 클리어 추가, ClearDepthStencilView 추가 이유 : 깊이값과 스텐실 값을 초기화 하기 위해
	// Depth가 1.0f인 이유 : 깊이값은 0~1사이의 값으로 1.0f가 가장 멀리있는 값이기 때문
	_deviceContext->ClearDepthStencilView(_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
	_deviceContext->RSSetViewports(1, &_viewport);
}

void Graphics::CreateDepthStencilView()
{
	{
		D3D11_TEXTURE2D_DESC desc = { 0 };
		ZeroMemory(&desc, sizeof(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;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.Usage = D3D11_USAGE_DEFAULT;
		desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
		desc.CPUAccessFlags = 0;
		desc.MiscFlags = 0;

		HRESULT hr = DEVICE->CreateTexture2D(&desc, nullptr, _depthStencilTexture.GetAddressOf());
		CHECK(hr);
	}

	{
		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
		ZeroMemory(&desc, sizeof(desc));
		desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
		desc.Texture2D.MipSlice = 0;

		HRESULT hr = DEVICE->CreateDepthStencilView(_depthStencilTexture.Get(), &desc, _depthStencilView.GetAddressOf());
		CHECK(hr);
	}

}

결과

참고 강의

https://www.inflearn.com/courses/lecture?courseId=329791&type=LECTURE&unitId=161128&subtitleLanguage=ko

profile
게임 클라이언트 프로그래머 준비중 (공부 및 기록용)

0개의 댓글