The ShaderSystemDemo is a prototype in C++, which can dynamically compile any shader language into any renderer api.
The demo just displays a 2D quad on the screen, but with different colors for each vertex of the quad. More complex demos might follow soon.
To start the demo application, you just need python
and Visual Studio 2022
. The VS solution is automatically generated by premake
.
git clone https://github.com/Cankar001/ShaderSystemDemo
cd ShaderSystemDemo/Scripts && python Setup.py
Now you should see the solution file in the root directory of the project. Just open it and build either the Debug or Release build.
Windows | Linux | MacOS | Android | IOS | Web |
---|---|---|---|---|---|
✓ | X | X | X | X | X |
OpenGL | Vulkan | DirectX 11 | DirectX 12 | Metal |
---|---|---|---|---|
✓ | X | ✓ | X | X |
By default, the demo will use OpenGL in combination with the GLSL demo shader. If you go into the Main.cpp
file, you should see this function call:
Renderer::SelectRenderingBackend(RenderingAPIType::OpenGL);
If you change the enumeration, the shader system will automatically build the shader binary for the respective rendering backend in the background, this is the current mapping:
OpenGL:
- Shader source -> SPIRV binary
- Reflection on the SPIRV binary
- SPIRV binary can be used by OpenGL
Vulkan:
- Shader source -> SPIRV binary
- Reflection on the SPIRV binary
- SPIRV binary can be used by Vulkan
DirectX11/DirectX12:
- Shader source -> SPIRV binary
- Reflection on the SPIRV binary
- SPIRV binary -> HLSL binary
- HLSL binary is compiled again by the DirectX11 api.
Metal:
- Shader source -> SPIRV binary
- Reflection on the SPIRV binary
- SPIRV binary -> MSL binary
- MSL binary can be used by Metal
This pipeline is applied automatically, all you have to do is to select the rendering backend in the Main.cpp
file.
Currently the default shader language is GLSL, but the system will work with HLSL shaders as well.
The current usage looks like this:
BufferLayout flatColorShaderLayout = {
BufferElement("a_Position", ShaderDataType::Float3, false),
BufferElement("a_TexCoord", ShaderDataType::Float2, false),
BufferElement("a_Color", ShaderDataType::Float4, false)
};
// This loads the GLSL shader and the system knows the language based on the file extension
s_Data->Library->Load("assets/shaders/FlatColorShader.glsl", flatColorShaderLayout, true);
// So this would load the HLSL shader version
s_Data->Library->Load("assets/shaders/FlatColorShader.hlsl", flatColorShaderLayout, true);
The above example can be found in ShaderSystem/src/Renderer/Renderer.cpp
.
If you take a look into the Main.cpp
file, there you can see that the uniform buffers and also the vertex attribute layout are hardcoded.
This will also improve in the near future, as the current implementation already does a reflection on the shader source, so in the future there shouldn't be a manual creation of uniform buffers necessary.