2 releases
0.1.2 | Jun 21, 2024 |
---|---|
0.1.0 | Sep 19, 2023 |
#245 in Graphics APIs
Used in nanogltf
24KB
490 lines
shadermagic
shadermagic
is a crate I wish existed. Think Therkla's hlslparser, but rust native.
shadermagic
pretend to be a compiler from pseudo-glsl to different glsl variants and Metal's MSL.
If you want something that actually works, check naga, spirvcross, sokol-shdc, glslang, glslcc, hlsl parser, hlslparser fork or even nanoshredder.
Another relevant case study is this emscripten hack. shadermagic
is a slightly more advanced version of the same idea.
shadermagic
takes some undocumented almost #version 130 shader and apply a ton of String::replace to make plain version 100
, version 100 with webgl1 extensions
, 130
, 330
, 300 es
and metal's MSL
.
Metal is a bit of a special case, with a bit of extra code on top of String::replace
. But it is still very sipmple string manipulations. shadermagic
knows nothing about AST and shaders semantics.
shadermagic
will never work well on arbitary glsl input. No amount of string::replace
could replace a compiler. However, it might be possible to design shaders specifically for shadermagic
, and it might take less work than hand-writing for each target. Or not! I really hope I put enough warnings here.
How to make glsl->metal works
Enough with warnings, tips to keep this bunch of hacks afloat:
- don't access uniforms outside the
main()
function, pass them as arguments. - put the main function last, after everything else in the shader
- annotate attribute in the vertex shader with // [[attribute(N)]]
- annotate varying in the vertex/fragment shader with // [[user(locnN)]]
- avoid functions with the same names in vertex/fragment shaders
- remember that String::replace is very stupid and does not take any context into account. Avoid naming things like "mymat3", avoid things like "BaseColor" and "Color". Yes, this is that bad.
- avoid .s/.t/.p/.q, use .x/.y/.z/.w instead
Dependencies
~1–1.6MB
~37K SLoC