All Projects → deanthecoder → GLSLShaderShrinker

deanthecoder / GLSLShaderShrinker

Licence: MIT license
Optimizes the size of GLSL shader code.

Programming Languages

C#
18002 projects
GLSL
2045 projects
Inno Setup
370 projects

Projects that are alternatives of or similar to GLSLShaderShrinker

Bonzomatic
Live shader coding tool and Shader Showdown workhorse
Stars: ✭ 829 (+2025.64%)
Mutual labels:  demoscene, glsl, shader, shadertoy
minimal gl
PC 4K Intro Editor
Stars: ✭ 36 (-7.69%)
Mutual labels:  demoscene, glsl, shader
DuEngine
An efficient interactive C++ renderer for ShaderToy-alike demos with 2D/3D/CubeMap/Video/Camera/LightField/Volume textures. (Partially used in my I3D 2018 papers)
Stars: ✭ 62 (+58.97%)
Mutual labels:  glsl, shader, shadertoy
ShaderBoy
Simple text editor that lets you write Shadertoy shaders more comfortably, anytime, anywhere.
Stars: ✭ 133 (+241.03%)
Mutual labels:  glsl, shader, shadertoy
YALCT
Yet Another Live Coding Tool - Powered by Veldrid and elbow grease
Stars: ✭ 25 (-35.9%)
Mutual labels:  demoscene, glsl, shadertoy
card-game-GLSL
card game in the single GLSL shader
Stars: ✭ 20 (-48.72%)
Mutual labels:  glsl, shader, shadertoy
shady
A GTK+ shader editor, that aims for Shadertoy.com compatibility (and more…)
Stars: ✭ 22 (-43.59%)
Mutual labels:  demoscene, glsl, shadertoy
ios-spritekit-shader-sandbox
👾 Collection of custom effects for SpriteKit implemented using GLSL/Metal shaders.
Stars: ✭ 63 (+61.54%)
Mutual labels:  glsl, shader
raymarching
Code for my raymarching in GLSL workshop series
Stars: ✭ 17 (-56.41%)
Mutual labels:  glsl, shader
sparksl-noise
minimum proof of concept about procedural noise generation in SparkAR's shader language (SparkSL).
Stars: ✭ 16 (-58.97%)
Mutual labels:  glsl, shader
frag3d.js
WebGL shader tools
Stars: ✭ 58 (+48.72%)
Mutual labels:  glsl, shader
shaping-functions
Visualisation of shaping functions
Stars: ✭ 75 (+92.31%)
Mutual labels:  glsl, shader
glsl-cos-palette
glsl function for making cosine palettes
Stars: ✭ 26 (-33.33%)
Mutual labels:  glsl, shader
music visualizer
Shader viewer / music visualizer for Windows and Linux
Stars: ✭ 137 (+251.28%)
Mutual labels:  glsl, shadertoy
ofxShadertoy
Addon for openFrameworks that sets up and loads Shadertoy (http://www.shadertoy.com) shaders
Stars: ✭ 77 (+97.44%)
Mutual labels:  glsl, shadertoy
nuance
A tool to run your shaders on the gpu. Also a good demo application for wgpu-rs.
Stars: ✭ 26 (-33.33%)
Mutual labels:  glsl, shader
glsl-editor
💾 A simple WebGL shader editor
Stars: ✭ 20 (-48.72%)
Mutual labels:  glsl, shader
shadertoy-to-video-with-FBO
Render a ShaderToy script directly to a video file. (added FrameBuffers support)
Stars: ✭ 26 (-33.33%)
Mutual labels:  glsl, shadertoy
ada
A general porpose OpenGL app library
Stars: ✭ 105 (+169.23%)
Mutual labels:  glsl, shader
shaderplace
Real-time collaborative GLSL livecode editor
Stars: ✭ 43 (+10.26%)
Mutual labels:  glsl, shader

Twitter URL

GLSL Shader Shrinker

What Is It For?

GLSL Shader Shrinker is a Windows GUI tool that attempts to reduce the size of GLSL fragment shader code, whilst keeping it readable and understandable.

It is written in C# using WPF and Visual Studio 2019, and has several hundred NUnit-powered unit tests.

Main UI

It is designed to work primarily with code from Shadertoy, but has limited support for other styles of GLSL too (E.g. Bonzomatic)

After writing a Shadertoy shader, usually from my boilerplate starting code, there is a sequence of operations I perform:

  • Delete dead/commented-out code.
  • Remove unused functions.
  • Inline some constants (Max raymarching distance, 'hit test' accuracy, ...)
  • If trying to get under the magic '4KB', simplify some of the calculations.

It occurred to me all of these steps can be automated.

What It Can Do

Over time more and more functionality has been added to this tool which can be used to 'GOLF' code. This is an ongoing process, and other tools are much more likely to produce more compact/compressible code (Especially when preparing GLSL for use in 4KB graphics demos, etc). However, GLSL Shader Shrinker can...

  • Rename functions and variable to single-characters.
  • Inline functions.
  • Introduce #define macros to minimize the code character count.

(Some of of these items might be suggested as a 'hint' even when not GOLFing.)

Example (Shadertoy Starting Point)

A small snippet of GLSL which shows some of the optimizations available.

Before Processing

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Time varying pixel color
    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

    // Output to screen
    fragColor = vec4(col,1.0);
}

