I'm using shaderc to compile glsl code in to spirv module and pass to pipelie in REAL-TIME. I want to use #include to reuse some of the shader code but shaderc is having problems recognizing it. Any one know how to solve this? (I'm NOT using command line to compile shader upfront.)
The error I got from shaderc is:
standard.vert:6: error: '#include' : #error unexpected include directive for header name: GlobalInclude.glsl
Here are my shaders and client codes:
standard.vert
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable
#include "GlobalInclude.glsl"
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
void main() {
gl_Position = passUBO.proj * passUBO.view * objectUBO.model * vec4(inPosition, 1.0);
fragColor = inColor;
fragTexCoord = inTexCoord;
}
standard.frag
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_KHR_vulkan_glsl : enable
#extension GL_GOOGLE_include_directive : enable
#include "GlobalInclude.glsl"
layout(set = PASS_SET, binding = TEXTURE_SLOT(0)) uniform sampler2D texSamplerAlbedo;
layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
void main() {
//outColor = vec4(fragTexCoord, 0.0, 1.0);
outColor = texture(texSamplerAlbedo, fragTexCoord);
}
GlobalInclude.glsl
#define FRAME_SET 0//per frame
#define SCENE_SET 1//per scene
#define PASS_SET 2//per pass
#define OBJECT_SET 3//per draw call
#define UNIFORM_BUFFER_BINDING_START 0
#define TEXTURE_BINDING_START 1
#define TEXTURE_SLOT(NUMBER) TEXTURE_BINDING_START + NUMBER
layout(set = SCENE_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform SceneUniformBufferObject {
uint time;
} sceneUBO;
layout(set = PASS_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform PassUniformBufferObject {
mat4 proj;
mat4 view;
uint passNum;
} passUBO;
layout(set = OBJECT_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform ObjectUniformBufferObject {
mat4 model;
} objectUBO;
layout(set = FRAME_SET, binding = UNIFORM_BUFFER_BINDING_START + 0) uniform FrameUniformBufferObject {
uint frameNum;
} frameUBO;
Compile shader using shaderc API:
bool Shader::CreateShaderFromFile(shaderc_shader_kind kind, bool optimize)
{
// read shader string
if (!ReadShaderFromFile())
return false;
shaderc::Compiler compiler;
shaderc::CompileOptions options;
// like -DMY_DEFINE=1
//options.AddMacroDefinition("MY_DEFINE", "1");
if (optimize) options.SetOptimizationLevel(shaderc_optimization_level_size);
std::cout << "output 1:" << shaderString << std::endl;
// preprocess
shaderc::PreprocessedSourceCompilationResult preprocessed = compiler.PreprocessGlsl(shaderString, kind, fileName.c_str(), options);
if (preprocessed.GetCompilationStatus() != shaderc_compilation_status_success)
{
throw std::runtime_error(preprocessed.GetErrorMessage());
return false;
}
shaderString = { preprocessed.cbegin(), preprocessed.cend() };
std::cout << "output 2:" << shaderString << std::endl;
// compile
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(shaderString, kind, fileName.c_str(), options);
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
{
throw std::runtime_error(module.GetErrorMessage());
return false;
}
shaderBytecode = { module.cbegin(), module.cend() };// not sure why sample code copy vector like this
return true;
}