Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork41
Minify and obfuscate GLSL or HLSL code
License
laurentlb/shader-minifier
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Shader Minifier is a tool that minifies and obfuscates shader code (GLSL andHLSL) without affecting its behaviour. It is also suitable for reducing the sizeof the shaders in other applications (e.g. webgl, games).
Its original use-case is for thedemoscene, for optimizing 4k and 64kintros. In the context of 4kB intros, Shader Minifier help developers maintainand iterate on human-readable files, while shipping optimized code. Even when ashader is minified by hand by experienced demosceners, Shader Minifier is oftenable to optimize it further. See this2010report.
Shader Minifier is available:
- As an online website:https://ctrl-alt-test.fr/minifier/
- As a command-line tool (download fromReleases)
- As a .NET library (seeExample)
To be notified of new releases, use the watch feature of GitHub.
- Parsing and printing of GLSL or HLSL code.
- Generation of a file (such as a C header) that can be embedded in an application.
- A command-line interface that can fit in a build.
- A web interface, for interactive workflows.
- Ability to minify multiple shaders at once, in a consistent way.
See the list oftransformations for more information.In brief:
- Strip spaces, remove comments, remove useless parens.
- Inline functions, variables and constant values.
- Simplify constant expressions:
5. * 2.
becomes10.
. - Group declarations:
float a=2.;float b;
becomesfloat a=2.,b;
. - Apply other tricks to reduce the file size.
- Simplify calls to vector constructors using vector swizzles.
- Rename variables, typically to one character.
- Remove unused local variables, unused functions and other dead code.
Other transformations try to make the code more compression friendly, e.g.
- Consistently rename vector fields (e.g. use
foo.xy
instead offoo.rg
) tohelp the compression. - Reuse the variable names as much as possible: a local variable may have thesame name as a global variable not used in the function; two functions may havethe same name using function overloading.
- Analyze the context and make statistics to compute the variable name that willbe the most compression-friendly.
/* File generated with Shader Minifier 1.3 * http://www.ctrl-alt-test.fr */#ifndefHEART_FRAG_EXPECTED_# defineHEART_FRAG_EXPECTED_# defineVAR_mouse "f"# defineVAR_resolution "y"# defineVAR_time "v"constchar*heart_frag="uniform float v;""uniform vec2 y;""uniform vec4 f;""void main()""{""vec2 f=(2.*gl_FragCoord.xy-y)/y.y;""float r=mod(v,2.)/2.,a=pow(r,.2)*.5+.5;""a-=a*.2*sin(r*6.2831*5.)*exp(-r*6.);""f*=vec2(.5,1.5)+a*vec2(.5,-.5);""float m=atan(f.x,f.y)/3.141593,x=length(f),e=abs(m),o=(13.*e-22.*e*e+10.*e*e*e)/(6.-5.*e),n=step(x,o)*pow(1.-x/o,.25);""gl_FragColor=vec4(n,0.,0.,1.);""}";#endif// HEART_FRAG_EXPECTED_
Multiple output formats are available.
Download Shader Minifier here:https://github.com/laurentlb/Shader_Minifier/releases
It is a command-line tool. Without argument, it will show the usage. If you arenot on Windows, you will need mono:
$ shader_minifier.exe # Windows$ mono shader_minifier.exe # Linux, Mac...
USAGE: Shader Minifier [--help] [--version] [-o <string>] [-v] [--debug] [--hlsl] [--format <text|indented|c-variables|c-array|js|nasm|rust>] [--field-names <rgba|xyzw|stpq>] [--preserve-externals] [--preserve-all-globals] [--no-inlining] [--aggressive-inlining] [--no-renaming] [--no-renaming-list <string>] [--no-sequence] [--no-remove-unused] [--no-overloading] [--move-declarations] [--preprocess] [--export-kkp-symbol-maps] [<filename>...]FILENAMES: <filename>... List of files to minifyOPTIONS: --version Display the version and exit -o <string> Set the output filename (default is shader_code.h) -v Verbose, display additional information --debug Debug, display more additional information --hlsl Use HLSL (default is GLSL) --format <text|indented|c-variables|c-array|js|nasm|rust> Choose to format the output (use 'text' if you want just the shader) --field-names <rgba|xyzw|stpq> Choose the field names for vectors: 'rgba', 'xyzw', or 'stpq' --preserve-externals Do not rename external values (e.g. uniform) --preserve-all-globals Do not rename functions and global variables --no-inlining Do not automatically inline variables and functions --aggressive-inlining Aggressively inline constants. This can reduce output size due to better constant folding. It can also increase output size due to repeated inlined constants, but this increased redundancy can be beneficial to compression, leading to a smaller final compressed size anyway. Does nothing if inlining is disabled. --no-renaming Do not rename anything --no-renaming-list <string> Comma-separated list of functions to preserve --no-sequence Do not use the comma operator trick --no-remove-unused Do not remove unused code --no-overloading When renaming functions, do not introduce new overloads --move-declarations Move declarations to group them --preprocess Evaluate some of the file preprocessor directives --export-kkp-symbol-maps Export kkpView symbol maps --help display this list of options.
In short:
List the shaders you want to minify on the command-line.
Use
-o
to choose the output file (by default, it will useshader_code.h
).If you pass-
for the output, it will be printed on stdout.Use
--format
to control the output format. By default, it will create a Cheader. There are other options to get only the shader, or have it in aJavascript, Rust, or nasm file.
4kB intros typically use a single shader file. The default flags should work well:
shader_minifier.exe -o shader_code.h fragment.glsl
We recommend that you frequently check the output of Shader Minifier to makesure there are no obvious problems. Useinlining where possible.
If you desperately need to save a few bytes, try another value of--field-names
. It can affect the size after compression.
The recommandation is to use:
shader_minifier.exe --format c-array *.frag -o shaders.h
Then, in your C or C++ code, include the file:
constchar*shaderSources[]= {#defineSHADER_MINIFIER_IMPL#includeshaders.h};
Note that uniforms will be renamed consistently across all the files. The#define
lines will tell you how they were renamed. To disable this renaming,use--preserve-externals
.
Use--format js
. It will define a variable for each shader, the variable namebeing derived from the input file. We expect you to run a Javascript minifier onthe output file.
The simplest solution is to minify each file separately:
shader_minifier.exe --format text --preserve-externals file.glsl -o file_opt.glsl
The output may be used as a drop-in replacement for your original shaders.
To better understand what Shader Minifier changed and get a more readableoutput, use the flags--format indented --no-renaming
. This will add someindentation to the output, instead of using overly long lines.
Shader Minifer works by applying to theAST modificationsthat produce a transformed but semantically equivalent AST. Theresulting assembly may be different, but the minified shader shouldhave the same behaviour as the original one. Or at least that's theintent.
Some of thetransformations are not completely safe and may break in some cornercases. If you observe differences, don't hesitate toreport a bug.
Shader Minifier will preserve the preprocessor directives (the lines startingwith#
), except that it strips the spaces.
If you define a macro, Shader Minifier will notice the name of the macro andwon't rename the occurrences of the macro. It also doesn't rename variables usedinside the macro. Clever macros are discouraged and can break the shader.
Avoid macros that contain references to other variables, or affect how thecode should be parsed. You may get a parse error in Shader Minifier, or get anoutput that won't compile.
With the flag--preprocess
, Shader Minifier will try to evaluate somepreprocessing directives:
#ifdef
is evaluated based on macros defined in the file.#else
is supported.- Nested
#ifdef
are supported. - Unknown directives will be preserved.
This is still experimental and there are some limitations:
- Macros declared with
#define
will be kept in the file, even if they are nolonger needed. #define
and#undefine
that appear inside a#if
region are not wellhandled.
If you want to temporary turn off the minifier, use the//[
and//]
comments. This can be useful as a workaround if you get a parser error.
Variables inside the region won't be renamed. Spaces will be stripped.
//[layout(local_size_x=32)in;//]
When renaming functions, Shader Minifier will try to introduce as muchoverloading as possible. This reduces the number of identifiers used by theshader and makes it more compression-friendly.
Shader Minifier works best when the input code doesn't use function overloading(two functions with the same name and different arguments). Function overloadingmight confuse the analysis and lead to an output that doesn't compile. Use theflag--no-overloading
if you don't want Shader Minifier to introduce functionoverloading, it's probably safer. Please also file issues related to functionoverloading, as we don't have enough test coverage at the moment.
Shader Minifier can export symbol files that map the minified code back to namesfrom the original source code. This lets you visualize shader size usinghttps://github.com/ConspiracyHu/rekkrunchy-with-analytics
On my machine, it takes around 1s to minify a shader. A lot of that time comesfrom the startup time of the binary. If you have many shaders, try to minifythem all at the same time by listing them all on the command-line.
- Whitespace and comments removal
- Parentheses simplifications
- Curly braces removal
- Literal numbers
- Constant arithmetic
- Conditionals evaluation
- Commutative operators
- Comma operator
- Useless else after return
- Ternary operator
- Loops
- Merge declarations
- Group declarations
- Augmented operators
- Rename vector fields
- Automatic inlining
- Aggressive inlining
- Explicit inlining
- Reassignment merging
- Variable reuse
- Vector constructors
- Function predeclarations
- Unused local variables
- Dead code removal
- Unused function removal
- Other functions
- Renaming
Please give feedback in thebugtracker.If something is blocking you, you can file a bug or update an existing bug. Werely on your feedback to prioritize the work.
Feature requests are encouraged. Add upvotes or comments to existing featurerequests that are important to you.
Contributions are welcome. Please leave a message before implementing asignificant change, so that we can agree on the solution.
Created by Laurent Le Brun (LLB / Ctrl-Alt-Test) andother contributors.
About
Minify and obfuscate GLSL or HLSL code
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Contributors10
Uh oh!
There was an error while loading.Please reload this page.