After Processing

void mainImage(out vec4 fragColor, vec2 fragCoord) {
	vec2 uv = fragCoord / iResolution.xy;
	fragColor = vec4((.5 + .5 * cos(iTime + uv.xyx + vec3(0, 2, 4))), 1);
}
  • in parameter prefix removed.
  • col variable inlined.
  • Numbers simplified - Decimal places and in vec4 construction.
  • Comments removed.

Note: All these changes are optional within the tool, and many other optimizations are available.


Getting Started

First, download and run the Windows installer from the 'Releases' section.

Note: The application requires the Microsoft .NET 5 runtimes to be installed. If they are not found the application will automatically prompt for them to be downloaded.

Step 1 - Import GLSL Code

You first need to import your GLSL into the tool.

Import

This can be achieved using:

  • Copy'n'paste from the clipboard. (CTRL-V)
  • Import from a text file.
  • Download from Shadertoy using an 'id'.

Shadertoy

Step 2 - Shrink GLSL Code

Next choose the level of processing you want to apply.

Shrink

  • Maximum processing - All options enabled.
  • Minimal processing - Minimal changes (Mostly code reformatting).
  • Custom options - Toggle exactly which processing features you require (Including GOLFing options)

Step 3 - Exporting GLSL Code

Export the 'shrunk' GLSL.

Export

This can be achieved using:

  • Copy'n'paste from the clipboard. (CTRL-C)
  • Export from a text file.

...and then use with Shadertoy, Bonzomatic, etc.


Hints

After shrinking your GLSL code, you might find some 'hints' are available. These range from 'this function isn't used' or 'this function is only used once, so you might like to inline it', all the way to some GOLFing hints.

Export


Limitations

Despite a lot of effort spent trying to ensure the tool produces great output every time, there are always going to be edge cases caused by different coding styles and patterns of content.

Heavy use of #define macros and #if...#else...#endif blocks can cause confusion when trying to parse the code. Compilers have the luxury of seeing which specific code path is enabled, but a tool like this needs to understand all possible code paths at the same time - Not always easy!

I apologize in advance if you find any issues - If I have the time I'll try my best to resolve them!

In most cases they can be worked-around using a set of 'custom' settings which disable the problematic feature.


Features

Remove Comments

Remove all C/C++ -style comments from the code.

Before

// This comment will be removed.
int myFunc(vec3 p) { return 1; }

After

int myFunc(vec3 p) { return 1; }

Keep Header Comments

Keep the top-most comments in the code, even when removing all others.

Before

// 'My Shader' written Me.
// This comment will stay.
int aGlobal = 2;

// This comment will be removed.
int myFunc(vec3 p) { return 1; }

After

// 'My Shader' written Me.
// This comment will stay.
int aGlobal = 2;

int myFunc(vec3 p) { return 1; }

Remove Unused Functions

Remove any functions that are not called within the code.

Note: Only active if a main...() function is defined.


Remove Unused Variables

Remove any global or local variables not used within the code.

Before

