Monthly Archives: June 2010

GLSL Minifier 0.4

We’ve just released GLSL Minifier 0.4! It fixes many problems, and add some new features. Tuesday update: version 0.4.1 improves a few things and adds an option to preserve external values, such as uniforms and varying. Here is the list of changes:

  • Command line is properly handled. Try the “-h” option to see the complete list of flags.
  • The -o option has been added, if you want to get the output in a particular file.
  • There is also a –shader-only, if you don’t want the C header and the formatted string.
  • Vectors accesses are made uniform, using (by default) only the “rgba” set. For instance, “foo.x” is renamed into “foo.r”.
  • Macros can be inserted to shorten external functions calls and types. This can greatly reduce the uncompressed output shader. However, the compressed file will most of the time be bigger (we’ve tested with Crinkler and kkrunchy). You can choose the threshold to control the number of macros that are inserted. This option is disabled by default.
  • The renaming algorithm has been changed. Previous versions of this tool were based on the GLSL 1.10 spec, which states that functions and variables use different namespaces. This is not true anymore since GLSL 1.20, so I had to remove a few tricks in the renamer & obfuscator.
  • 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.
  • Some information is now displayed on the console.
  • The –preserve-externals option has been added, so that you can use this compressor even if you have multiple shaders!

GLSL Minifier has been tested on the hand-optimized shader used in Retrospection, a great 4k intro (many thanks to FRequency and TITS who provided me the code). Here is the data:

Input file size is: 1727
File parsed. Shader size is: 1725
Rewrite tricks applied. Shader size is: 1723
Identifiers renamed. Shader size is: 1610
Macros added.
Minification finished. Shader size is: 1495

Note that this is the uncompressed size (size after macro injection is not useful). Once compiled with the C code and packed with Crinkler, it turns out we saved more than 30 bytes using this tool. If they had GLSL Minifier, FRequency and TITS could have improved even more their intro!

GLSL Minifier was also able to save a few bytes on To the Road of Ribbon, even if auld^titan spent time optimizing the intro to fit in 1k on Windows. Here is an example of output of the tool. See how it’s easy to include the file in your C/C++ project!

#ifndef SHADER_CODE_H_
#define SHADER_CODE_H_

const char *shader_roadOfRibbon = ""
 "float c=gl_Color.r*55;"
 "float e(vec3 e)"
 "{"
   "return min(cos(e.r)+cos(e.g)+cos(e.b)+cos(e.g*20)*.02,length(max(abs(e-vec3(cos(e.b)*.2,cos(e.b)*.2-.5,0))-vec3(.2,.02,c+3),vec3(0))));"
 "}"
 "vec3 o(vec3 c)"
 "{"
   "return normalize(vec3(e(c+vec3(.02,0,0)),e(c+vec3(0,.02,0)),e(c+vec3(0,0,.02))));"
 "}"
 "void main()"
 "{"
   "vec3 v=vec3(cos(c),-cos(c*.5)*.5+.5,c),r=normalize(vec3(gl_FragCoord.rg*.002-1,1)),n=v;"
   "for(int c=0;c<55;c++)"
     "n+=r*e(n);"
     "vec3 l=n+=r=reflect(r,o(n));"
     "for(int c=0;c<55;c++)"
       "n+=r*e(n);"
       "gl_FragColor=abs(dot(o(n),vec3(.1)))+vec4(.2,cos(c*.5)*.5+.5,sin(c*.5)*.5+.5,1)*length(n-v)*.01+length(n-v)*.01+(1-min(l.g+2,1.))*vec4(1,.8,.7,1);"
 "}";
#endif // SHADER_CODE_H_