DXR로 Ray tracing 렌더링을 하기 위해서는 렌더링할 Object들의 데이터(Vertex,Index)를 특수한 가속 구조(Acceleration Structure)에 넣어줘야 한다.
왜 이러한 가속구조에 렌더링 데이터를 넣어줘야하는지 이해하는게 중요하다.
그 이유는 충돌 판정 시간 단축을 위해서 이다.
가속 구조를 사용하지 않았을 때 Ray-Object 충돌 검출 알고리즘의 시간 복잡도는 O(n^2)이다.
DXR의 가속구조는 BVH(Bounding Volume Hierarchy)의 형태를 사용한다.
BVH를 사용한 Ray-Object충돌 검출 알고리즘의 시간 복잡도는 O(nlogn)이다.
이제 DXR의 가속구조를 프로그래밍해보자, DXR에서는 Top Level Acceleration Structure와 Bottom Level Acceleration Structure가 존재한다.
Top Level 가속 구조는 Bottom Level 가속구조 하나를 가리키는 Instance들의 집합이라고 할 수 있다. 보통 게임 캐릭터,오브젝트 1개당 1개의 Top Level 가속 구조 Instance가 생성된다. 코딩은 다음과 같은 과정을 거친다. 자세한 코드는 너무 길어져서 생략한다..
TLAS(Top Level Acceleration Structure)생성 순서
1. BLAS(Bottom Level Acceleration Structure)에 대응하는 Instance버퍼 생성
2. 각 Instance에는 Transform,id, HitGroupIndex,등의 정보를 입력
3. Instance버퍼를 이용해서 TLAS버퍼 생성
Bottom Level 가속 구조는 Instance를 구성하는 Geometry들의 집합이라고 할 수 있다.
코딩과정은 다음과 같다.
BLAS(Bottom Level Acceleration Structure)생성 순서
1. 렌더링할 GeometryDesc생성(Vertex버퍼,Index버퍼,Format등 입력)
2. GeometryDesc정보를 바탕으로 BLAS버퍼 생성
pCommandList->SetComputeRootShaderResourceView( static_cast<UINT>(EGlobalRootSignatureSlot::AccelerationStructureSlot), m_topLevelAccelerationStructure.GetAccelerationStructure()->GetGPUVirtualAddress() );//TLAS 바인딩
Root Signature의 SRV Inline Root Descriptor에 바인딩해주는 코드다. 주목할 점은 BLAS는 TLAS에 이미 바인딩 되어있기에 파이프라인에는 TLAS만 바인딩해주면 된다.
RaytracingAccelerationStructure g_scene : register(t0, space0);//TLAS
가속 구조는 RaytracingAccelerationStructure라는 구조체 형식으로 사용할 수 있다.
TraceRay(
g_scene, //acceleration structure
RAY_FLAG_NONE,
TraceRayParameters::InstanceMask, //instance mask
TraceRayParameters::HitGroupOffset[RayType::Radiance], //hit group base index설정(공식:trace ray설정 index+ instance index + (geometry index * geometry stride)
TraceRayParameters::GeometryStride, //geometry stride
TraceRayParameters::MissShaderOffset[RayType::Radiance], //miss shader index
ray, //ray 정보
payload //payload
);
Shader에 할당한 가속 구조 변수는 TraceRay함수의 첫번째 인자로 사용된다.