개발중인 D3D12엔진에서 사용하는 Descriptor Table구조다.
예를 들어 두개의 텍스쳐를 사용하고 있는 오브젝트 한개가 있다.
두개의 텍스쳐-매터리얼을 가지고 있으므로 렌더링은 두번 나눠서 해야한다.
하지만 두개의 그룹-Facegroup이라 부르겠다-은 월드상에서 동일한 Transform Matrix를 사용해서 렌더링한다. 따라서 Transform Matrix와 같이 공통적으로 사용할 수 있는 리소스의 경우 한번만 설정하고 변경없이 두번 렌더링 하면 된다.
두개의 FaceGroup이 공통적으로 사용할 리소스는
Projection을 위한 matrix, Shadow map등이다.
각각의 FaceGroup이 다르게 사용할 리소스는 각자의 Texture,그밖의 매터리얼을 설정하는 constant이다.
이 Descriptor Table의 형식으로 RootSignature를 만드는 코드는 다음과 같다.
CD3DX12_DESCRIPTOR_RANGE rangesPerObj[2]; rangesPerObj[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 2, 0); // b0 : default , b1 : bones rangesPerObj[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 2); // t2 : toon table , t3:shadow CD3DX12_DESCRIPTOR_RANGE rangesPerFacegroup[2]; rangesPerFacegroup[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 2); // b2 : material rangesPerFacegroup[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 0); // t0 : diffuse , t1: mask D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; CD3DX12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsDescriptorTable(2, rangesPerObj, D3D12_SHADER_VISIBILITY_ALL); rootParameters[1].InitAsDescriptorTable(2, rangesPerFacegroup, D3D12_SHADER_VISIBILITY_ALL); CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, _countof(samplers), samplers, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ID3DBlob* pSignature = NULL; ID3DBlob* pError = NULL; if (FAILED(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &pSignature, &pError))) { const char* szMsg = (const char*)pError->GetBufferPointer(); __debugbreak(); } if (FAILED(pResourceManager->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(), &m_pRootSignature))) __debugbreak();
오브젝트 렌더링 초입부에서 pCommandList->SetGraphicsRootDescriptorTable(0, commonHeapHandle); 로 0번 파라미터를 설정해주고,
각각의 FaceGroup을 렌더링 할때마다 pCommandList->SetGraphicsRootDescriptorTable(1, commonHeapHandle); 로 1번 파라미티를 변경해서 렌더링하면 된다.
처음 보면 이게 뭥미..싶지만 역시 코드를 짜다보면 어떻게 사용하는지 감이 온다.