2023.07.14 - [GRAPHICS PROGRAMMING] - [번역]GPU DRIVEN RENDERING OVERVIE
코드 맵
모든 Draw Indirect 개선 사항을 구현하는 코드는 Github repo의 "engine" 브랜치에 있습니다. 직접 링크는 다음과 같습니다.
GitHub - vblanco20-1/vulkan-guide at engine
코드베이스는 5장에서 끝난 부분을 계속해서 진행합니다. 그러나 많은 개선 및 추상화가 추가되었습니다. Extra 장에 있는 모든 것이 여기에 있으며, Extra 장에 게시 된 내용 중 일부는 없습니다.
- Imgui 지원: 엔진에 imgui UI를 추가하여 대부분 VulkanEngine 클래스에서 찾을 수 있습니다. 여기에서 설명합니다.
Implementing DearImgui to a Vulkan engine
- CVars.h/cpp: 일부 구성 변수에 대한 CVar 시스템을 구현합니다. 여기에서 설명합니다. 여기 구현된 것은 Imgui에서 변수를 조정하는 지원도 제공합니다.
Configurable options through a CVAR system
- player_camera.h: 지도에서 비행할 수 있는 작은 카메라 시스템입니다.
- logger.h: Console에서 더 좋은 정보/오류 메시지를 얻기 위한 로그 시스템입니다.
- vk_pushbuffer: 동적 Discriptor에 사용되는 버퍼에 데이터를 추가합니다.
- vk_profiler: 각 패스가 얼마나 걸리는 지를 알 수 있는 Time profiler가 추가되었으며, GPU에서 처리하는 삼각형 수를 표시할 수도 있습니다. Imgui에 연결됩니다.
- vk_engine_scenerender.cpp: Main vk_engine.cpp에서 cull Logic과 Draw Logic을 분리합니다. 여기에서 culling과 draw 명령이 실행됩니다.
- vk_scene: draw indirect 버퍼 및 다른 Mesh Pass를 위한 scene 관리를 포함합니다.
- material_system: 특정 재질이 여러 Mesh Pass에서 렌더링되도록 허용하는 새로운 재질 시스템으로, pipeline 및 Descriptors 를 추상화 합니다.
- vk_descriptors: Descriptors 세트의 완전한 추상화로, 여기에서 설명합니다.
A thin abstraction for descriptor sets
- vk_shaders: 셰이더 컴파일링 코드입니다. spirv-reflect를 사용하여 셰이더에서 자동으로 파이프라인 레이아웃을 빌드하고 다른 정보를 가져옵니다.
- 자산 시스템 및 베이커: 여기에서 나온 것입니다. 더 최적화된 메시 형식을 지원하며, 프리팹 및 재질을 지원합니다. 이제 임의의 GLTF 파일과 FBX 파일을로드 할 수 있습니다. 프리팹은 씬 노드의 목록이며 로드될 때 여러 렌더링 가능한 객체로 변환됩니다.
- Compute Shaders: Compute Shaders의 Logic이 Main Vulkan Engine 클래스에 추가되었습니다. 이제 ComputePipelineBuilder 및 메모리 동기화 주위의 기능이 더 많습니다.
- 개선된 버퍼 처리: Uniform Buffers 및 Storage Buffers는 이제 버퍼를 확장하기 위한 Reallocate 기능과 같은 몇 가지 개선이 있습니다. 대부분 vk_engine.cpp에서 이루어집니다.
렌더 플로우
메인 엔진 Render loop는 장(chapter) 이후의 Render loop와 유사하지만 많은 것들이 추가되었습니다. 먼저 렌더링 가능한 객체의 처리는 vk_scene을 통해 이루어지며, 프리팹에서 로드됩니다.
엔진을 초기화할 때 몇 가지 프리팹을 로드하고 MeshObjects로 세계에 주입하여, 이를 RenderScene에 주입한 다음, 재료와 구성에 따라 여러 메시 패스에 객체를 추가합니다.
3개의 메시 패스가 처리됩니다. Forward 패스는 불투명한 개체의 렌더링을 처리하고, Transparent는 투명 객체를 처리하며, 불투명 개체가 완료된 후에 그립니다. 그리고 Shadow 패스가 있습니다. MeshObjects는 설정에 따라 이러한 3개 패스 중 하나에 등록됩니다. 불투명 객체는 Forward 및 Shadow 패스에 추가되고, 투명 객체는 그림자를 캐스팅하지 않으므로 투명 패스에만 등록됩니다.
엔진이 로드되면, RenderScene::build_batches()와 RenderScene::merge_meshes()가 엔진 초기화의 끝에서 호출됩니다. build_batches는 모든 메시 패스를 처리하고 간접 드로우 명령을 준비합니다. merge_meshes는 RenderScene에 등록된 각각의 메시의 버텍스 버퍼를 가져와 하나의 거대한 버텍스 버퍼로 병합합니다. 이렇게 하면 버텍스 버퍼를 메시 패스 당 한 번 바인딩하고 다시 접근하지 않을 수 있습니다.
초기화가 완료되면 프레임 루프로 이동합니다.
프레임 루프의 시작에서는 디스크립터 캐시 및 프레임 삭제 대기열을 플러시하여 동적으로 변경되는 것을 재설정합니다. 그런 다음 ready_mesh_draw()를 호출하여 객체 데이터의 변경 사항을 처리하고 모든 것을 GPU에 업로드합니다. 이것은 RenderScene에서 처리된 데이터를 GPU에 업로드하는 주요 단계입니다.
이것이 완료되면 계산 culling 패스의 데이터를 준비하기 시작합니다. RenderScene의 각 메시 패스마다 ready_cull_data가 호출됩니다. 이렇게 하면 cull 컴퓨트 셰이더에서 쓰기 위해 GPU draw 상태가 "기본" 상태로 재설정됩니다.
다중 ready_cull 호출이 완료되면, 컴퓨트 셰이더가 실행되기 전에 모든 메모리 전송이 완료되도록 파이프라인 배리어를 실행합니다.
그 후, 3개 패스에 대한 culling이 실행됩니다. Forward와 Transparent 패스는 모두 주 카메라 뷰에서 culling을 수행하므로 동일한 설정을 사용하며, shadow 패스는 다른 로직을 사용합니다.
Cull 컴퓨트 셰이더가 실행된 후, draw 명령을 실행합니다. 먼저 shadow_pass()가 실행되어 태양의 위치에서 장면 깊이를 깊이 텍스처로 렌더링합니다. 그런 다음 forward 패스가 실행되며, 불투명한 메시를 모두 렌더링한 다음 투명한 메시를 렌더링합니다.
렌더링이 끝나면, 깊이 버퍼가 깊이 피라미드로 변환됩니다. 이것은 다음 프레임에서 culling에 사용됩니다.
또한 렌더링된 이미지를 스왑 체인으로 복사하여 프레젠테이션에 준비합니다.
'TECH.ART.FLOW.IO' 카테고리의 다른 글
테크니컬 아티스트의 역할 (2) | 2023.09.03 |
---|---|
[번역]A Data-Driven Paradigm for Precomputed Radiance Transfer. PART-1 (0) | 2023.09.01 |
[번역]Texture Virtualization for Terrain Rendering (0) | 2023.08.31 |
[Example]테크아트팀 조직 운영의 예. 타입 1 (0) | 2023.08.29 |
Made a short but strong announcement at ADOBE DAY 2023. (0) | 2023.08.29 |