Closed stanoddly closed 2 weeks ago
Ok so this is my first proposal. MyShader.shadermeta
:
{
"stage": "fragment",
"resources": {
"samplers": 0,
"storageTextures": 0,
"storageBuffers": 0,
"uniformBuffers": 0
},
"shaders": [
{
"format": "spirv",
"path": "vulkan/MyShader.spirv",
"entryPoint": "main"
}
]
}
shaders
as a list is future proof, I can potentially add version
later. entryPoint
is part of the shader
because it may be different for each format
.
I could also embed a binary shader into shadermeta too:
{
"format": "spirv",
"content": "BASE64 VERY LONG CONTENT",
"entryPoint": "main"
}
But that's a different story.
In the end I took a slightly different direction.
Instead of shader metadata I will store shaders themselves. ShaderPack
with an extension .spak
(or .spak.json
for json
). JSON looks like this:
{
"stage": "vertex",
"resources": {
"samplers": 0,
"storageTextures": 0,
"storageBuffers": 0,
"uniformBuffers": 0
},
"shaders": [
{
"format": "spirv",
"entryPoint": "main",
"content": "..."
}
]
}
For JSON content
is either text based shader code (e.g. .msl
) or binary in base64 (all other shaders basically).
In future .spak
could be generated by a command line tool which would take a source shader language program. The source language could be any language that could be compiled or/and transpiled into different shader languages/bytecodes. That means GLSL, HLSL or even slang (but no Metal and god forbid WGSL).
Before I have the command line I have to do things manually and create base64 via command line:
cat shader.spv | base64 -w 0
Not great, not terrible.
Currently the shaders use a builder pattern, e.g.:
It is used to allow specify multiple things: stage, entry-point, resources and the way to load it. However, it's awkward. 😅 This information is available during the shader creation, nobody should specify it at compile time. On top of that, entry-point could be different per each platform.
I think that it would be more beneficial to treat it as a content (read this one) and require an additional file which would contain all the required metadata to be able to configure shader properly. For example
MyShader.shadermeta
:(the json schema is stupid I know, just to get the idea)
Then in the code I could just:
And all the shader metadata would be handled as a content and the code wouldn't expose it. Looks simple and stupid.