[DirectX 11] Fast Picking (Object ID Picking)

2022. 3. 29. 02:48·Graphics

Object ID Picking

- Object Picking을 하기위해선 화면상의 현재 Mouse Position에 위치하는 Face를 모두 검사하는 방식을 사용했었는데, 생각해보니 굳이 CPU 측에서 모든 Object의 Face를 검색하는 것보단 간단한 Object ID를 화면상에 그리는 방식이 빠를것이라 생각이 들었다. Staging Buffer를 활용하면 해당 영역의 GPU Resource Data를 Copy 할 수 있다는 것을 알게되어 활용해보기로 하였다.

 

Picking 방식

- Object 생성시 부여되는 고유 Number를 활용하여 Hash Color를 생성

- Picking Event 실행시 화면상에 모든 Object Hash Color를 Draw 실행

- Staging Buffer를 통해 해당 Mouse Position에 위치한 1x1 Pixel의 Hash Color를 추출

- 추출한 Hash Color에 해당하는 Object 검색 및 선택

 


// Picking 전용 Texture 2D
// 해당 Texture는 데이터 입력은 Shader에서 하되, 해당 값을 CPU에서 읽을수 있어야 하므로
// Usage Option을 D3D11_USAGE_STAGING으로 설정..
D3D11_TEXTURE2D_DESC texCopyDesc;
ZeroMemory(&texCopyDesc, sizeof(texCopyDesc));
texCopyDesc.Width = 1;
texCopyDesc.Height = 1;
texCopyDesc.MipLevels = 1;
texCopyDesc.ArraySize = 1;
texCopyDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texCopyDesc.SampleDesc.Count = 1;
texCopyDesc.SampleDesc.Quality = 0;
texCopyDesc.Usage = D3D11_USAGE_STAGING;
texCopyDesc.BindFlags = 0;
texCopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
texCopyDesc.MiscFlags = 0;

D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = width;
texDesc.Height = height;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = 0;

/// RenderTargetView 2D
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
ZeroMemory(&rtvDesc, sizeof(rtvDesc));
rtvDesc.Format = texDesc.Format;
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvDesc.Texture2D.MipSlice = 0;

// RenderTarget 생성..
g_Factory->CreateRenderTexture<RT_ID_Copy>(&texCopyDesc, nullptr, nullptr, nullptr, nullptr);
g_Factory->CreateRenderTexture<RT_ID>(&texDesc, nullptr, &rtvDesc, nullptr, nullptr);

- Object ID를 그릴 RenderTarget 생성 및 Mouse Position Pixel을 가져오기 위한 1x1 Staging Buffer 생성

 

UINT PickingPass::FindPick(int x, int y)
{
	m_PickPointBox.left		= x,
	m_PickPointBox.right	= x + 1;
	m_PickPointBox.top		= y,
	m_PickPointBox.bottom	= y + 1;
	m_PickPointBox.front	= 0;
	m_PickPointBox.back		= 1;

	g_Context->OMSetRenderTargets(0, nullptr, nullptr);

	g_Context->CopySubresourceRegion(m_ID_CopyTex2D, 0, 0, 0, 0, m_ID_Tex2D, 0, &m_PickPointBox);

	// 현재 선택한 Object ID..
	UINT pickID = 0;

	// Mapping SubResource Data..
	D3D11_MAPPED_SUBRESOURCE mappedResource;
	ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));

	// GPU Access Lock Texture Data..
	g_Context->Map(m_ID_CopyTex2D, 0, D3D11_MAP_READ, 0, &mappedResource);

	// 해당 Pixel Copy가 잘못 되었을 경우..
	if (mappedResource.pData == nullptr) return 0;

	pickID = ((UINT*)mappedResource.pData)[0];

	// GPU Access UnLock Texture Data..
	g_Context->Unmap(m_ID_CopyTex2D, 0);

	return pickID;
}

- 모든 Object ID를 그린 후 Mouse Position의 Pixel을 Copy 하여 해당 ID 반환하는 과정

 

적용 화면

Object ID Picking 과정

저작자표시 (새창열림)

'Graphics' 카테고리의 다른 글

[DirectX 11] Vertex Texture Fetch Skinning Animation Instancing  (0) 2022.04.21
[DirectX 11] Hierarchical Z-Buffer Occlusion Culling  (0) 2022.04.04
[DirectX 11] Game Engine Render Resource 동기화 방식 및 Resource 관리 방식  (0) 2022.03.16
[DirectX 11] Game Engine & Graphic Engine 분리 및 Render Data 전달 방식  (0) 2022.03.07
[DirectX 11] Hardware Instancing  (0) 2022.03.02
'Graphics' 카테고리의 다른 글
  • [DirectX 11] Vertex Texture Fetch Skinning Animation Instancing
  • [DirectX 11] Hierarchical Z-Buffer Occlusion Culling
  • [DirectX 11] Game Engine Render Resource 동기화 방식 및 Resource 관리 방식
  • [DirectX 11] Game Engine & Graphic Engine 분리 및 Render Data 전달 방식
KyuHwang
KyuHwang
  • KyuHwang
    DirectX Engine
    KyuHwang
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • C++ (4)
      • CS (0)
      • Graphics (32)
      • DLL (2)
      • Shader (7)
      • Project (4)
      • ETC (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • YouTube
  • 공지사항

  • 인기 글

  • 태그

    DirectX 2D
    nvtt
    animation retargeting
    bc format
    Order Independent Transparency
    Shader Macro
    std::is_base_of
    dll
    Shader Resource 관리
    Alpha Blending
    hlsl
    DLL Interface
    Directx11
    texture block compression
    Project
    Return Type Operator
    Hash Code
    Explicit Linking
    Define Function
    C ++
    shader
    Implicit Linking
    animation constraint
    mobile format
    std::enable_if
    Win API
    Define Macro
    Shader Reflection
    RunTime Compile Shader
    rigging chain
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
KyuHwang
[DirectX 11] Fast Picking (Object ID Picking)
상단으로

티스토리툴바