Readme.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. Atom Meshlets Gem POC
  9. =====================
  10. Author: Adi Bar-Lev, May 2022
  11. Contributors:
  12. Dependencies: meshlets generation is done by an excellent open source library -
  13. the MeshOptimizer library: https://github.com/zeux/meshoptimizer
  14. Demo Show Case
  15. --------------
  16. MeshletsExampleComponent will generate two meshlet models that will be displayed
  17. along side the original one with UVs grouped by meshlet and can be associated with
  18. color.
  19. The first colored meshlets model is the reference model done by generating the meshlets
  20. in the CPU at run time model load and by using the material DebugShaderMaterial_01 based on the
  21. shader DebugShaderPBR_ForwardPass - all copied to this folder.
  22. The second Meshlets model is using the meshlets data from the CPU and processing it
  23. on the fly using dispatch compute that creates the index buffer and the UV coloring - this
  24. is then sent to a direct draw render that will displays it.
  25. The latest is the POC that can be enhance to become a parallel GPU driven pipeline.
  26. Short Intro
  27. ===========
  28. The Meshlets Gem is a POC for rendering meshes solely on the GPU using
  29. meshlets / mesh clusters.
  30. This is done to promote maximum parallelism in processing relative small pieces
  31. of the mesh and gain performance by doind fast culling that due to the size and locality
  32. of these clusters is much more efficient than culling the entire mesh.
  33. The work is inspired by Ubisoft 2015 presentation and recently Nanity by Epic.
  34. The current POC does not do the indirect dispatch and render and lacks the culling
  35. stage - these are the main two steps missing to make it beyond a POC.
  36. What does it do?
  37. ================
  38. - Splits the mesh and creates the data structures requires for meshlets
  39. - Prepares the GPU, buffers and data required by the GPU for such render pipeline
  40. - Dispatch Compute groups that generates the index buffer and debug color UVs
  41. - Direct draw the output of the compute using direct buffer access for the vertex streams
  42. Known Bug:
  43. ==========
  44. - In the latest version there seem to be an occasional missing meshlet group, hence creating
  45. an area with missing polygons, this might be a very simple counting bug. Will be fixed in
  46. future versions.
  47. Moving Forward
  48. ==============
  49. - Create and prepare culling data compute culling data
  50. - Create a new compute stage that will cull the meshlets based on one of the following:
  51. - Previous meshlets reprojected Z (requires pre-pass and adding delta objects)
  52. - Previous Hi-Z (cracks can occur - needs to compensate)
  53. - Best occluders
  54. - other..
  55. - Based on the culling create new indexing table (into the index buffer) for the visible meshlets
  56. - Run the current meshlet compute on visible meshlets only
  57. - Calculate the indices and populate the index buffer
  58. - Add actual PBR render connected to Atom's lighting
  59. - Change the mesh loader and processing as an AssetProcessor builder job to be done offline
  60. Remark: The POC seem to still have a small bug - in some meshes, small amount of polygons
  61. might not render. Due to the selective nature of how it looks, it might be as simple
  62. as missing a meshlet group.
  63. Intent
  64. ======
  65. This POC intent is not to replace the existing render pipeline. The provided gem is a POC towards a GPU
  66. driven render pipeline and is an opportunity for the O3DE community to take this gem as reference and enhance.
  67. Removing the CPU from the equation is considered by many the path to the future of rendering, and using
  68. meshlets techniques increases performance as they eliminate the majority of the invisible meshes in the scene
  69. that otherwise would have sent to render due to partial visibility of the meshes. All in all this technique
  70. represents a much more optimal rendering approach, one that was successfully used by Ubisoft and is a large part of Nanite today.
  71. This approach is parallel to the mesh render pipeline that exists in Atom today and is an opportunity for
  72. O3DE community to look into and hopefully advance in the future.
  73. In no way it comes to replace the existing mesh render pipeline in Atom that is state of the art and coming to maturity.
  74. References:
  75. ===========
  76. Ubisoft - Siggraph 2015: https://advances.realtimerendering.com/s2015/aaltonenhaar_siggraph2015_combined_final_footer_220dpi.pdf
  77. Meshlets Intro - NVidia: https://developer.nvidia.com/blog/introduction-turing-mesh-shaders/
  78. Cluster Culling 2016: https://gpuopen.com/learn/geometryfx-1-2-cluster-culling/
  79. Epic Nanite 2021: https://quip-amazon.com/-/blob/RKb9AAL3zt8/G7A6Cxor0gvn_WPGltB-8g?name=Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf&s=Gn3dAhbv9gN6
  80. Activision - Geometry Rendering Pipeline architecture 2021: https://research.activision.com/publications/2021/09/geometry-rendering-pipeline-architecture
  81. Quick Build and Run Directions
  82. ==============================
  83. This is a summary of the steps you'll need to follow, see the additional sections below for details.
  84. 1. Go over the files in this directory - you'd need to follow the instructions below and copy
  85. the files to various locations. Create a Meshlets branch so you'd do it once only.
  86. 2. Add the gem directory to the file engine.json:
  87. "external_subdirectories": [
  88. "Gems/Meshlets",
  89. ...
  90. 3. Compile meshoptimizer.lib as static library and add it to the Meshlets gem
  91. 4. Update several build configuration files to connect the gem to AtomSampleViewer (ASV)
  92. 5. Run cmake to apply the configuration changes
  93. 6. Update ASV code to add the Meshlets sample
  94. 7. Build the ASV standalone project
  95. 8. Run the standalone ASV and choose the Meshlets demo from the RPI demos sub-menu
  96. 9. When selecting a model, a secondary CPU meshlet model will be generated and
  97. displayed alongside, and in the GPU demo, a third one created by the GPU will
  98. be displayed as well.
  99. Adding the meshoptimizer library to the Gem
  100. ===========================================
  101. The meshoptimizer library is not included as part of the O3DE.
  102. When adding and compiling this Gem, compile the meshoptimizer
  103. library and add it as part of Meshlets.Static project.
  104. Once this is done, the Gem should compile and link properly to allow you
  105. to run the ASV sample 'Meshlets' (created with the MeshletsExampleComponent).
  106. The meshoptimizer library and source can be found in the following Github link:
  107. https://github.com/zeux/meshoptimizer
  108. Here are the specific steps to build and install the library, on Windows:
  109. git clone https://github.com/zeux/meshoptimizer
  110. cd meshoptimizer
  111. mkdir build
  112. cmake . -B build
  113. cmake --build build --config Release
  114. copy build\Release\meshoptimizer.lib [YourO3DEPath]\Gems\Meshlets\External\Lib
  115. Finally, in Visual Studio, right-click the Meshlets.Static project
  116. and click Add > Existing Item..., then select
  117. [YourO3DEPath]\Gems\Meshlets\External\Lib\meshoptimizer.lib
  118. (Note that if you run cmake in O3DE again, this setting will be lost and you
  119. will have to add meshoptimizer.lib to the Meshlets.Static project again).
  120. Connecting the Gem to the project folder (AtomSamplesViewer for example):
  121. =========================================================================
  122. In the following example I will use AtomSampleViewer as the active project. If this
  123. is not the case, simply replace with the directory name of your active project.
  124. 1. Add Meshlets Shader Assets directories to the file
  125. AtomSampleViewer/config/shader_global_build_options.json
  126. "PreprocessorOptions" : {
  127. "predefinedMacros": ["AZSL=17"],
  128. // The root of the current project is always the first include path.
  129. // These include paths are already part of the automatic include folders list.
  130. // By specifying them here, we are boosting the priority of these folders above all the other automatic include folders.
  131. // (This is not necessary for the project, but just shown as a usage example.)
  132. "projectIncludePaths": [
  133. "Gems/Atom/RPI/Assets/ShaderLib",
  134. "Gems/Atom/Feature/Common/Assets/ShaderLib",
  135. "Gems/Meshlets/Assets/Shaders"
  136. ]
  137. 2. Not required: you can choose to add Meshlets Assets in
  138. AtomSampleViewer/Registry/assets_scan_folders.setreg
  139. "Meshlets":
  140. {
  141. "SourcePaths":
  142. [
  143. "Gems/Meshlets/Assets"
  144. ]
  145. }
  146. Remark: this is NOT required in this case as Meshlets can process regular Atom meshes
  147. 3. Enable Meshlets gem for the active project - AtomSampleViewer/project.json
  148. "gem_names": [
  149. ...
  150. "Meshlets"
  151. ]
  152. 4. Add a build dependency on the meshlets gem - AtomSampleViewer/Gem/Code/CMakeLists.txt
  153. ly_add_target(
  154. NAME AtomSampleViewer.Private.Static STATIC
  155. ...
  156. BUILD_DEPENDENCIES
  157. PUBLIC
  158. Gem::Meshlets.Static
  159. 5. Copy the shader debug files (DebugShaderPBR_ForwardPass.*) to the material types directory:
  160. [o3de]\AtomSampleViewer\Materials\Types\*
  161. 6. Copy the material type file 'DebugShaderPBR.materialtype' to the material types directory:
  162. [o3de]\AtomSampleViewer\Materials\DebugShaderPBR.materialtype
  163. 7. Copy the material file 'debugshadermaterial_01.material' to the material directory:
  164. [o3de]\AtomSampleViewer\Materials\DebugShaderMaterial_01.material
  165. Including the Meshlets sample in ASV
  166. ====================================
  167. 1. Add the following two files to the directory [o3de]\AtomSampleViewer\Gem\Code\Source
  168. MeshletsExampleComponent.h
  169. MeshletsExampleComponent.cpp
  170. 2. Alter SampleComponentManager.cpp to include the following lines:
  171. Add the following line to the header files section:
  172. #include <MeshletsExampleComponent.h>
  173. Add the following line to the method SampleComponentManager::GetSamples()
  174. NewRPISample<MeshletsExampleComponent>("Meshlets"),
  175. Set the pipeline descriptor to allow pass injection:
  176. pipelineDesc.m_allowModification = true;
  177. 3. Add the source files to the make file 'atomsampleviewergem_private_files.cmake'
  178. set(FILES
  179. Source/MeshletsExampleComponent.cpp
  180. Source/MeshletsExampleComponent.h
  181. ...