Shader Minifier by Ctrl-Alt-Test [web]
screenshot added by LLB on 2010-06-15 23:26:07
platform :
type :
release date : june 2010
  • 46
  • 6
  • 0
popularity : 69%
  • 0.88
alltime top: #1649
added on the 2010-06-15 23:26:07 by LLB LLB

popularity helper

increase the popularity of this prod by spreading this URL:

or via: facebook twitter pinterest tumblr


You might have guessed from the name: this tool will pack your GLSL shader and make it as small as possible. Spaces, comments, useless parenthesis will be removed, variables will be renamed, compile-time known values might be simplified, macros can be inserted, and many other tricks are applied. This tool requires
.NET or Mono, it should work on Windows, Linux, Mac, BSD. I hope it will help you make great intros. :)

Please check our website for complete description and examples. Feel free to send me features requests and optimizations ideas!

added on the 2010-06-15 23:28:02 by LLB LLB
hell yes !!
rulez added on the 2010-06-15 23:33:35 by xtrium xtrium
rulez added on the 2010-06-15 23:37:39 by wullon wullon
rulez added on the 2010-06-15 23:48:57 by _0x3a ^DESiRE _0x3a ^DESiRE
The name alone is worth a thumb. ;)
rulez added on the 2010-06-16 00:14:46 by tomtebloss tomtebloss
I wonder how such tool fits in the workflow of a demo coder.

Wouldn't it be nice have such tool in JS ? It would to work online and offline, be smaller, not require .NET or Mono. I doubt there would be any noticeable speed difference. Idealy this could be combined with something à la ShaderToy to see the result right away and be able to tweak the original shader, minify it, compare sizes and results.
added on the 2010-06-16 00:29:23 by p01 p01
p01: usually, people don't write their intro in their browser, they use a compiler + IDE. They can call this tool just before compiling in release and calling crinkler. The tool outputs either some C code or the shader alone (if someone wants another output format, I can add it).

I'm not sure if it would be useful to put this tool online, but I can try to use it as a CGI. The code is quite complex - I doubt anyone will rewrite it in JS.
added on the 2010-06-16 00:38:01 by LLB LLB
really cool LLB, I did once a ShaderStrip equivalent handling vertex and fragment shader uniform problem... but I was not enough motivated to integrate a full parser! ;) Nice job!

I read that you have used F# and FParsec for the lexer/grammar... I'm not a huge fan of functionnal programming, but I have to admit that when it comes to lexer/parser, the syntax is extremely close to what we would write in a lex/yacc... without the pain of a more complex build chain and integration into the host language...

@p01, well shader obfuscation is mainly used when you are coding a 4k in c/c++/asm, checking compression ratio against crinkler, so I don't really see benefit of a cooperative usage with shadertoy... and It's indeed nice to have such a tool integrated in an intro build process.
rulez added on the 2010-06-16 00:39:41 by xoofx xoofx
rulez added on the 2010-06-16 00:41:58 by sigflup sigflup
(hehe, LLB, from your resume, I understand now why you are using F#... :D )
added on the 2010-06-16 00:45:27 by xoofx xoofx
rulez added on the 2010-06-16 00:45:36 by mad mad
it makes it smaller, no doubt, but does it make it compress better? :)
added on the 2010-06-16 01:04:44 by Gargaj Gargaj
Gargaj: yes. Some features such as the #define are not enable by default because it makes the compressed result bigger (even if the uncompressed file is much smaller).

The name of variables and functions is based on a statistical analysis of the code. Names are reused as much as possible, using function overloading and variables shadowing, in order to make the output compress better.

I have some ideas for the next version (using type information + detecting patterns in the code), but if you have suggestions to improve it, I'd love to hear them!
added on the 2010-06-16 01:12:43 by LLB LLB
rulez added on the 2010-06-16 01:25:28 by ponce ponce
Nice idea, nice execution :)

But somehow I'm still more into the idea of murdering myself by writing obfuscated, ugly code from the start haha
rulez added on the 2010-06-16 02:34:56 by ferris ferris
Oh, and nice name <3
added on the 2010-06-16 02:35:09 by ferris ferris
Can someone bother to recompress some intro using it to see what happens?

