3D Graphics

DirectX11 RTV, SRV등등 View의 역할

hunhun4949 2024. 9. 7. 14:42

DirectX11에서 변수타입 맨 뒤에 view가 붙은 애들이 종종 보인다.

이런 변수명을 가진 애들이 하는 일이 뭘까?

이들은 주로 GPU에서 특정 리소스(텍스처나 버퍼)에 접근하는 방법을 정의한다.

이러한 View는 GPU가 텍스처나 버퍼에 대한 다양한 읽기/쓰기 접근을 할 수 있게 해준다.

 

DirectX에서 주요 개념 : 리소스와 뷰

  • 리소스(resource) : GPU에서 사용할 데이터(텍스처, 버퍼)이다. 리소스는 GPU에서 메모리에 저장된 데이터 자체를 의미한다.
  • 뷰(view) : 리소스에 대한 접근 방식을 정의하는 객체이다. 뷰는 리소스를 직접 사용하는 것이 아니라, 리소스를 어떻게 사용할지를 정의한다. 뷰를 통해 GPU가 리소스에 접근 할 수 있게된다.

DirectX에서 주요 뷰 타입

  • RenderTargetView(RTV)
    • 역할 : 이 뷰는 특정 텍스처 또는 버퍼를 렌더 타겟으로 사용 할 수 있게 정의한다. 즉, GPU에서 픽셀 출력을 할 때, 렌더링 결과를 저장할 대상이 된다.
    • 설명 : 렌더타셋(RenderTarget)은 화면에 출력될 이미지 데이터를 저장하는 곳이다. 이해하기 쉽게 도화지라고 생각하자. RTV는 GPU가 렌더링한 결과를 이 RenderTarget에 쓰도록 지시한다.
    • 예시 코드
ID3D11Texture2D* renderTarget;
ID3D11RenderTargetView* rtv;
device->CreateRenderTargetView(renderTarget, nullptr, &rtv);

 

  • DepthStencilView(DSV)
    • 역할 : 이 뷰는 텍스처를 깊이 버퍼(Depth Buffer)와 스텐실 버퍼(stencil Buffer)로 사용할 수 있게 한다. 이는 깊이 테스트와 스텐실 테스트를 수행하는데 필요하다.
    • 설명 : 깊이 버퍼는 렌더링 시 불체의 깊이 정보를 저장하며, 스텐실 버퍼는 특정 픽셀을 렌더링할지 여부를 결정하는데 추가적인 테스트를 제공한다. 이 기능들은 주로 빛연산을 한번에 처리하는 Defferred Rendering이나 그림자를 생성할때 사용된다.
    • 예시 코드
ID3D11Texture2D* depthStencilBuffer;
ID3D11DepthStencilView* dsv;
device->CreateDepthStencilView(depthStencilBuffer, nullptr, &dsv);
  • ShaderResourceView(SRV)
    • 역할 : 이 뷰는 리소스를 셰이더에서 읽을 수 있는 리소스로 정의한다. 주로 텍스처나 버퍼의 데이터를 셰이더에서 참조할 때 사용된다.
    • 설명 : 텍스처로 넘겨지는 정보로 diffuseMap, specularMap, normalMap등이 있다.
    • 예시 코드
ID3D11Texture2D* texture;
ID3D11ShaderResourceView* srv;
device->CreateShaderResourceView(texture, nullptr, &srv);
  • UnorderedAccessView(UAV)
    • 역할 : 이 뷰는 리소스를 임의로 읽고 쓸 수 있는 뷰로 정의한다. 주로 컴퓨트 셰이더 또는 픽셀 셰이더에서 리소르에 임의의 순서로 접근할 수 있게 해준다.
    • 설명 : UAV는 GPU가 동시에 여러 스레드를 사용하여 데이터에 접근하는 경우에 사용된다. 주로 병렬 연산이 필요한 경우 유용하다. 사용처 예시, ray picking
    • 예시 코드
ID3D11Texture2D* texture;
ID3D11UnorderedAccessView* uav;
device->CreateUnorderedAccessView(texture, nullptr, &uav);

 

위의 4개가 view의 주요 사용처고 코드에서 주목해봐야할 부분은 ID3D11Texture2D* 타입을 리소스로 받는다는거다. 즉 어떤 용도로 사용을 하든 일단 2차원 배열로 저장을 하고 이후에 view를 설정해서 이 2차원 정보를 어떻게 쓸지를 설정해주는거다. 

 

 

뷰의 사용 흐름

  1. 리소스 생성 : 먼저 GPU에서 사용할 텍스처나 버퍼같은 리소스를 생성해준다. 이 리소스는 데이터를 저장할 공간을 의미한다.
  2. 뷰 생성 : 그런 다음, 그 리소스를 어떻게 사용할지에 따라 뷰를 생성한다. 이 뷰는 리소스에 대한 접근 방식을 정의한다.
  3. GPU에 바인딩 : 마지막으로 생성한 뷰를 GPU에 바인딩해서, GPU가 해당 리소스를 접근하고 사용할 수 있게 한다.

예시 코드 : 렌더 타섹과 깊이 스텡실 설정

// 렌더 타겟 텍스처 생성
ID3D11Texture2D* renderTargetTexture;
D3D11_TEXTURE2D_DESC rtDesc = {};
rtDesc.Width = 800;
rtDesc.Height = 600;
rtDesc.MipLevels = 1;
rtDesc.ArraySize = 1;
rtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtDesc.SampleDesc.Count = 1;
rtDesc.Usage = D3D11_USAGE_DEFAULT;
rtDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
device->CreateTexture2D(&rtDesc, nullptr, &renderTargetTexture);

// 렌더 타겟 뷰 생성
ID3D11RenderTargetView* rtv;
device->CreateRenderTargetView(renderTargetTexture, nullptr, &rtv);

// 깊이 스텐실 텍스처 생성
ID3D11Texture2D* depthStencilTexture;
D3D11_TEXTURE2D_DESC dsDesc = {};
dsDesc.Width = 800;
dsDesc.Height = 600;
dsDesc.MipLevels = 1;
dsDesc.ArraySize = 1;
dsDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
dsDesc.SampleDesc.Count = 1;
dsDesc.Usage = D3D11_USAGE_DEFAULT;
dsDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
device->CreateTexture2D(&dsDesc, nullptr, &depthStencilTexture);

// 깊이 스텐실 뷰 생성
ID3D11DepthStencilView* dsv;
device->CreateDepthStencilView(depthStencilTexture, nullptr, &dsv);

// 렌더 타겟과 깊이 스텐실 뷰를 설정
context->OMSetRenderTargets(1, &rtv, dsv);

 

리소스 생성할때 Desc라는게 사용되는게 보일텐데 DescDescriptor의 줄임말로 이름과 같이 2D 텍스처를 생성할 때 텍스처의 다양한 속성을 정의(설명)하는 구조체다. Desc에 대한 자세한 내용은 다른 글에서 설명하겠다.

 

 

 

결론 : View는 DirectX에서 GPU가 리소스(텍스처나 버퍼)에 접근하는 방식을 정의하는 중요한 객체이다.

'3D Graphics' 카테고리의 다른 글

Deferred Render  (2) 2024.09.09
DirectX11 TEXTURE2D DESC  (3) 2024.09.07
Skinning Animation  (4) 2024.08.28
3D Graphics Blend State에 대해 알아보자  (0) 2024.08.21
3D Graphics RasterizerState에 대해 알아보자  (0) 2024.08.21