This product will make you happy.

Shader Minifier is a tool to pack HLSL or GLSL shader code. You can use it to make nice 4k PC-demos (such as this one) or to obfuscate your shader code in your next video game (don’t forget there are tools to intercept and display your shader code while your application is running). It generates a code as small as possible that is equivalent to the input code. The generated code is also designed to compress well, and has been optimized for use with Crinkler, but should perform well with any other compression tool. Shader Minifier generates a C header file you can include from your code. This file contains the shader code in a compact string and macros to retrieve the name of the uniforms (because they are renamed).

How well does this tool pack? Can’t I do it by hand?

Size-optimizing a shader code by hand is tedious and inefficient. No matter how good your are, this GLSL/HLSL packer will probably be able to improve your hand-optimized code. It doesn’t mean you can do stupid things and rely only on the tool. Basically, you should do the optimizations the tool cannot do. Keep all the spaces, comments and useful variables names you need to have a readable and maintainable piece of code. You should focus on clever optimizations.

Most intros, even among the best ones, would benefit from this tool. Hand-written shaders can often be reduced by dozens of bytes (after compression) by using Shader Minifier. See statistics.

Features

  • Code is parsed and pretty-printed in an automatic and uniform way.
  • A C header code is (optionally) generated. The shader is split in many lines (using quotes on every line) and indented, so that you can still maintain the shader.
  • Useless whitespaces and comments are removed.
  • Useless parenthesis are removed, by applying GLSL precedence rules.
  • Useless curly brackets are removed. eg. “if(test){a=4; return b++;}” is replaced by “if(test)return a=4,b++;”
  • Constant arithmetic expressions are simplified. This allows you to keep a more readable input file. 3.14159 * 2. will become 6.28318
  • Definitions are squeezed. eg. “float a=2.;float b;” becomes “float a=2.,b;”
  • User variables and functions are renamed, usually using a single letter. Names are reused as much as possible (this includes overloading functions, and variable shadowing). Agressive name reuse greatly improves compression, and delays the point where you need two-letters names.
  • Variables that start with “i_” are inlined. That will help you keep a clear code, name your values, while still having a short final code. The inlining is stupid, so avoid side-effects!
  • Vectors accesses are made uniform, using (by default) only the “xyzw” set. For instance, “foo.r” is renamed into “foo.x”.
  • The smoothstep function can be rewritten using IQ’s trick. It’s not done by default, because it’s not always a good thing to do.
  • If you use multiple shaders, you might use the –preserve-externals function, and your uniform/varying/attribute values won’t be renamed.

Example of (stupid) input file:

  1. uniform int time;
  2.  
  3. float sum(vec3 v) { return v.x + v.y + v.z; }
  4.  
  5. float foo(vec3 v, float k) {
  6.   float tmp = 1.;
  7.   int i_count = 4;
  8.   for (int i = 0; i < 5 * i_count; ++i)
  9.     tmp /= k;
  10.   return tmp * v.sts;
  11. }

Here is the generated output, ready to be included in a C/C++ project!

  1. #ifndef SHADER_CODE_H_
  2. #define SHADER_CODE_H_
  3. #define U_TIME "r"
  4. const char *shader_test = ""
  5.  "uniform int r;"
  6.  "float t(vec3 r)"
  7.  "{"
  8.    "return r.r+r.g+r.b;"
  9.  "}"
  10.  "float t(vec3 r,float t)"
  11.  "{"
  12.    "float o=1.;"
  13.    "for(int r=0;r<20;++r)"
  14.      "o/=t;"
  15.    "return o*r.rgr;"
  16.  "}";
  17. #endif // SHADER_CODE_H_

Bugs, limitations

  • Macros are not modified (useless whitespace will be removed though). If you do tricky things in your macro (eg. if the replacement is needed to parse the code), the tool might fail. Also, you’re not allowed to use macros inside functions or expressions.
  • User-defined records are not renamed and cannot contain fields conflicting with vec4 (e.g. “r”, “rg”, “x”…).
  • If you have overloaded functions in your input, the tool might be confused.

Download

Download Shader Minifier 1.0 (free for demoscene or non-commercial use).
This exe should work on Windows and Unix, but you’ll need Microsoft .NET or Mono.

Please send your comments and suggestions, either on #ctrl-alt-test (on IRCNet), or by email (laurentlb [at] gmail.com).

6 Responses to “Shader Minifier”

  1. [...] Ce billet était mentionné sur Twitter par Frank Tovar, p0unce. p0unce a dit: 4k writers, #ctrl-alt-test released a new GLSL minifier tool by http://www.ctrl-alt-test.fr/?page_id=7 #demoscene [...]

  2. [...] GLSL Minifier is a tool made by a french demogroup (yeah!) to pack GLSL shader code into a C header file. It generates a code as small as possible that is equivalent to the input code. GLSL Minifier has been optimized for the compression tool Crinkler. [...]

  3. [...] GLSL minifier Possibly related posts: (automatically generated)Scenarios for jscJSC Ultra Application to Support [...]

  4. [...] optimized for the compression tool Crinkler. More information about Shader Minifier can be found HERE. Size-optimizing a shader code by hand is tedious and inefficient. No matter how good your are, [...]

  5. [...] generating music in byte-sized intros. To shrink the file size even further, CTRL-ALT-TEST’s Shader Minifier was applied – an “uniminified” and commented JOGL2 port of Hartverdrahtet is [...]

  6. [...] we did after Revision 2012 was changing from binary shaders to text shaders; size optimized by Shader Minifier. This approach saved us around 4 kb of compressed size in the player executable, but pap believed [...]