Skip to main content
Prisma Engine compiles and manages shaders through two classes: 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 under resources/common/shaders/ and split by language:
At runtime the engine loads pre-compiled bytecode: DXIL blobs for DirectX 12 and SPIR-V .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

Reads a compiled shader file from disk (SPIR-V .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

Releases the bytecode vectors and clears reflection data. The RHI resource handle (m_RHIResource) is reset, triggering GPU-side destruction when no other references exist.

GetBytecodeRaw

Returns the SPIR-V bytecode as 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

The engine sets the RHI resource after uploading the bytecode to the GPU. Retrieve it when you need the backend shader handle for pipeline state creation.

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

Loads a shader from 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

Returns a previously loaded shader by name, or 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

Pass ShaderCompileOptions 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.
At runtime the engine loads the .spv files from the APK asset archive:
You do not need to invoke glslangValidator or spirv-cross manually — the Gradle plugin handles compilation as part of ./gradlew assembleDebug.

Per-API shader directories

Example: loading shaders for a custom pipeline