Shader — a loaded, backend-agnostic shader asset — and ShaderLibrary — the runtime registry that loads, caches, and hot-reloads shaders during development. Shader source is stored separately per API: HLSL for DirectX 12 and GLSL for Vulkan. On Android, the Gradle build plugin automatically compiles GLSL to SPIR-V before packaging.
Shader paths
Source files are stored underresources/common/shaders/ and split by language:
.spv files for Vulkan. The Vulkan path on Android differs — see Android SPIR-V compilation below.
Shader class
Prisma::Graphic::Shader is both a Prisma::Asset and an IShader. It holds the raw SPIR-V bytecode (as uint32_t[]), shader reflection data, and an optional RHI resource handle pointing to the backend-created shader object.
Load
.spv), stores the raw bytecode in m_Bytecode and m_BytecodeBytes, and parses the shader reflection data. Returns true on success.
const std::filesystem::path&
required
Path to the compiled shader file. Relative paths are resolved from the engine’s working directory.
Unload
m_RHIResource) is reset, triggering GPU-side destruction when no other references exist.
GetBytecodeRaw
uint32_t words — the format required by vkCreateShaderModule. Use GetBytecode() for the equivalent uint8_t view.
GetReflection / FindResource
GetReflection() returns the full reflection structure parsed when the shader was loaded. FindResource() looks up a binding by name; FindResourceByBindPoint() looks up by register index and register space (DirectX 12 terminology).
SetRHIResource / GetRHIResource
ShaderType
ShaderLanguage
Shader::GetLanguage() always returns ShaderLanguage::SPIRV — the engine operates exclusively on compiled bytecode at runtime.
ShaderLibrary
ShaderLibrary is an ISubSystem that caches loaded Shader objects by name and optionally performs hot-reload polling during development.
ShaderLibrary::Load
path, stores it under name, and returns a shared pointer. If a shader with the same name is already cached, the cached version is returned without re-loading from disk.
const std::string&
required
Logical name used to retrieve the shader later with
Get().const std::filesystem::path&
required
Path to the compiled
.spv or HLSL bytecode file.ShaderLibrary::Get
nullptr if no shader with that name has been loaded.
const std::string&
required
The logical name passed to
Load().Hot reload
ShaderLibrary::Update() is called each frame by the engine. It accumulates time and, once per second, checks the modification timestamps of all loaded shader files against the values recorded at load time. When a file has changed on disk, it reloads and replaces the cached Shader automatically. This is active only in debug builds.
ShaderCompileOptions
PassShaderCompileOptions when using a backend that supports runtime compilation (e.g., HLSL via DXC):
bool
Embed debug information in the bytecode. Disables most optimisations. Defaults to
false.bool
Enable backend optimisations. Defaults to
true.int
Optimisation level from
0 (disabled) to 3 (maximum). Defaults to 3.bool
Treat compile warnings as errors. Defaults to
false.std::vector<std::string>
Preprocessor defines injected at compile time, e.g.
"ENABLE_SHADOWS".Android SPIR-V compilation
On Android, GLSL shaders are not pre-compiled offline. Instead, the Android Gradle plugin compiles them automatically during the build:- Source location:
projects/android/PrismaAndroid/app/src/main/assets/shaders/ - File extensions:
.vert,.frag,.comp - Output:
build/intermediates/shader_assets/**/*.spv— bundled into the APK automatically.
.spv files from the APK asset archive:
glslangValidator or spirv-cross manually — the Gradle plugin handles compilation as part of ./gradlew assembleDebug.