Anyway nice useful tool.
rulez added on the 2010-06-16 03:06:25 by xernobyl xernobyl
good job!
with em defines for globals its absolutely working.
i prefer to do the job by hand tho, more control of bytes ;)
rulez added on the 2010-06-16 03:33:49 by ɧ4ɾɗվ. ɧ4ɾɗվ.
rulez added on the 2010-06-16 04:13:03 by PENETRATOR PENETRATOR
nice one could use later on D:
rulez added on the 2010-06-16 06:25:58 by panic panic
r0x0r, very very nice !
Melikes ++
rulez added on the 2010-06-16 06:56:34 by cxnull cxnull
i've been waiting for that. cool!
rulez added on the 2010-06-16 08:17:30 by mueslee mueslee
Basically great, but it doesn't support forward declaration of functions, which our 4ks need:

Code: Parse error: Error in src\shader.fs: Ln: 12 Col: 19 vec4 traceRay(vec3, vec3, int); ^ Expecting: Ascii letter, digit, identifier, whitespace or '_'
rulez added on the 2010-06-16 08:56:09 by xTr1m xTr1m
xTr1m: I didn't expect people would use it (you can always reorder, right?). Anyway, I'll update the parser, and I will also add recent GLSL features (invariant, centroid, switch...).
added on the 2010-06-16 09:48:15 by LLB LLB
LLB & @lx: I know the main use case of that tool is for 4K intros. The impact of the obfuscation/minification on the compression ratio slipped my mind :p

My idea of having such tool written in JS and integrated with shader preview was to be able to spot the eventual errors and glitches introduced by the minifier and to reduce the turn around time ( no need to re-compile ). To allow for more tweaking.

But yeah shaders optimization belong in the intro build process, regardless of the language.
rulez added on the 2010-06-16 12:55:49 by p01 p01
Awesome !
rulez added on the 2010-06-16 16:10:45 by Anat Anat
God is French it turns out.
rulez added on the 2010-06-16 18:40:31 by auld auld
Nice tool.
rulez added on the 2010-06-16 22:22:01 by ham ham
Nice stuff! Have anyone tried how much space it gives after compression?
One question: why does it always leave leading zeros before negatives?
I mean transformation "-.3 -> -0.3".
rulez added on the 2010-06-17 07:55:50 by stan_1901 stan_1901
yep, remove that zeroes !
also i might add that no software ever was able to replace any human being !
4ks are humans prods made by humans and stripped down to few of bytes by humans !
DONNOT rely on software if you wanna obtain full control of what is going on ! ;)
what i wanted to say is:
making 4ks is fun for coders, so dont spoil any fun by using any software, just do it by hand !
its worth the effort ! :D ( also you´ll teach yourself how to code your next 4k in a better way everytime you go through any stripdown-phase ! )
if you do 4ks you are seriously doing major-demoscenish stuff so dont cut yourself by taking the easy road !
hardy, that depends on you being as efficient as the program at stripping :)
4ks are humans prods made by humans and stripped down to few of bytes by humans !
DONNOT rely on software if you wanna obtain full control of what is going on ! ;)

Even software made by humans? ;-)
added on the 2010-06-17 10:21:23 by untel untel
hArDy, just out of curiosity, do you use Crinkler? ;-)

Seriously, this tool doesn't prevent you from working to the last byte on a 4k. But it will do some nasty job for you, like the statistical analysis for naming.

More importantly in my opinion, it allows to work on a human readable code. The time you don't waste concentrating on obfuscated code can be wisely spent on content and size optimization. :-)

And no doubt you will still have plenty of low level work to do.
added on the 2010-06-17 10:45:43 by Zavie Zavie
exactly what i said !
so why asking ?
i wouldnt want to have some rewritten code and need to find out first what got renamed to what instead of renaming it all by myself and still having the control of what is what !
ofcoz if you think its worth it, use that tool and youll be fine ! i wont !
Yep, I've read your discussion in the forum just now.
added on the 2010-06-17 11:01:22 by Zavie Zavie
Sounds like a perl job. Implementation on .NET -- why-oh-why???
added on the 2010-06-17 17:43:04 by Hoild Hoild
Perl would have been perfect if it was a regexp oriented work. However, this is far more complex; you can think of it as a compiler: it parses the source code, generates a tree (AST), makes transformations, simplifications... and outputs the result. This allows complex code optimizations that you couldn't do with a flat text representation.
added on the 2010-06-17 17:58:50 by LLB LLB

Sounds like a perl job. Implementation on .NET -- why-oh-why???

Nah mate, this is a perl-job.
added on the 2010-06-18 02:29:34 by sigflup sigflup
awesome tool!!! thank you :)
rulez added on the 2010-06-20 22:17:50 by pera pera
Awesome tool, but macros have compatibility problems:
- variables/functions can't be named like keywords on ATI:
Code:#define t vec3 t t=t(0,1,2);
- redefinions in the same scope:
Code:#define s scale; uniform float s; const vec3 s=vec3(0,1,2);
Code:for(int c=0;c<9;c++){float c = 1.;}
rulez added on the 2010-06-22 18:23:16 by rrrola rrrola
Thanks for the feedback!
Macros are just ignored for the moment. I can improve a few things, but it is very hard to fully handle macros.

