The shader is precompiled into binary and loaded when the program is running, which can improve performance and save startup time.
1. Use google shaderc to precompile and load shader
1.1 Download code https://github.com/google/shaderc
The third_party file needs to put the dependent third party.
Because of the problem of computer access to google, shaderc-2023.4\utils\git-sync-deps
the third party cannot be downloaded automatically through the script. Manually download
https://codeload.github.com/KhronosGroup/SPIRV-Tools/zip/refs/tags/v2023. 3.rc1
https://codeload.github.com/KhronosGroup/SPIRV-Headers/zip/refs/tags/sdk-1.3.250.1
https://codeload.github.com/KhronosGroup/glslang/zip/refs/tags/ sdk-1.3.250.1
1.2 configuration
Use CMake (cmake-gui) to build shaderc, generate vs project
Don't forget to configure the third-party library directory
1.3 compile
VS compiles shaderc to get header files and libraries
All libraries are dynamic libraries of MDD
2. Introduce shaderc into the engine
2.1 Add header files and libraries to CmakeLists.txt
shaderc provides two ways to reference,
- Use libshaderc_combined directly, which is a static library
- 用glslang, OSDependent, OGLCompiler,shaderc_util, SPIRV, HLSL, SPIRV-Tools, and SPIRV-Tools-opt.
2.2 Source code modification
It will judge whether there is a cache file, if not, generate a shader bin file, and load the bin file if there is one openGLShader.cpp
.CompileOrGetOpenGLBinaries
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source_text, Utils::GLShaderStageToShaderC(stage), m_FilePath.c_str(), options);
CreateProgram
The shader will be created according to the bin file, skipping the compilation process.
glShaderBinary(1, &shaderID, GL_SHADER_BINARY_FORMAT_SPIR_V, spirv.data(), spirv.size() * sizeof(uint32_t));
glSpecializeShader(shaderID, "main", 0, nullptr, nullptr);
glAttachShader(program, shaderID);
3. Performance
- The way to directly compile the shader code, each shader consumes 20ms
- The first time the shader is compiled to generate the bin file, each shader consumes 2000ms
- The way to directly load the shader bin file, each shader consumes 5ms