int myFunc() {
    int unused = 2; // <-This will be removed.
    return 1;
}

After

int myFunc(vec3 p) { return 1; }

Remove Unreachable Code

Remove any code which cannot be reached.

Before

float myFunc(vec3 p) {
    return p.x + p.y - p.z;

    // This code cannot be reached.
    a *= 2;
}

After

float myFunc(vec3 p) {
    return p.x + p.y - p.z;
}

Remove Disabled Code

Remove any commented-out code, or code surrounded with #if 0...#endif.

Before

#if 1
float myFunc(vec3 p) { return p.x + p.y - p.z; }
#else
float myFunc(vec3 p) { return 3.141; }
#endif

After

float myFunc(vec3 p) { return p.x + p.y - p.z; }

Simplify Function Declarations

  • Removes function declarations with no matching definition.
  • Removes declarations where the matching definition is early enough to be used by all its callers.
  • Removes declaration parameter names.

Before

// Declare a function.
float sum(float value1, float value2);

// Define the function.
float sum(float value1, float value2) { return value1 + value2; }

// Use the function.
void main() { myFunc(1, 2); }

After

// Define the function.
float sum(float value1, float value2) { return value1 + value2; }

// Use the function.
void main() { myFunc(1, 2); }

Simplify Function Parameters

  • Removes void parameters.
  • Removes in keywords (which is the default in GLSL).

Before

float myFunc(void) { return 3.141; }
float sum(in float a, in float b) { return a + b; }

After

float myFunc() { return 3.141; }
float sum(float a, float b) { return a + b; }

Group Variable Declarations

  • Merge multiple declarations of the same variable type (when it makes sense to do so).
  • Applies to global variables, local variables, and fields in a struct.

Before

struct MyType {
    vec3 hit;
    vec3 color;
    vec2 uv;
};

After

struct MyType {
    vec3 hit, color;
    vec2 uv;
};

Join Variable Declarations and Assignments

Join variable declarations with their corresponding assignments, removing the need for the variable name to be specified twice.

Before

float myFunc() {
    float result; // This will move.
    float b = 1.0;
    result = b * 3.141;
    return result;
}

After

float myFunc() {
    float b = 1.0;
    float result = b * 3.141;
    return result;
}

Note: Fully simplified this would become...

float myFunc() { return 3.141; }

Detect New Constants

Find any variables assigned a value that can be made const.

Note: These can become candidates for inlining into the code, when used with other options.

Before

float myFunc() {
    float PI = 3.141;
    return 2.0 * PI;
}

After

float myFunc() {
    const float PI = 3.141;
    return 2.0 * PI;
}

Inline Constant Variables

Remove a const variable by inlining it in all the places it is used.

Note: This will only be performed if it will result in shorter code.

Before

const float MAX_DIST = 128.0;

bool isVisible(float dist) { return dist <= MAX_DIST; }

After

bool isVisible(float dist) { return dist <= 128.0; }

Inline Constant #defines

Remove a #define by inlining its (constant) value in all the places it is used.

Note: This will only be performed if it will result in shorter code.

Before

#define MAX_DIST 128.0

bool isVisible(float dist) { return dist <= MAX_DIST; }

After

bool isVisible(float dist) { return dist <= 128.0; }

Simplify Number Format

Performs a variety of formatting changes to represent numbers using less characters.

Before

float a = 1.200;
float b = 001.00;
float c = 23.0f;
float d = float(1.2);
float e = float(12);
float f = 123000.0;
int   g = int(1.2);
int   h = int(23);

After

float a = 1.2;
float b = 1.;
float c = 23.;
float d = 1.2;
float e = 12.;
float f = 123e3;
int   g = 1;
int   h = 23;

Simplify Vector Construction

Simplify the construction of vector and matrix types.

Before

vec3 a = vec3(1.0, 2.0, 3.0);
vec2 b = vec2(4.0, 4.0);
vec3 c = a.xyz;
vec3 d = vec3(a);

After

vec3 a = vec3(1, 2, 3);
vec2 b = vec2(4);
vec3 c = a;
vec3 d = a;

Simplify Vector References

Simplify the construction of vector and matrix types.

Before