I cannot repro your second example. Could you send it by email? (laurentlb at gmail)

For the "for" loop, I need to check if it's valid or not. The variable is reused because it's not used in the block - this is valid in C, but I didn't check for GLSL. Thanks again!
added on the 2010-06-22 18:55:04 by LLB LLB
Is there any alternative for HLSL? Anyone knows? :)
rulez added on the 2010-07-16 00:17:54 by merry merry
Wow how come I missed this, really sweet idea. Thanks a lot for taking that extra step and doing something most of us were talking about for a long time but didn't do because we're too lazy. :)
rulez added on the 2010-07-16 03:54:55 by decipher decipher
@merry: little after GLSL Minifier, someone started TinyHLSL. Though, seeing the code, so far the tool is way more basic.
added on the 2010-07-16 19:48:36 by Zavie Zavie
thx for sharing
rulez added on the 2010-07-30 23:44:32 by T$ T$
Thumbs for this. Keep working on it, please!
rulez added on the 2010-08-28 23:10:50 by raer raer
I was busy working on my 64k intro (B - Incubation), but it's now released. Be sure this will be improved soon. Thanks for the feedback!
added on the 2010-08-29 00:00:36 by LLB LLB
Most reported bugs are fixed. If you have any problem, feel free to contact me, it will help me prioritize my todo-list!
added on the 2010-09-25 21:47:18 by LLB LLB
you might have more feedback in your BBS topic
added on the 2010-10-13 10:42:25 by ponce ponce
gotta try this out sometime
rulez added on the 2010-10-13 12:24:47 by pommak pommak
Updated again today: fewer bugs, better compression ratio (details on Ctrl-Alt-Test website).
added on the 2010-10-15 02:10:54 by LLB LLB
Awesome work!

I'm using this tool for my 8k intro.
And I have some suggestions.

My program is using 'glBindAttribLocation' and 'glTransformFeedbackVaryings'.
These functions take input and output vertex attribute's names in vertex shader.
So 'in' and 'out' variables in vertex shader needs to be '#define' like uniform variables by GLSL minifier.

And my program using multiple shaders and they share same name uniform variables.
So I want GLSL minifier write #define names which have shader file name.

glsl_minifier.exe foo_vertex_shader.vs -o foo_vertex_shader.vs.h


in vec3 in_normal;
in vec3 in_texcoord;
out vec3 out_normal;
out vec3 out_texcoord;
uniform samplerBuffer positions;

void main()



const char *foo_vertex_shader_vs = ""
"in vec3 n,t;"
"out vec3 o,u;"
"uniform samplerBuffer p;"
"void main()"

Thank you.
rulez added on the 2010-11-06 14:08:23 by tomohiro tomohiro
rulez added on the 2010-11-06 14:09:45 by Defiance Defiance
Thanks for the feedback tomohiro, I'll add these features in next update (drop me an email if you need it sooner).
added on the 2010-11-08 16:07:51 by LLB LLB
I'd like to have a command line argument so that it won't rename in and out variables, I'm generating direct shader output, no C header, and need the variables as designed.
added on the 2011-01-27 22:40:57 by xTr1m xTr1m
tomohiro & xTr1m: I have updated the tool. "in" and "out" variables are handled the same way as "varying" and others. Use --preserve-externals flag if you don't want them to be renamed.
added on the 2011-01-30 02:13:05 by LLB LLB
That's great! thanks :)
added on the 2011-01-30 09:35:25 by xTr1m xTr1m
New download url. Many updates, including support for HLSL.
added on the 2011-02-10 00:39:59 by LLB LLB
rulez added on the 2011-02-10 01:04:59 by las las
Cool. Thanks!
added on the 2011-02-10 09:46:06 by raer raer
Second thumb up to make it working with HLSL! Welcome to ShaderMinifier!
added on the 2011-02-10 10:44:11 by xoofx xoofx
haven't really used it yet, but im sure it will be very useful
instant thumb!
rulez added on the 2011-02-10 14:46:37 by unc unc
This is a great tool! I'm using this tool when I make prod for revision.

But I found some bugs.
It show Parse error if "#if 0 ~ #endif" is used inside function definition.

And it also show Parse error with unsigned int constant.
uint c = 123u;

