That is how one ends up with shader minification.
And this is still quite actual as pain point, given how shaders work in 3D Web APIs.
As for modules, avoiding them is a performance feature since it is easier to optimize code when you compile everything in one unit. Rather than go toward modules, modern graphics has moved away from them by removing dynamic linking from newer shader languages such as SPIR-V. I believe a limited form of dynamic linking was later introduced in the form of graphics pipeline libraries for avoiding performance issues from a combinatoric explosion of partially redundant compilations when translating shaders from Direct3D 11 and earlier, but for anything outside of translating other APIs, you are supposed to avoid using that as far as I know.
It is also the way on most proprietary APIs.
Metal and DirectX have dynamic linking, shader libraries, and one thing slang thankfully has, is exactly being a modern modular language, which has been given to Khronos as GLSL successor, alongside the already major adoption HLSL, GLSL is done.
"Khronos Releases OpenGL 4.6 with SPIR-V Support"
https://www.khronos.org/news/press/khronos-releases-opengl-4...
> OpenGL 4.6 adds support for ingesting SPIR-V shaders to the core specification, guaranteeing that SPIR-V shaders will be widely supported by OpenGL implementations
https://devblogs.microsoft.com/directx/directx-adopting-spir...
If anyone wants to try it, I've made a web build: https://ctrl-alt-test.fr/minifier/
I might write a more general article later on writing code minifiers, e.g. how it compares to writing a code formatter, how to implement the transformations, etc.
On the tech side, the code is written in F#. The web build uses Bolero (Blazor for F#). So maybe I'll write later about my experience writing an open source project with F# and evolving it.
Also wondering how you handle named uniforms?
To state that more precisely, everything is going to be translated into a SSA syntax in a compiler pass at some point. At that point, much of what he described should be either something the toolchain would have done (such as comment removal by the preprocessor) or effectively undone (such as the variable name reuse since by definition SSA makes each variable name be used exactly once). The rest should converge to the same result after subsequent optimization passes (such as an inlining pass). If you find a performance difference from using his tool, file a bug report with your compiler’s authors.
const float x = sin(2);
const float y = 2;
If you define these two consts, we can inline y everywhere it's used. But by default, we don't inline x as it would lead to more work at runtime (maybe it doesn't matter for sin, but other function calls can be expensive). If you notice performance issues, please file a bug.Renaming uniforms is optional (there's a flag). If you use C++, you can generate a .h header file that contains both the minified shader and macros that tell you how they've been renamed.
So Shader Minifier will generate macros like:
# define VAR_time "f"
to tell you that "time" is now called "f" and you can use VAR_time in your C++ code.I also enjoy alternating work between multiple of my hobby projects, and I find it refreshing to come back to this F# codebase once in a while. :)
zombot•9mo ago
pests•9mo ago
keyle•9mo ago