[HN Gopher] 15 Years of Shader Minification
___________________________________________________________________
15 Years of Shader Minification
Author : laurentlb
Score : 137 points
Date : 2025-05-10 07:51 UTC (3 days ago)
(HTM) web link (www.ctrl-alt-test.fr)
(TXT) w3m dump (www.ctrl-alt-test.fr)
| zombot wrote:
| > #define R return
|
| OK, that was not what I thought of when reading "shader
| minification".
| pests wrote:
| Thankfully that's not what the article is about, three
| paragraphs later it is noticed this has no savings after
| compression.
| keyle wrote:
| The author is referencing the demo scene, where they often have
| to meet very tight budgets in terms of space, so everyone is on
| an equal footing and it makes for very interesting wow moments.
| monokai_nl wrote:
| Thank you for making this tool. I'm calling it in a custom
| webpack plugin so it transforms GLSL code into a single minified
| string on every build / watch event. I used this setup for my
| latest artwork: https://monokai.com/work/origin
| akomtu wrote:
| With recursive #defines it would be possible to do LZW
| compression.
| wiz21c wrote:
| do you actually needs recursivity for that ?
| pjmlp wrote:
| The pain of GL shaders, only because they don't embrace modern
| programming like modules and bytecode delivery.
|
| 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.
| ryao wrote:
| Regarding bytecode delivery, have you seen SPIR-V?
|
| 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.
| TazeTSchnitzel wrote:
| Dynamic linking is returning because of ray-tracing also.
| pjmlp wrote:
| Of course, but that is only for Vulkan, technically it is
| possible with OpenGL 4.6, but I doubt anyone is bothering
| with it.
|
| 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.
| manchmalscott wrote:
| I mean, in my personal projects I've transpiled GLSL into
| spir-v bytecode for use with OpenGL 4.5, even. Libshaderc
| has suppported that for years.
| pjmlp wrote:
| Maybe using extensions?
|
| "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
| BearOso wrote:
| > Of course, but that is only for Vulkan, technically it is
| possible with OpenGL 4.6, but I doubt anyone is bothering
| with it.
|
| https://devblogs.microsoft.com/directx/directx-adopting-
| spir...
| pjmlp wrote:
| Yes, and what does that change in the context of GLSL?
| laurentlb wrote:
| I wrote this article mainly for the people in the demoscene. If
| anything is unclear or missing for the Hackernews audience, I'm
| happy to answer questions here.
|
| 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.
| tonyhart7 wrote:
| is there HN equivalent on game industry??
| wesz wrote:
| https://gamedev.city/
| tonyhart7 wrote:
| wow, seems empty
| tough wrote:
| Some older discussions about this:
|
| https://news.ycombinator.com/item?id=40419289
| sagacity wrote:
| This is an awesome tool, thanks Laurent! Currently using it for
| my next 64k intro which will probably ship sometime in 2047 :)
| slimbuck wrote:
| Have you tested the shader's runtime performance penalty after
| minification?
|
| Also wondering how you handle named uniforms?
| ryao wrote:
| I cannot answer this for him, but I can speculate on the answer
| to your first question. The transformations he described his
| minifier applying do not change the code from the perspective
| of the compiler in any meaningful way, so the end result should
| have no performance difference. The only possible exception is
| the inlining, but the compiler likely would have done that
| anyway, so the end result should still have no difference.
|
| 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.
| laurentlb wrote:
| Most transformations don't change the code that's executed.
| 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.
| gitroom wrote:
| Man, 15 years grinding on this is hardcore - big respect, love
| this kinda craft.
| laurentlb wrote:
| Thanks! To be fair, there have been a few years without a
| single commit: https://github.com/laurentlb/shader-
| minifier/graphs/contribu... (before 2013, the code was in a
| private svn repo).
|
| 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. :)
___________________________________________________________________
(page generated 2025-05-13 23:02 UTC)