If I change unsigned int constant for signed, GLSL compiler generate errors or warnings.
I can avoid this error by replacing all uint with int.
But I would like to use uint type rather than int in my shader.

Thank you in advance.
added on the 2011-04-06 20:34:28 by tomohiro tomohiro
Doesn't seem to like "gl_FragData[0]", is this an error?

Just something you should be aware of..
added on the 2011-04-17 01:32:43 by ferris ferris
Thanks for awesome tool.

I typed like below.

>>shader_minifier test.fx --hlsl

but caused error.

>>Error: Parse error: Error in test.fx: Ln: 2 Col: 20
>>cbuffer cbPerFrame : register( b0 )
>>Expecting: '('

test.fx is like this.

/* test.fx */
cbuffer cbPerFrame : register( b0 )
column_major float4x4 viewProj;
column_major float4x4 view;
column_major float4x4 proj;

Shader Minifier doesn't allow this style?

rulez added on the 2011-05-01 06:26:25 by q^nonoil q^nonoil
and I long for "not rename function" option.
added on the 2011-05-02 06:55:51 by q^nonoil q^nonoil
Thanks for the feedback, I'll try to fix all this in the next release.
added on the 2011-05-02 14:44:00 by LLB LLB
For lazy people and .NET haters, there is now Shader Minifier Online.
added on the 2011-05-17 23:08:25 by LLB LLB
I've found a bug.
Sevaral functions are renamed to same name with HLSL that has a lot of functions.
Please fix this.

added on the 2011-06-18 06:08:11 by q^nonoil q^nonoil
That's called function overloading and it's a feature.
But if you've got conflicts in your entry points, that's something I will fix.
added on the 2011-06-21 00:06:22 by LLB LLB
Very very cool.

Unfortunately, the HLSL feature doesn't seem to support DX10-style "Texture2D <float4> tex"-statements or state blocks (ala "BlendState blend { BlendEnable[0] = FALSE; };")
rulez added on the 2011-06-21 00:22:13 by kusma kusma
It also seems support for attributes (like "maxvertexcount(12)]" and "[unroll]") as well as Geometry Shader input types aren't supported either.
added on the 2011-06-21 00:28:35 by kusma kusma
That should have been "[maxvertexcount(12)]", of course.
added on the 2011-06-21 09:46:55 by kusma kusma
rulez added on the 2011-07-31 23:29:06 by cce cce
LLB: any news on the fix (2011-06-21 00:06:22)? The minifier generates several functions with the same name, one of those should be the entry point of my shader... It'd be cool if you could at least provide an option to prevent any function to be given a name that appears in the "no-renaming-list". That way I can tell the minifier in the "no-renaming-list" which functions are my entry points.
added on the 2011-08-31 13:44:44 by xTr1m xTr1m
Thanks, this one is fixed. Support for DX10 will come later.
added on the 2011-09-02 23:27:00 by LLB LLB
added on the 2011-11-09 12:52:52 by LLB LLB
rulez added on the 2013-04-03 22:03:54 by cupe cupe
Source code released on github. Please report bugs and request features there. https://github.com/laurentlb/Shader_Minifier/
added on the 2013-04-04 21:56:24 by LLB LLB
very cool stuff! :) thanks for the source release!
rulez added on the 2013-04-04 22:00:54 by payne payne
thank you for the source <3
added on the 2013-04-05 10:41:12 by cupe cupe
cool too, much appreciated
rulez added on the 2013-08-08 15:16:54 by Canopy Canopy
Of course!
rulez added on the 2013-08-08 19:11:56 by ok3anos ok3anos
First time I tried it. Can produce code that doesn't compile, but after finding the problem, it ruled how it obfurscates my code :)
rulez added on the 2013-09-07 20:46:00 by Optimus Optimus
Fantastic tool. Thank you for this.
rulez added on the 2014-07-24 09:41:02 by drift drift
rulez added on the 2015-09-11 11:46:12 by Patu Patu
rulez added on the 2017-02-17 02:47:19 by cxw cxw
Thank you for this, works great!
rulez added on the 2020-02-12 13:18:55 by NoxWings NoxWings
Inexcusably, I somehow never thumbed this one up. Thanks for this tool!
rulez added on the 2021-03-18 06:40:36 by iq iq
Modern 4k scene would not be possible without this tool!
rulez added on the 2021-03-18 07:19:03 by provod provod

submit changes

if this prod is a fake, some info is false or the download link is broken,

do not post about it in the comments, it will get lost.

instead, click here !

[previous edits]

add a comment