[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)