shader预编译为二进制,在程序运行时候加载,可以提升性能,节省启动时间.
1. 采用google shaderc预编译与加载shader
1.1 下载代码 https://github.com/google/shaderc
third_party文件里需要放依赖的第三方
因为电脑访问google的问题,无法通过shaderc-2023.4\utils\git-sync-deps
脚本自动下载第三方,手动下载
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 配置
用CMake (cmake-gui)构建shaderc,生成vs工程
别忘了配置第三方库目录
1.3 编译
vs编译shaderc,得到头文件和库
所有的库都是MDD的动态库
2. 在引擎里引入shaderc
2.1 在CmakeLists.txt增加头文件和库
shaderc提供了两种方式引用,
- 直接用libshaderc_combined,这是一个静态库
- 用glslang, OSDependent, OGLCompiler,shaderc_util, SPIRV, HLSL, SPIRV-Tools, and SPIRV-Tools-opt.
2.2 源码修改
在openGLShader.cpp
里CompileOrGetOpenGLBinaries
会判断是否有cache文件,没有就生成shader bin文件,有就加载bin文件.
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source_text, Utils::GLShaderStageToShaderC(stage), m_FilePath.c_str(), options);
CreateProgram
会根据bin文件创建shader,跳过了编译的过程.
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. 性能
- 直接编译shader代码的方式,每个shader消耗20ms
- 初次编译shader生成bin文件的方式,每个shader消耗2000ms
- 直接加载shader bin文件的方式,每个shader消耗5ms