vec3 a = vec3(1, 2, 3);
vec2 b = vec2(a.x, a.y);
vec3 c = vec2(a.x, a.y, a.z, a.x);
vec3 d = vec3(other_vec3);

After

vec3 a = vec3(1, 2, 3);
vec2 b = a.xy;
vec3 c = a.xyzx;
vec3 d = other_vec3;

Simplify Code Branching

Simplify branches by removing the else keyword where possible.

Before

if (a == b)
    return a;
else // < Not required.
    return a + b;

After

if (a == b)
    return a;
return a + b;

Combine Consecutive Assignments

Consecutive assignments of the same variable can often be inlined.

Before

float doMaths() {
    float a = myFunc();
    a = pow(a, 2.0);
    a = a + 23.3;
    return a;
}

After

float doMaths() {
    float a = pow(myFunc(), 2.0) + 23.3;
    return a;
}

Combine Assignment With Single Use

A variable assignment used on the next line can often be inlined, if that next line is an assignment or if condition.

Before

float doMaths() {
    float a, b, c;
    a = myFunc();
    b = pow(a, 2.0);
    c = b * 2.2;
    return c;
}

After

float doMaths() {
    float c;
    c = pow(myFunc(), 2.0) * 2.2;
    return c;
}

Also

Before

bool f() {
    float a = getValue();
    if (a > 2.)
        return true;
    return false;
}

After

bool f() {
    if (getValue() > 2.)
        return true;
    return false;
}

Introduce +=, -=, /=, *=

Make use of a combined math operator/assignment when possible.

Before

float doMaths() {
    float a = 2.1;
    a += 1.0;
    a = a * 3.141;
    return a;
}

After

float doMaths() {
    float a = 2.1;
    a++;
    a *= 3.141;
    return a;
}

Simplify Mathematical Expressions

Reduce unnecessary round brackets when performing arithmetic.

Before

float doMaths() {
    return (2.0 * (3.141)) * (1.1 + 2.2);
}

After

float doMaths() {
    return 2.0 * 3.141 * (1.1 + 2.2);
}

Perform Simple Arithmetic

Pre-evaluate simple arithmetic. E.g.

  • Change a = b + -c to a = b - c
  • Change f * 1.0 or f / 1.0 to f
  • Change f + 0.0 or f - 0.0 to f
  • Remove f * 0.0 (when safe).
  • Change pow(3.0, 2.0) to 9.0
  • Change float a = 1.2 / 2.3 * 4.5; to float a = 2.3478;
  • Change vec2 f = vec2(1.1, 2.2) + 3.3 * 4.4; to vec2 f = vec2(15.62, 16.72);
  • Change float f = dot(v, vec3(0, 1, 0)); to float f = v.y;

Replace Functions Calls With Result

If the result of a function call can be calculated, replace the call with the result.

Before

float doMaths(float a, float b, float c) {
    return a * b + a + sin(c);
}

float f() {
    float result = doMaths(1.0, 2.0, 3.14159);
}

After

float f() {
    float result = 3.0;
}

Move constant parameters to within called functions

If all calls to a function use the same constant parameter, attempt to remove the parameter from the call site and inline it into the called function.

Before

float doMaths(float a, float b) {
    return a * b;
}

float f() {
    // All calls pass '2.0' for parameter 'a'.
    float result = doMaths(2.0, 3.0) + doMaths(2.0, 5.0);
}

After

float doMaths(float b) {
    return 2.0 * b;
}

float f() {
    float result = doMaths(3.0) + doMaths(5.0);
}

GOLF user defined code names

Reduce the size of the code by renaming user-defined names. Attempts are made to keep some of the letters of the object to rename.

Before

float sum(float number, float anotherNumber) {
    return number + anotherNumber;
}

After

float s(float n, float a) {
    return n + a;
}

Define common terms

Reduce the size of the code by adding #defines for regularly used terms.

Before

float f(float number, float anotherNumber) {
    return smoothstep(0.0, 1.0, number) + smoothstep(0.5, 1.5, anotherNumber);
}

After

#define S smoothstep
float f(float number, float anotherNumber) {
    return S(0.0, 1.0, number) + S(0.5, 1.5, anotherNumber);
}

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].