{"id":18444618,"url":"https://github.com/deanthecoder/glslshadershrinker","last_synced_at":"2025-07-02T03:02:10.721Z","repository":{"id":50468838,"uuid":"365330774","full_name":"deanthecoder/GLSLShaderShrinker","owner":"deanthecoder","description":"Cross-platform tool to Reformat/Remove Dead Code/Optimise/Analyse GLSL shader code.","archived":false,"fork":false,"pushed_at":"2023-11-20T12:04:58.000Z","size":1816,"stargazers_count":101,"open_issues_count":1,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-04T11:37:22.994Z","etag":null,"topics":["avalonia","avalonia-ui","avaloniaui","csharp","demoscene","glsl","shader","shadertoy"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deanthecoder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-05-07T19:12:54.000Z","updated_at":"2025-03-03T14:06:09.000Z","dependencies_parsed_at":"2023-11-20T13:41:54.656Z","dependency_job_id":null,"html_url":"https://github.com/deanthecoder/GLSLShaderShrinker","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/deanthecoder/GLSLShaderShrinker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deanthecoder%2FGLSLShaderShrinker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deanthecoder%2FGLSLShaderShrinker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deanthecoder%2FGLSLShaderShrinker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deanthecoder%2FGLSLShaderShrinker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deanthecoder","download_url":"https://codeload.github.com/deanthecoder/GLSLShaderShrinker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deanthecoder%2FGLSLShaderShrinker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263066557,"owners_count":23408387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avalonia","avalonia-ui","avaloniaui","csharp","demoscene","glsl","shader","shadertoy"],"created_at":"2024-11-06T07:02:55.278Z","updated_at":"2025-07-02T03:02:10.679Z","avatar_url":"https://github.com/deanthecoder.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/deanthecoder.svg?style=social\u0026label=Follow%20%40deanthecoder)](https://twitter.com/deanthecoder)\n# GLSL Shader Shrinker\n* Download from the [Releases](https://github.com/deanthecoder/GLSLShaderShrinker/releases) section.\n* May require the [.NET Desktop runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-desktop-7.0.0-windows-x64-installer), if not already installed.\n* May require the [ASP.NET runtime](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-aspnetcore-7.0.0-windows-hosting-bundle-installer), if not already installed.\n* Mac users may need to run the following command to unblock the application:\u003cbr\u003e`xattr -d com.apple.quarantine /Applications/GLSL\\ Shader\\ Shrinker.app`\n\n## What Is It For?\nGLSL Shader Shrinker is a cross-platform GUI tool that attempts to reduce the size of GLSL fragment shader code, whilst keeping it _readable_ and understandable.\n\nIt is written in C# using [Avalonia](https://avaloniaui.net/) and [JetBrains Rider](https://www.jetbrains.com/rider/), and has several hundred NUnit-powered unit tests.\n\n![Main UI](img/ED209.png?raw=true \"Main UI\")\n\nIt is designed to work primarily with code from [Shadertoy](https://www.shadertoy.com/), but has limited support for other styles of GLSL too (E.g. [Bonzomatic](https://github.com/Gargaj/Bonzomatic), [Posh Brolly](https://www.poshbrolly.net/))\n\nAfter writing a shader, usually from my boilerplate starting code, there is a sequence of operations I perform:\n* Delete dead/commented-out code.\n* Remove unused functions.\n* Inline some constants (Max raymarching distance, 'hit test' accuracy, ...)\n* If trying to get under the magic '4KB', simplify some of the calculations.\n\nIt occurred to me all of these steps can be automated.\n\n## What It *Can* Do\nOver time more and more functionality has been added to this tool which can be used to '[GOLF](https://en.wikipedia.org/wiki/Code_golf)' code.\nThis 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... \n\n* Rename functions and variable to single-characters.\n* Inline functions.\n* Introduce ```#define``` macros to minimize the code character count.\n\n(Some of of these items might be suggested as a 'hint' even when not GOLFing.)\n\n## Example (Shadertoy Starting Point)\nA small snippet of GLSL which shows **some** of the optimizations available.\n\n### Before Processing\n```glsl\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord )\n{\n    // Normalized pixel coordinates (from 0 to 1)\n    vec2 uv = fragCoord/iResolution.xy;\n\n    // Time varying pixel color\n    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n\n    // Output to screen\n    fragColor = vec4(col,1.0);\n}\n```\n### After Processing\n```glsl\nvoid mainImage(out vec4 fragColor, vec2 fragCoord) {\n\tvec2 uv = fragCoord / iResolution.xy;\n\tfragColor = vec4((.5 + .5 * cos(iTime + uv.xyx + vec3(0, 2, 4))), 1);\n}\n```\n* ```in``` parameter prefix removed.\n* ```col``` variable inlined.\n* Numbers simplified - Decimal places and in ```vec4``` construction.\n* Comments removed.\n\n**Note:** All these changes are optional within the tool, and many other optimizations are available.\n\n---\n## Getting Started\n\nFirst, download and run the installer from the 'Releases' section.\n\n**Note:** The application requires the Microsoft .NET 7 runtimes to be installed. If they are not found the application will automatically prompt for them to be downloaded.\n\n### Step 1 - Import GLSL Code\nYou first need to import your GLSL into the tool.\n\n![Import](img/Import.png?raw=true \"Import\")\n\nThis can be achieved using:\n* Copy'n'paste from the clipboard. (CTRL-V)\n* Import from a text file.\n* Download from [Shadertoy](https://www.shadertoy.com/) using an 'id'.\n\n![Shadertoy](img/Shadertoy.png?raw=true \"Shadertoy\")\n\n### Step 2 - Process GLSL Code\nNext choose the level of processing you want to apply.\n\n![Shrink](img/Shrink.png?raw=true \"Shrink\")\n\n* Maximum - All options enabled.\n* Reformat - Minimal changes (Mostly code reformatting).\n* Remove Dead Code - Remove unreferences functions and unreachable code.\n* Custom - Toggle exactly which processing features you require (Including GOLFing options)\n\n### Step 3 - Exporting GLSL Code\nExport the 'processed' GLSL.\n\n![Export](img/Export.png?raw=true \"Export\")\n\nThis can be achieved using:\n* Copy'n'paste from the clipboard. (CTRL-C)\n* Export to a text file.\n\n...and then use with Shadertoy, Bonzomatic, etc.\n\n---\n## Hints\nAfter processing your GLSL code, you might find some 'hints' are available.\nThese 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.\n\n![Export](img/Hints.png?raw=true \"Export\")\n\n---\n## Limitations\nDespite a lot of effort spent trying to ensure the tool produces valid output every time, there are always going to be edge cases caused by different coding styles and patterns of content.\n\nHeavy 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!\n\nIn most cases issues can be worked-around using a set of 'custom' settings which disable the problematic feature.\n\n---\n# Features\n* [Remove Comments](#remove-comments)\n* [Keep Header Comments](#keep-header-comments)\n* [Remove Unused Functions](#remove-unused-functions)\n* [Remove Unused Variables](#remove-unused-variables)\n* [Remove Unreachable Code](#remove-unreachable-code)\n* [Remove Disabled Code](#remove-disabled-code)\n* [Simplify Function Declarations](#simplify-function-declarations)\n* [Simplify Function Parameters](#simplify-function-parameters)\n* [Group Variable Declarations](#group-variable-declarations)\n* [Join Variable Declarations and Assignments](#join-variable-declarations-and-assignments)\n* [Detect New Constants](#detect-new-constants)\n* [Inline Constant Variables](#inline-constant-variables)\n* [Inline Constant #defines](#inline-constant-#defines)\n* [Simplify Number Format](#simplify-number-format)\n* [Simplify Vector Construction](#simplify-vector-construction)\n* [Simplify Vector References](#simplify-vector-references)\n* [Simplify Code Branching](#simplify-code-branching)\n* [Combine Consecutive Assignments](#combine-consecutive-assignments)\n* [Combine Assignment With Single Use](#combine-assignment-with-single-use)\n* [Introduce +=, -=, /=, *=](#introduce-+=,--=,-/=,-*=)\n* [Simplify Mathematical Expressions](#simplify-mathematical-expressions)\n* [Perform Simple Arithmetic](#perform-simple-arithmetic)\n* [Replace Functions Calls With Result](#replace-functions-calls-with-result)\n* [Move constant parameters to within called functions](#move-constant-parameters-to-within-called-functions)\n* [GOLF user defined code names](#golf-user-defined-code-names)\n* [Define common terms](#define-common-terms)\n## Remove Comments\nRemove all C/C++ -style comments from the code.\n#### Before\n```c\n// This comment will be removed.\nint myFunc(vec3 p) { return 1; }\n```\n#### After\n```c\nint myFunc(vec3 p) { return 1; }\n```\n\n---\n## Keep Header Comments\nKeep the top-most comments in the code, even when removing all others.\n#### Before\n```c\n// 'My Shader' written Me.\n// This comment will stay.\nint aGlobal = 2;\n\n// This comment will be removed.\nint myFunc(vec3 p) { return 1; }\n```\n#### After\n```c\n// 'My Shader' written Me.\n// This comment will stay.\nint aGlobal = 2;\n\nint myFunc(vec3 p) { return 1; }\n```\n\n---\n## Remove Unused Functions\nRemove any functions that are not called within the code.\n\n**Note:** Only active if a `main...()` function is defined.\n\n---\n## Remove Unused Variables\nRemove any global or local variables not used within the code.\n#### Before\n```c\nint myFunc() {\n    int unused = 2; // \u003c-This will be removed.\n    return 1;\n}\n```\n#### After\n```c\nint myFunc(vec3 p) { return 1; }\n```\n\n---\n## Remove Unreachable Code\nRemove any code which cannot be reached.\n#### Before\n```c\nfloat myFunc(vec3 p) {\n    return p.x + p.y - p.z;\n\n    // This code cannot be reached.\n    a *= 2;\n}\n```\n#### After\n```c\nfloat myFunc(vec3 p) {\n    return p.x + p.y - p.z;\n}\n```\n\n---\n## Remove Disabled Code\nRemove any commented-out code, or code surrounded with `#if 0...#endif`.\n#### Before\n```c\n#if 1\n    float myFunc(vec3 p) { return p.x + p.y - p.z; }\n#else\n    float myFunc(vec3 p) { return 3.141; }\n#endif\n```\n#### After\n```c\nfloat myFunc(vec3 p) { return p.x + p.y - p.z; }\n```\n\n---\n## Simplify Function Declarations\n* Removes function declarations with no matching definition.\n* Removes declarations where the matching definition is early enough to be used by all its callers.\n* Removes declaration parameter names.\n\n#### Before\n```c\n// Declare a function.\nfloat sum(float value1, float value2);\n\n// Define the function.\nfloat sum(float value1, float value2) { return value1 + value2; }\n\n// Use the function.\nvoid main() { myFunc(1, 2); }\n```\n#### After\n```c\n// Define the function.\nfloat sum(float value1, float value2) { return value1 + value2; }\n\n// Use the function.\nvoid main() { myFunc(1, 2); }\n```\n\n---\n## Simplify Function Parameters\n* Removes `void` parameters.\n* Removes `in` keywords (which is the default in GLSL).\n\n#### Before\n```c\nfloat myFunc(void) { return 3.141; }\nfloat sum(in float a, in float b) { return a + b; }\n```\n#### After\n```c\nfloat myFunc() { return 3.141; }\nfloat sum(float a, float b) { return a + b; }\n```\n\n---\n## Group Variable Declarations\n* Merge multiple declarations of the same variable type (when it makes sense to do so).\n* Applies to global variables, local variables, and fields in a `struct`.\n\n#### Before\n```c\nstruct MyType {\n    vec3 hit;\n    vec3 color;\n    vec2 uv;\n};\n```\n#### After\n```c\nstruct MyType {\n    vec3 hit, color;\n    vec2 uv;\n};\n```\n\n---\n## Join Variable Declarations and Assignments\nJoin variable declarations with their corresponding assignments, removing the need for the variable name to be specified twice.\n\n#### Before\n```c\nfloat myFunc() {\n    float result; // This will move.\n    float b = 1.0;\n    result = b * 3.141;\n    return result;\n}\n```\n#### After\n```c\nfloat myFunc() {\n    float b = 1.0;\n    float result = b * 3.141;\n    return result;\n}\n```\n**Note:** Fully simplified this would become...\n```c\nfloat myFunc() { return 3.141; }\n```\n\n---\n## Detect New Constants\nFind any variables assigned a value that can be made `const`.\n\n**Note:** These can become candidates for inlining into the code, when used with other options.\n\n#### Before\n```c\nfloat myFunc() {\n    float PI = 3.141;\n    return 2.0 * PI;\n}\n```\n#### After\n```c\nfloat myFunc() {\n    const float PI = 3.141;\n    return 2.0 * PI;\n}\n```\n\n---\n## Inline Constant Variables\nRemove a `const` variable by inlining it in all the places it is used.\n\n**Note:** This will only be performed if it will result in shorter code.\n\n#### Before\n```c\nconst float MAX_DIST = 128.0;\n\nbool isVisible(float dist) { return dist \u003c= MAX_DIST; }\n```\n#### After\n```c\nbool isVisible(float dist) { return dist \u003c= 128.0; }\n```\n\n---\n## Inline Constant #defines\nRemove a `#define` by inlining its (constant) value in all the places it is used.\n\n**Note:** This will only be performed if it will result in shorter code.\n\n#### Before\n```c\n#define MAX_DIST 128.0\n\nbool isVisible(float dist) { return dist \u003c= MAX_DIST; }\n```\n#### After\n```c\nbool isVisible(float dist) { return dist \u003c= 128.0; }\n```\n\n---\n## Simplify Number Format\nPerforms a variety of formatting changes to represent numbers using less characters.\n#### Before\n```c\nfloat a = 1.200;\nfloat b = 001.00;\nfloat c = 23.0f;\nfloat d = float(1.2);\nfloat e = float(12);\nfloat f = 123000.0;\nint   g = int(1.2);\nint   h = int(23);\n```\n#### After\n```c\nfloat a = 1.2;\nfloat b = 1.;\nfloat c = 23.;\nfloat d = 1.2;\nfloat e = 12.;\nfloat f = 123e3;\nint   g = 1;\nint   h = 23;\n```\n\n---\n## Simplify Vector Construction\nSimplify the construction of vector and matrix types.\n#### Before\n```c\nvec3 a = vec3(1.0, 2.0, 3.0);\nvec2 b = vec2(4.0, 4.0);\nvec3 c = a.xyz;\nvec3 d = vec3(a);\n```\n#### After\n```c\nvec3 a = vec3(1, 2, 3);\nvec2 b = vec2(4);\nvec3 c = a;\nvec3 d = a;\n```\n\n---\n## Simplify Vector References\nSimplify the construction of vector and matrix types.\n#### Before\n```c\nvec3 a = vec3(1, 2, 3);\nvec2 b = vec2(a.x, a.y);\nvec3 c = vec2(a.x, a.y, a.z, a.x);\nvec3 d = vec3(other_vec3);\n```\n#### After\n```c\nvec3 a = vec3(1, 2, 3);\nvec2 b = a.xy;\nvec3 c = a.xyzx;\nvec3 d = other_vec3;\n```\n\n---\n## Simplify Code Branching\nSimplify branches by removing the ```else``` keyword where possible.\n#### Before\n```c\nif (a == b)\n    return a;\nelse // \u003c Not required.\n    return a + b;\n```\n#### After\n```c\nif (a == b)\n    return a;\nreturn a + b;\n```\n\n---\n## Combine Consecutive Assignments\nConsecutive assignments of the same variable can often be inlined.\n#### Before\n```c\nfloat doMaths() {\n    float a = myFunc();\n    a = pow(a, 2.0);\n    a = a + 23.3;\n    return a;\n}\n```\n#### After\n```c\nfloat doMaths() {\n    float a = pow(myFunc(), 2.0) + 23.3;\n    return a;\n}\n```\n\n---\n## Combine Assignment With Single Use\nA variable assignment used on the next line can often be inlined, if that next line is an assignment or ```if``` condition.\n#### Before\n```c\nfloat doMaths() {\n    float a, b, c;\n    a = myFunc();\n    b = pow(a, 2.0);\n    c = b * 2.2;\n    return c;\n}\n```\n#### After\n```c\nfloat doMaths() {\n    float c;\n    c = pow(myFunc(), 2.0) * 2.2;\n    return c;\n}\n```\nAlso\n#### Before\n```c\nbool f() {\n    float a = getValue();\n    if (a \u003e 2.)\n        return true;\n    return false;\n}\n```\n#### After\n```c\nbool f() {\n    if (getValue() \u003e 2.)\n        return true;\n    return false;\n}\n```\n\n---\n## Introduce +=, -=, /=, *=\nMake use of a combined math operator/assignment when possible.\n#### Before\n```c\nfloat doMaths() {\n    float a = 2.1;\n    a += 1.0;\n    a = a * 3.141;\n    return a;\n}\n```\n#### After\n```c\nfloat doMaths() {\n    float a = 2.1;\n    a++;\n    a *= 3.141;\n    return a;\n}\n```\n\n---\n## Simplify Mathematical Expressions\nReduce unnecessary round brackets when performing arithmetic.\n#### Before\n```c\nfloat doMaths() {\n    return (2.0 * (3.141)) * (1.1 + 2.2);\n}\n```\n#### After\n```c\nfloat doMaths() {\n    return 2.0 * 3.141 * (1.1 + 2.2);\n}\n```\n\n---\n## Perform Simple Arithmetic\nPre-evaluate simple arithmetic.\nE.g.\n* Change ```a = b + -c``` to ```a = b - c```\n* Change ```f * 1.0``` or ```f / 1.0``` to ```f```\n* Change ```f + 0.0``` or ```f - 0.0``` to ```f```\n* Remove ```f * 0.0``` (when safe).\n* Change ```pow(3.0, 2.0)``` to ```9.0```\n* Change ```float a = 1.2 / 2.3 * 4.5;``` to ```float a = 2.3478;```\n* Change ```vec2 f = vec2(1.1, 2.2) + 3.3 * 4.4;``` to ```vec2 f = vec2(15.62, 16.72);```\n* Change ```float f = dot(v, vec3(0, 1, 0));``` to ```float f = v.y;```\n\n---\n## Replace Functions Calls With Result\nIf the result of a function call can be calculated, replace the call with the result.\n#### Before\n```c\nfloat doMaths(float a, float b, float c) {\n    return a * b + a + sin(c);\n}\n\nfloat f() {\n    float result = doMaths(1.0, 2.0, 3.14159);\n    ...\n}\n```\n#### After\n```c\nfloat f() {\n    float result = 3.0;\n    ...\n}\n```\n\n---\n## Move constant parameters to within called functions\nIf 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.\n#### Before\n```c\nfloat doMaths(float a, float b) {\n    return a * b;\n}\n\nfloat f() {\n    // All calls pass '2.0' for parameter 'a'.\n    float result = doMaths(2.0, 3.0) + doMaths(2.0, 5.0);\n}\n```\n#### After\n```c\nfloat doMaths(float b) {\n    return 2.0 * b;\n}\n\nfloat f() {\n    float result = doMaths(3.0) + doMaths(5.0);\n}\n```\n\n---\n## GOLF user defined code names\nReduce the size of the code by renaming user-defined names.\nAttempts are made to keep some of the letters of the object to rename.\n#### Before\n```c\nfloat sum(float number, float anotherNumber) {\n    return number + anotherNumber;\n}\n```\n#### After\n```c\nfloat s(float n, float a) {\n    return n + a;\n}\n```\n\n---\n## Define common terms\nReduce the size of the code by adding #defines for regularly used terms.\n#### Before\n```c\nfloat f(float number, float anotherNumber) {\n    return smoothstep(0.0, 1.0, number) + smoothstep(0.5, 1.5, anotherNumber);\n}\n```\n#### After\n```c\n#define S smoothstep\nfloat f(float number, float anotherNumber) {\n    return S(0.0, 1.0, number) + S(0.5, 1.5, anotherNumber);\n}\n```\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeanthecoder%2Fglslshadershrinker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeanthecoder%2Fglslshadershrinker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeanthecoder%2Fglslshadershrinker/lists"}