├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── Checker
├── Checker.fsproj
├── compression_test.fs
├── glslang.exe
└── main.fs
├── Directory.Build.props
├── Example
├── Example.csproj
└── Program.cs
├── LICENSE
├── Minifier
├── Minifier.fsproj
├── analyzer.fs
├── api.fs
├── ast.fs
├── builtin.fs
├── formatter.fs
├── inlining.fs
├── options.fs
├── parse.fs
├── preprocessor.fs
├── printer.fs
├── renamer.fs
└── rewriter.fs
├── README.md
├── SMBolero.Client
├── Main.fs
├── Properties
│ └── launchSettings.json
├── SMBolero.Client.fsproj
├── Startup.fs
└── wwwroot
│ ├── css
│ └── index.css
│ ├── index.html
│ ├── main.html
│ └── minifier.js
├── SMBolero.Server
├── Index.fs
├── Properties
│ └── launchSettings.json
├── SMBolero.Server.fsproj
└── Startup.fs
├── Shader Minifier.sln
├── ShaderMinifier
├── ShaderMinifier.fsproj
└── main.fs
├── TRANSFORMATIONS.md
├── appveyor.yml
├── check.bash
├── compile.bash
├── lib
├── Argu.dll
├── Compressor.dll
├── FParsec.dll
├── FParsecCS.dll
├── FSharp.Core.dll
├── OpenTK.dll
└── System.ValueTuple.dll
├── run-from-source.bash
└── tests
├── all-glsl.expected
├── commands.txt
├── compile.txt
├── compression_results.log
├── real
├── README.md
├── audio-flight-v2.frag
├── audio-flight-v2.frag.expected
├── buoy.frag
├── buoy.frag.expected
├── chocolux.expected
├── chocolux.frag
├── clod.expected
├── clod.frag
├── controllable-machinery.frag
├── controllable-machinery.frag.expected
├── deform.frag
├── disco.expected
├── disco.frag
├── ed-209.frag
├── ed-209.frag.expected
├── elevated.hlsl
├── elevated.hlsl.expected
├── endeavour.frag
├── endeavour.frag.expected
├── from-the-seas-to-the-stars.frag
├── from-the-seas-to-the-stars.frag.expected
├── frozen-wasteland.frag
├── frozen-wasteland.frag.expected
├── heart.expected
├── heart.frag
├── heart.frag.expected
├── heart2.expected
├── heart2.frag
├── julia.frag
├── kaleidoscope.frag
├── kinder_painter.expected
├── kinder_painter.frag
├── leizex.expected
├── leizex.frag
├── lunaquatic.frag
├── lunaquatic.frag.expected
├── mandel.frag
├── mandelbulb.expected
├── mandelbulb.frag
├── metatunnel.frag
├── monjori.frag
├── monjori.frag.expected
├── motion_blur.frag
├── mouton
│ ├── fxaa.frag
│ ├── mouton.expected
│ ├── mouton.frag
│ └── mouton.vert
├── ohanami.frag
├── ohanami.frag.expected
├── orchard.frag
├── orchard.frag.expected
├── oscars_chair.frag
├── oscars_chair.frag.expected
├── postprocessing.frag
├── quaternion.frag
├── radial_blur.frag
├── robin.frag
├── robin.frag.expected
├── slisesix.frag
├── slisesix.frag.expected
├── star.frag
├── sult.expected
├── sult.frag
├── terrarium.frag
├── terrarium.frag.expected
├── the_real_party_is_in_your_pocket.frag
├── the_real_party_is_in_your_pocket.frag.expected
├── to_the_road_of_ribbon.expected
├── to_the_road_of_ribbon.frag
├── valley_ball.glsl
├── valley_ball.glsl.expected
├── yx_long_way_from_home.frag
├── yx_long_way_from_home.frag.expected
└── z_invert.frag.expected
├── shadertoy.h.glsl
└── unit
├── 1.simple.frag
├── 2.simple.frag
├── 2.simple.opt.frag
├── arg-inlining.expected
├── arg-inlining.frag
├── array.frag
├── array.frag.expected
├── augmented.frag
├── augmented.frag.expected
├── blocks.expected
├── blocks.frag
├── bug.frag.expected
├── bug321.expected
├── bug321.frag
├── commas.frag
├── conditionals.frag
├── conditionals.frag.expected
├── deadcode.frag
├── deadcode.frag.expected
├── decimals.frag
├── decimals.frag.expected
├── empty_block.frag
├── externals.expected
├── externals.frag
├── externals.preserved.expected
├── file name with-weird caractères.frag
├── file name with-weird caractères.frag.c-variables.expected
├── file name with-weird caractères.frag.js.expected
├── file name with-weird caractères.frag.json.expected
├── file name with-weird caractères.frag.nasm.expected
├── file name with-weird caractères.frag.rust.expected
├── float.frag
├── float.frag.expected
├── forbidden.expected
├── forbidden.frag
├── forward_declaration.frag
├── forward_declaration.frag.expected
├── function_comma.expected
├── function_comma.frag
├── function_overload.expected
├── function_overload.frag
├── function_overload.no.expected
├── function_overload2.expected
├── functions.hlsl
├── geometry.hlsl
├── geometry.hlsl.expected
├── hexa.frag
├── inline-aggro.aggro.expected
├── inline-aggro.expected
├── inline-aggro.frag
├── inline-fn-multiple.expected
├── inline-fn-multiple.frag
├── inline-fn.aggro.expected
├── inline-fn.expected
├── inline-fn.frag
├── inline.aggro.expected
├── inline.expected
├── inline.frag
├── inline.no.expected
├── inout.expected
├── inout.frag
├── inout2.frag
├── interface-block-renaming.expected
├── interface-block-renaming1.frag
├── interface-block-renaming2.frag
├── interface_block.frag
├── interface_block.frag.expected
├── keyword_prefix.frag
├── keyword_prefix.frag.expected
├── layout.comp
├── layout.frag
├── layout.frag.expected
├── layout.geom
├── loop.frag
├── loop.frag.expected
├── macros.expected
├── macros.frag
├── many_variables.expected
├── many_variables.frag
├── minus-zero.expected
├── minus-zero.frag
├── nested_if.frag
├── nested_if.frag.expected
├── numbers.frag
├── numbers.frag.expected
├── operators.expected
├── operators.frag
├── overload.expected
├── overload.frag
├── pi.frag
├── pi.frag.expected
├── precedence.frag
├── precedence.frag.expected
├── precision.frag
├── precision.frag.expected
├── preprocess.frag
├── preprocess.frag.expected
├── preprocess_if.frag
├── preprocess_if.frag.expected
├── qualifiers.expected
├── qualifiers.frag
├── rename_conflict.frag
├── reuse-var.frag
├── reuse-var.frag.expected
├── shadowing.frag
├── shadowing.frag.expected
├── simple.frag
├── simplify.expected
├── simplify.frag
├── smoothstep.frag
├── struct.frag
├── struct.frag.expected
├── struct2.frag
├── struct2.frag.expected
├── struct_inheritance.hlsl
├── struct_inheritance.hlsl.expected
├── suffix.frag
├── switch.expected
├── switch.frag
├── symbols.frag
├── symbols.frag.expected
├── symbols.frag.sym
├── templates.hlsl
├── templates.hlsl.expected
├── ternary.frag
├── ternary.frag.expected
├── unused_assignments.frag
├── unused_assignments.frag.expected
├── unused_removal.frag
├── unused_removal.frag.expected
├── vectors.frag
├── vectors.frag.expected
├── verbatim.frag
└── verbatim.frag.expected
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [laurentlb]
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Checker
3 | #################
4 |
5 | Checker/.out.spv
6 | tests/out/
7 |
8 | #################
9 | ## Eclipse
10 | #################
11 |
12 | *.pydevproject
13 | .project
14 | .metadata
15 | bin/
16 | tmp/
17 | *.tmp
18 | *.bak
19 | *.swp
20 | *~.nib
21 | local.properties
22 | .classpath
23 | .settings/
24 | .loadpath
25 |
26 | # External tool builders
27 | .externalToolBuilders/
28 |
29 | # Locally stored "Eclipse launch configurations"
30 | *.launch
31 |
32 | # CDT-specific
33 | .cproject
34 |
35 | # PDT-specific
36 | .buildpath
37 |
38 |
39 | #################
40 | ## Visual Studio
41 | #################
42 |
43 | .vs/
44 |
45 | ## Ignore Visual Studio temporary files, build results, and
46 | ## files generated by popular Visual Studio add-ons.
47 |
48 | # User-specific files
49 | *.suo
50 | *.user
51 | *.sln.docstates
52 |
53 | # Build results
54 | [Dd]ebug/
55 | [Rr]elease/
56 | *_i.c
57 | *_p.c
58 | *.ilk
59 | *.meta
60 | *.obj
61 | *.pch
62 | *.pdb
63 | *.pgc
64 | *.pgd
65 | *.rsp
66 | *.sbr
67 | *.tlb
68 | *.tli
69 | *.tlh
70 | *.tmp
71 | *.vspscc
72 | .builds
73 | *.dotCover
74 |
75 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
76 | #packages/
77 |
78 | # Visual C++ cache files
79 | ipch/
80 | *.aps
81 | *.ncb
82 | *.opensdf
83 | *.sdf
84 |
85 | # Visual Studio profiler
86 | *.psess
87 | *.vsp
88 |
89 | # ReSharper is a .NET coding add-in
90 | _ReSharper*
91 |
92 | # Installshield output folder
93 | [Ee]xpress
94 |
95 | # DocProject is a documentation generator add-in
96 | DocProject/buildhelp/
97 | DocProject/Help/*.HxT
98 | DocProject/Help/*.HxC
99 | DocProject/Help/*.hhc
100 | DocProject/Help/*.hhk
101 | DocProject/Help/*.hhp
102 | DocProject/Help/Html2
103 | DocProject/Help/html
104 |
105 | # Click-Once directory
106 | publish
107 |
108 | # Others
109 | [Bb]in
110 | [Oo]bj
111 | sql
112 | TestResults
113 | *.Cache
114 | ClientBin
115 | stylecop.*
116 | ~$*
117 | *.dbmdl
118 | Generated_Code #added for RIA/Silverlight projects
119 |
120 | # Backup & report files from converting an old project file to a newer
121 | # Visual Studio version. Backup files are not needed, because we have git ;-)
122 | _UpgradeReport_Files/
123 | Backup*/
124 | UpgradeLog*.XML
125 |
126 |
127 |
128 | ############
129 | ## Windows
130 | ############
131 |
132 | # Windows image file caches
133 | Thumbs.db
134 |
135 | # Folder config file
136 | Desktop.ini
137 |
138 |
139 | #############
140 | ## Python
141 | #############
142 |
143 | *.py[co]
144 |
145 | # Packages
146 | *.egg
147 | *.egg-info
148 | dist
149 | build
150 | eggs
151 | parts
152 | bin
153 | var
154 | sdist
155 | develop-eggs
156 | .installed.cfg
157 |
158 | # Installer logs
159 | pip-log.txt
160 |
161 | # Unit test / coverage reports
162 | .coverage
163 | .tox
164 |
165 | #Translations
166 | *.mo
167 |
168 | #Mr Developer
169 | .mr.developer.cfg
170 |
171 | # Mac crap
172 | .DS_Store
173 |
--------------------------------------------------------------------------------
/Checker/Checker.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | ..
7 | --update-golden
8 |
9 |
10 |
11 |
12 |
13 |
14 | PreserveNewest
15 |
16 |
17 |
18 |
19 |
20 | ..\lib\Argu.dll
21 |
22 |
23 | ..\lib\FSharp.Core.dll
24 |
25 |
26 | ..\lib\OpenTK.dll
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Checker/compression_test.fs:
--------------------------------------------------------------------------------
1 | module CompressionTests
2 |
3 | open ShaderMinifier
4 | open System.Runtime.InteropServices
5 | open System.IO
6 | open System.Text
7 |
8 | #nowarn "51" // use of native pointers
9 |
10 | module Crinkler =
11 | []
12 | extern void InitCompressor()
13 |
14 | []
15 | extern single ApproximateModels4k(char* data, int datasize)
16 |
17 |
18 | let testFiles = [
19 | "audio-flight-v2.frag"
20 | "buoy.frag"
21 | "controllable-machinery.frag"
22 | "ed-209.frag"
23 | "elevated.hlsl"
24 | "endeavour.frag"
25 | "from-the-seas-to-the-stars.frag"
26 | "frozen-wasteland.frag"
27 | "kinder_painter.frag"
28 | "leizex.frag"
29 | "lunaquatic.frag"
30 | "mandelbulb.frag"
31 | "ohanami.frag"
32 | "orchard.frag"
33 | "oscars_chair.frag"
34 | "robin.frag"
35 | "slisesix.frag"
36 | "terrarium.frag"
37 | "the_real_party_is_in_your_pocket.frag"
38 | "valley_ball.glsl"
39 | "yx_long_way_from_home.frag"
40 | ]
41 |
42 | let writer = new StringWriter()
43 |
44 | let log fmt =
45 | let logger str =
46 | printf "%s" str
47 | writer.Write(str)
48 |
49 | Printf.ksprintf logger fmt
50 |
51 | let compressionTest args filenames =
52 | let options = Options.init(args)
53 | let minified =
54 | use out = new StringWriter()
55 | let files = [|for f in filenames -> f, File.ReadAllText("tests/real/" + f)|]
56 | let minifier = Minifier(options, files)
57 | minifier.Format(out)
58 | out.ToString().ToCharArray()
59 |
60 | let pointer = &&minified.[0]
61 | log "%-40s " (match filenames with [f] -> f | f::_ -> f + " (and others)" | [] -> "?")
62 | log "%5d " minified.Length
63 | let compressedSize = Crinkler.ApproximateModels4k(pointer, minified.Length)
64 | log "=> %8.3f\n" compressedSize
65 | minified.Length, float compressedSize
66 |
67 | let compressFile (file: string) =
68 | let langArg = if file.EndsWith("hlsl") then [|"--hlsl"|] else [||]
69 | let extraArgs = [|"--format"; "text"|]
70 | compressionTest (Array.append langArg extraArgs) [file]
71 |
72 | let run () =
73 | Crinkler.InitCompressor() // Platform must be set to x64
74 |
75 | writer.GetStringBuilder().Clear() |> ignore
76 |
77 | // Tests for minifying multiple files together.
78 | // We don't have good examples of files that fit together, but these files use the same uniforms (e.g. time, tex0).
79 | let multifileInputs1 = ["clod.frag"; "leizex.frag"; "slisesix.frag"; "motion_blur.frag"; "mandel.frag"; "kaleidoscope.frag"]
80 | let multifileOutput1 = compressionTest [|"--format"; "text"|] multifileInputs1
81 |
82 | let multifileInputs2 = ["mouton/mouton.vert"; "mouton/mouton.frag"; "mouton/fxaa.frag"]
83 | let multifileOutput2 = compressionTest [|"--format"; "text"|] multifileInputs2
84 |
85 | // Tests for individual files.
86 | let sizes = multifileOutput1 :: multifileOutput2 :: List.map compressFile testFiles
87 | let minifiedSum = List.sumBy fst sizes
88 | let compressedSum = List.sumBy snd sizes
89 | log "Total: %5d => %9.3f\n" minifiedSum compressedSum
90 |
91 | File.WriteAllText("tests/compression_results.log", writer.ToString())
92 |
--------------------------------------------------------------------------------
/Checker/glslang.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/Checker/glslang.exe
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(MSBuildThisFileDirectory)artifacts
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/Example.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Example/Program.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Example of use of the ShaderMinifier library from C#.
3 | */
4 |
5 | using ShaderMinifier;
6 |
7 | var shader = """
8 | out vec4 fragColor;
9 | void main()
10 | {
11 | fragColor = vec4(1., 1., 1., 1.);
12 | }
13 | """;
14 |
15 | var file = Tuple.Create("filename.frag", shader);
16 | var options = Minifier.ParseOptions(new[] { "--format", "text" });
17 | var minifier = new Minifier(options, new[] { file });
18 | minifier.Format(System.Console.Out);
19 |
--------------------------------------------------------------------------------
/Minifier/Minifier.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ..\lib\Argu.dll
25 |
26 |
27 | ..\lib\FParsec.dll
28 |
29 |
30 | ..\lib\FParsecCS.dll
31 |
32 |
33 | ..\lib\FSharp.Core.dll
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Minifier/api.fs:
--------------------------------------------------------------------------------
1 | namespace ShaderMinifier
2 |
3 | open System.IO
4 |
5 | type Minifier(options, files) =
6 | let getSize (shaders: Ast.Shader[]) =
7 | shaders |> Seq.sumBy (fun s -> Printer.print s.code |> String.length)
8 |
9 | let minify (options: Options.Options) (files: (string*string)[]) =
10 | // like printfn when verbose option is set
11 | let vprintf fmt = fprintf (if options.verbose then stdout else TextWriter.Null) fmt
12 |
13 | let printSize (shaders: Ast.Shader[]) =
14 | if options.verbose then
15 | let length = getSize shaders
16 | vprintf "Shader size is: %d\n" length
17 |
18 | let names = String.concat "," [for n, c in files -> $"'{n}' ({c.Length}b)"]
19 | options.trace $"----- minifying {names}"
20 | vprintf "Input file size is: %d\n" (files |> Array.sumBy (fun (_, s) -> s.Length))
21 |
22 | let parseAndRewrite (filename, content) =
23 | let shader = Parse.runParser options filename content
24 | let code =
25 | if shader.reorderFunctions then
26 | Rewriter.reorderFunctions options shader.code
27 | else shader.code
28 | { shader with code = Rewriter.simplify options code }
29 |
30 | let shaders = Array.Parallel.map parseAndRewrite files
31 | vprintf "Rewrite tricks applied. "; printSize shaders
32 |
33 | if options.noRenaming then
34 | shaders, [||]
35 | else
36 | let exportedNames = Renamer.rename options (Seq.toArray shaders) |> List.toArray
37 | vprintf "Identifiers renamed. "; printSize shaders
38 | shaders, exportedNames
39 |
40 | let shaders, exportedNames = minify options files
41 |
42 | static member ParseOptions(flags) = Options.init flags
43 | static member ParseOptionsWithFiles(flags) = Options.initFiles flags
44 |
45 | member _.GetSize = getSize shaders
46 | member _.GetShaders = shaders
47 |
48 | member _.Format(writer) = Formatter.print options writer shaders exportedNames
49 | member _.Format(writer, options) =
50 | Formatter.print options writer shaders exportedNames
51 | member _.FormatWithLocations(writer) = Formatter.printWithLocations options writer shaders exportedNames
52 |
--------------------------------------------------------------------------------
/Minifier/builtin.fs:
--------------------------------------------------------------------------------
1 | module internal Builtin
2 |
3 | // source: https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf
4 |
5 | let keywords = System.Collections.Generic.HashSet<_>([
6 | "if"; "else"; "break"; "continue"; "do"; "for"; "while"; "switch"; "case"; "default";
7 | "in"; "out"; "inout"; "discard"; "return"; "lowp"; "mediump"; "highp"; "precision";
8 | "struct"; "layout"; "centroid"; "flat"; "smooth"; "noperspective"; "patch"; "sample"; "invariant";
9 | "precise"; "subroutine"; "coherent"; "volatile"; "restrict"; "readonly"; "writeonly";
10 | "const"; "uniform"; "buffer"; "shared"; "attribute"; "varying"
11 | "template"
12 | ])
13 |
14 | let builtinScalarTypes = set [
15 | "bool"; "int"; "uint"; "float"; "double"
16 | ]
17 | let builtinVectorTypes = set([
18 | for p in [""; "d"; "b"; "i"; "u"] do
19 | for n in ["2"; "3"; "4"] do
20 | yield p+"vec"+n
21 | ])
22 | let builtinMatrixTypes = set([
23 | for p in [""; "d"] do
24 | for n in ["2"; "3"; "4"] do
25 | yield p+"mat"+n
26 | for c in ["2"; "3"; "4"] do
27 | for r in ["2"; "3"; "4"] do
28 | yield p+"mat"+c+"x"+r
29 | ])
30 |
31 | let isSamplerType (name: string) = name.Contains("sampler")
32 |
33 | let builtinTypes = set [ "void" ] + builtinScalarTypes + builtinVectorTypes + builtinMatrixTypes;
34 |
35 | let implicitConversions = // (from, to)
36 | [
37 | (["int"], "uint")
38 | (["int"; "uint"], "float")
39 | (["int"; "uint"; "float"], "double")
40 | (["ivec2"], "uvec2")
41 | (["ivec3"], "uvec3")
42 | (["ivec4"], "uvec4")
43 | (["ivec2"; "uvec2"], "vec2")
44 | (["ivec3"; "uvec3"], "vec3")
45 | (["ivec4"; "uvec4"], "vec4")
46 | (["ivec2"; "uvec2"; "vec2"], "dvec")
47 | (["ivec3"; "uvec3"; "vec3"], "dvec3")
48 | (["ivec4"; "uvec4"; "vec4"], "dvec4")
49 | (["mat2"], "dmat2")
50 | (["mat3"], "dmat3")
51 | (["mat4"], "dmat4")
52 | (["mat2x3"], "dmat2x3")
53 | (["mat2x4"], "dmat2x4")
54 | (["mat3x2"], "dmat3x2")
55 | (["mat3x4"], "dmat3x4")
56 | (["mat4x2"], "dmat4x2")
57 | (["mat4x3"], "dmat4x3")
58 | ]
59 |
60 | let assignOps = set [
61 | "="; "+="; "-="; "*="; "/="; "%="
62 | "<<="; ">>="; "&="; "^="; "|="
63 | "++"; "--"; "$++"; "$--"
64 | ]
65 | let nonAssignOps = set [
66 | "*"; "/"; "%"
67 | "+"; "-"
68 | "<<"; ">>"
69 | "<"; ">"; "<="; ">="
70 | "=="; "!="
71 | "&"; "^"; "|"
72 | "&&"; "^^"; "||"
73 | ]
74 | let augmentableOperators = set ["+"; "-"; "*"; "/"; "%"; "<<"; ">>"; "&"; "^"; "|"]
75 |
76 | let castFunctions = builtinTypes - set ["void"]
77 | let trigonometryFunctions = set([
78 | "acos"; "acosh"; "asin"; "asinh"; "atan"; "atanh"; "cos"; "cosh"; "degrees";
79 | "radians"; "sin"; "sinh"; "tan"; "tanh"])
80 | let mathsFunctions = set([
81 | "abs"; "ceil"; "clamp"; "dFdx"; "dFdy"; "exp"; "exp2"; "floor"; "floor"; "fma";
82 | "fract"; "fwidth"; "inversesqrt"; "isinf"; "isnan"; "log"; "log2"; "max"; "min";
83 | "mix"; "mod"; "modf"; "noise"; "pow"; "round"; "roundEven"; "sign"; "smoothstep";
84 | "sqrt"; "step"; "trunc"])
85 | let vectorFunctions = set([
86 | "cross"; "distance"; "dot"; "equal"; "faceforward"; "length"; "normalize";
87 | "notEqual"; "reflect"; "refract"])
88 | let textureFunctions = set(["texture"; "textureLod"; "texture2D"])
89 |
90 | let pureBuiltinFunctions =
91 | trigonometryFunctions +
92 | mathsFunctions +
93 | vectorFunctions +
94 | castFunctions +
95 | textureFunctions
96 |
97 | let impureBuiltinFunctions = set ["atomicCounterIncrement"]
98 |
99 | let builtinFunctions = pureBuiltinFunctions + impureBuiltinFunctions
100 |
101 | // Type qualifiers telling that a global variables is an 'external' name
102 | // (it may be referenced from other files).
103 | let externalQualifiers = set ["in"; "out"; "attribute"; "varying"; "uniform"]
104 |
105 | let isFieldSwizzle s =
106 | Seq.forall (fun c -> Seq.contains c "rgba") s ||
107 | Seq.forall (fun c -> Seq.contains c "xyzw") s ||
108 | Seq.forall (fun c -> Seq.contains c "stpq") s
109 |
110 | let swizzleIndex = function
111 | | 'r' | 'x' | 's' -> 0
112 | | 'g' | 'y' | 't' -> 1
113 | | 'b' | 'z' | 'p' -> 2
114 | | 'a' | 'w' | 'q' -> 3
115 | | c -> failwithf "not a swizzle (%c) " c
116 |
--------------------------------------------------------------------------------
/SMBolero.Client/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "SMBolero.Client": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "environmentVariables": {
7 | "ASPNETCORE_ENVIRONMENT": "Development"
8 | },
9 | "applicationUrl": "https://localhost:54027;http://localhost:54028"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SMBolero.Client/SMBolero.Client.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | PreserveNewest
22 |
23 |
24 | Never
25 |
26 |
27 | Never
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/SMBolero.Client/Startup.fs:
--------------------------------------------------------------------------------
1 | namespace SMBolero.Client
2 |
3 | open Microsoft.AspNetCore.Components.WebAssembly.Hosting
4 | open Bolero.Remoting.Client
5 |
6 | module Program =
7 |
8 | []
9 | let Main args =
10 | let builder = WebAssemblyHostBuilder.CreateDefault(args)
11 | builder.RootComponents.Add("#main")
12 | builder.Services.AddBoleroRemoting(builder.HostEnvironment) |> ignore
13 | builder.Build().RunAsync() |> ignore
14 | 0
15 |
--------------------------------------------------------------------------------
/SMBolero.Client/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Shader Minifier
7 |
8 |
9 |
10 | Loading...
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SMBolero.Client/wwwroot/minifier.js:
--------------------------------------------------------------------------------
1 | const highlights = [];
2 | const min2src = [];
3 | const src2min = [];
4 |
5 | function getHash(line, col, isMin) {
6 | return line * 1000 + col;
7 | }
8 |
9 | function extractAnnotations(str) {
10 | const lines = str.split('\n');
11 | for (let i = 0; i < lines.length; i++) {
12 | var hasReplaced = true;
13 | while (hasReplaced) {
14 | hasReplaced = false;
15 | lines[i] = lines[i].replace(/(\w+)@(-?\d+),(-?\d+)@/, function (match, ident, line, col, offset) {
16 | hasReplaced = true;
17 | line--;
18 | col--;
19 | min2src[getHash(i, offset)] = { ident, line, col };
20 | src2min[getHash(line, col)] = { ident, line: i, col: offset };
21 | return ident;
22 | });
23 | }
24 | }
25 | return lines.join('\n');
26 | }
27 |
28 | function getPrefix(isMin) {
29 | return isMin ? 'min' : 'src';
30 | }
31 |
32 | function addAnnotations(str, sourceMap, div, isMin) {
33 | const lines = str.split('\n');
34 | for (let i = 0; i < lines.length; i++) {
35 | const line = lines[i];
36 | const lineDiv = document.createElement('div');
37 | lineDiv.classList.add('line');
38 | var html = line.replace(/\w+/g, function (match, offset) {
39 | // console.log(match, i, offset);
40 | const hash1 = getHash(i, offset);
41 | if (sourceMap[hash1]) {
42 | const hash2 = getHash(sourceMap[hash1].line, sourceMap[hash1].col);
43 | return `${match}`;
44 | }
45 | return match;
46 | });
47 |
48 | const comment = html.indexOf('//');
49 | if (comment !== -1) {
50 | html = html.substring(0, comment) + '';
51 | }
52 |
53 | lineDiv.innerHTML = html;
54 | div.appendChild(lineDiv);
55 | }
56 | }
57 |
58 | function show(x, hash) {
59 | const links = document.querySelectorAll("." + hash);
60 | removeHighlights();
61 | for (const link of links) {
62 | addHighlight(link);
63 | }
64 | addHighlight(x);
65 | }
66 | function removeHighlights() {
67 | for (const hl of highlights) {
68 | hl.classList.remove('highlight');
69 | }
70 | highlights.length = 0;
71 | }
72 |
73 |
74 | function addHighlight(item) {
75 | item.classList.add('highlight');
76 | item.scrollIntoView({ block: "center" });
77 | highlights.push(item);
78 | }
79 |
80 | function updateShader(shaderSource, shaderMinified) {
81 | const source = document.querySelector('.source');
82 | const minified = document.querySelector('.minified');
83 |
84 | removeHighlights();
85 | source.innerHTML = '';
86 | minified.innerHTML = '';
87 | min2src.length = 0;
88 | src2min.length = 0;
89 |
90 | const shaderMinified2 = extractAnnotations(shaderMinified);
91 | addAnnotations(shaderMinified2, min2src, minified, true);
92 | addAnnotations(shaderSource, src2min, source, false);
93 | }
94 |
95 | function copyBtn() {
96 | const minified = document.querySelector('.minified');
97 | console.log("Copy", minified.textContent);
98 | navigator.clipboard.writeText(minified.textContent);
99 | const icon = document.querySelector('.copy-icon');
100 |
101 | // animation
102 | icon.classList.remove('animated-icon');
103 | setTimeout(() => icon.classList.add('animated-icon'), 0);
104 | }
105 |
--------------------------------------------------------------------------------
/SMBolero.Server/Index.fs:
--------------------------------------------------------------------------------
1 | module SMBolero.Server.Index
2 |
3 | open Bolero.Html
4 | open Bolero.Server.Html
5 | open SMBolero
6 |
7 | let page = doctypeHtml {
8 | head {
9 | meta { attr.charset "UTF-8" }
10 | meta { attr.name "viewport"; attr.content "width=device-width, initial-scale=1.0" }
11 | title { "Shader Minifier" }
12 | link { attr.rel "stylesheet"; attr.href "css/index.css" }
13 | }
14 | body {
15 | div { attr.id "main"; comp }
16 | boleroScript
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SMBolero.Server/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "SMBolero.Server": {
4 | "commandName": "Project",
5 | "launchBrowser": true,
6 | "environmentVariables": {
7 | "ASPNETCORE_ENVIRONMENT": "Development"
8 | },
9 | "applicationUrl": "https://localhost:54039;http://localhost:54040"
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/SMBolero.Server/SMBolero.Server.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/SMBolero.Server/Startup.fs:
--------------------------------------------------------------------------------
1 | namespace SMBolero.Server
2 |
3 | open Microsoft.AspNetCore
4 | open Microsoft.AspNetCore.Authentication.Cookies
5 | open Microsoft.AspNetCore.Builder
6 | open Microsoft.AspNetCore.Hosting
7 | open Microsoft.Extensions.DependencyInjection
8 | open Bolero
9 | open Bolero.Remoting.Server
10 | open Bolero.Server
11 | open SMBolero
12 | open Bolero.Templating.Server
13 |
14 | type Startup() =
15 |
16 | // This method gets called by the runtime. Use this method to add services to the container.
17 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
18 | member this.ConfigureServices(services: IServiceCollection) =
19 | services.AddMvc() |> ignore
20 | services.AddServerSideBlazor() |> ignore
21 | services
22 | .AddAuthorization()
23 | .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
24 | .AddCookie()
25 | .Services
26 | .AddBoleroHost()
27 | #if DEBUG
28 | .AddHotReload(templateDir = __SOURCE_DIRECTORY__ + "/../SMBolero.Client")
29 | #endif
30 | |> ignore
31 |
32 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
33 | member this.Configure(app: IApplicationBuilder, env: IWebHostEnvironment) =
34 | app
35 | .UseAuthentication()
36 | .UseRemoting()
37 | .UseStaticFiles()
38 | .UseRouting()
39 | .UseBlazorFrameworkFiles()
40 | .UseEndpoints(fun endpoints ->
41 | #if DEBUG
42 | endpoints.UseHotReload()
43 | #endif
44 | endpoints.MapBlazorHub() |> ignore
45 | endpoints.MapFallbackToBolero(Index.page) |> ignore)
46 | |> ignore
47 |
48 | module Program =
49 |
50 | []
51 | let main args =
52 | WebHost
53 | .CreateDefaultBuilder(args)
54 | .UseStaticWebAssets()
55 | .UseStartup()
56 | .Build()
57 | .Run()
58 | 0
59 |
--------------------------------------------------------------------------------
/Shader Minifier.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31903.59
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Minifier", "Minifier\Minifier.fsproj", "{325463FD-AC9D-40DC-B8F2-4ECE086DD840}"
7 | EndProject
8 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Checker", "Checker\Checker.fsproj", "{193EC716-6B61-4A84-A955-6F5AA057B776}"
9 | EndProject
10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SMBolero.Client", "SMBolero.Client\SMBolero.Client.fsproj", "{F6A044CD-2AAA-4849-A4BC-B35AD681A2E2}"
11 | EndProject
12 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SMBolero.Server", "SMBolero.Server\SMBolero.Server.fsproj", "{AD579A74-B3E4-46F1-B262-1F0E37B71BE3}"
13 | EndProject
14 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ShaderMinifier", "ShaderMinifier\ShaderMinifier.fsproj", "{9D562C37-FE7F-4D40-B456-4036FA4FAA7E}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(SolutionProperties) = preSolution
22 | HideSolutionNode = FALSE
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {325463FD-AC9D-40DC-B8F2-4ECE086DD840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {325463FD-AC9D-40DC-B8F2-4ECE086DD840}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {325463FD-AC9D-40DC-B8F2-4ECE086DD840}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {325463FD-AC9D-40DC-B8F2-4ECE086DD840}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {193EC716-6B61-4A84-A955-6F5AA057B776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {193EC716-6B61-4A84-A955-6F5AA057B776}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {193EC716-6B61-4A84-A955-6F5AA057B776}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {193EC716-6B61-4A84-A955-6F5AA057B776}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {F6A044CD-2AAA-4849-A4BC-B35AD681A2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {F6A044CD-2AAA-4849-A4BC-B35AD681A2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {F6A044CD-2AAA-4849-A4BC-B35AD681A2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {F6A044CD-2AAA-4849-A4BC-B35AD681A2E2}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {AD579A74-B3E4-46F1-B262-1F0E37B71BE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {AD579A74-B3E4-46F1-B262-1F0E37B71BE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {AD579A74-B3E4-46F1-B262-1F0E37B71BE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {AD579A74-B3E4-46F1-B262-1F0E37B71BE3}.Release|Any CPU.Build.0 = Release|Any CPU
41 | {9D562C37-FE7F-4D40-B456-4036FA4FAA7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 | {9D562C37-FE7F-4D40-B456-4036FA4FAA7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 | {9D562C37-FE7F-4D40-B456-4036FA4FAA7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {9D562C37-FE7F-4D40-B456-4036FA4FAA7E}.Release|Any CPU.Build.0 = Release|Any CPU
45 | EndGlobalSection
46 | EndGlobal
47 |
--------------------------------------------------------------------------------
/ShaderMinifier/ShaderMinifier.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | ..\lib\Argu.dll
15 |
16 |
17 | ..\lib\FParsec.dll
18 |
19 |
20 | ..\lib\FParsecCS.dll
21 |
22 |
23 | ..\lib\FSharp.Core.dll
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ShaderMinifier/main.fs:
--------------------------------------------------------------------------------
1 | module Main
2 |
3 | open ShaderMinifier
4 | open System.IO
5 |
6 | let readFile file =
7 | use stream =
8 | if file = "" then new StreamReader(System.Console.OpenStandardInput())
9 | else new StreamReader(file)
10 | stream.ReadToEnd()
11 |
12 | let minifyFiles (options: Options.Options) filenames out =
13 | let files = [|
14 | for f in filenames do
15 | let content = readFile f
16 | let filename = if f = "" then "stdin" else f
17 | yield filename, content |]
18 | let minifier = Minifier(options, files)
19 | minifier.Format(out)
20 |
21 | let run (options: Options.Options) filenames =
22 | use out =
23 | if Options.debugMode || options.outputName = "" || options.outputName = "-" then stdout
24 | else new StreamWriter(options.outputName) :> TextWriter
25 | try
26 | minifyFiles options filenames out
27 | 0
28 | with
29 | | :? IOException as ex ->
30 | printfn "Error: %s" ex.Message
31 | 1
32 | | exn ->
33 | printfn "%s" (exn.ToString())
34 | 1
35 |
36 | []
37 | let main argv =
38 | let err =
39 | try
40 | let options, files = Options.initFiles argv
41 | if options.verbose then
42 | printfn "Shader Minifier %s - https://github.com/laurentlb/Shader_Minifier" Options.version
43 | run options files
44 | with
45 | | :? Argu.ArguParseException as ex ->
46 | printfn "%s" ex.Message
47 | 1
48 | | Failure msg ->
49 | printfn "%s" msg
50 | 1
51 | if Options.debugMode then System.Console.ReadLine() |> ignore
52 | exit err
53 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.0.{build}
2 | branches:
3 | only:
4 | - master
5 | image: Visual Studio 2022
6 | configuration: Debug
7 | platform: Any CPU
8 | before_build:
9 | - cmd: nuget restore
10 | build_script:
11 | - cmd: dotnet --version
12 | - cmd: dotnet build "Shader Minifier.sln" /l:"C:\Program Files\AppVeyor\BuildAgent\dotnetcore\Appveyor.MSBuildLogger.dll"
13 | test_script:
14 | - cmd: dotnet run --project Checker/ --compile-golden
15 |
--------------------------------------------------------------------------------
/check.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | dotnet run --project Checker/ --skip-glslang-compile
4 |
--------------------------------------------------------------------------------
/compile.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | dotnet build "Shader Minifier.sln"
4 |
--------------------------------------------------------------------------------
/lib/Argu.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/Argu.dll
--------------------------------------------------------------------------------
/lib/Compressor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/Compressor.dll
--------------------------------------------------------------------------------
/lib/FParsec.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/FParsec.dll
--------------------------------------------------------------------------------
/lib/FParsecCS.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/FParsecCS.dll
--------------------------------------------------------------------------------
/lib/FSharp.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/FSharp.Core.dll
--------------------------------------------------------------------------------
/lib/OpenTK.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/OpenTK.dll
--------------------------------------------------------------------------------
/lib/System.ValueTuple.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/lib/System.ValueTuple.dll
--------------------------------------------------------------------------------
/run-from-source.bash:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | dotnet run --project ShaderMinifier -- "$@"
4 |
--------------------------------------------------------------------------------
/tests/compile.txt:
--------------------------------------------------------------------------------
1 | 330 frag tests/out/real/chocolux.minind.frag
2 | 330 frag tests/out/real/clod.minind.frag
3 | 110 frag tests/out/real/kinder_painter.minind.frag
4 | 330 frag tests/out/real/disco.minind.frag
5 | 330 frag tests/out/real/leizex.minind.frag
6 | 330 frag tests/out/real/heart.minind.frag
7 | 330 frag tests/out/real/mandelbulb.minind.frag
8 | # https://github.com/laurentlb/shader-minifier/issues/402 : 110 frag tests/out/real/to_the_road_of_ribbon.minind.frag
9 | 330 frag tests/out/real/sult.minind.frag
10 | 330 frag tests/out/real/monjori.minind.frag
11 | 330 frag tests/out/real/valley_ball.minind.glsl
12 | 330 frag tests/out/real/slisesix.minind.frag
13 | 330 frag tests/out/real/lunaquatic.minind.frag
14 |
15 | hlsl frag tests/out/real/elevated.minind.hlsl
16 |
17 | 110 frag tests/out/real/yx_long_way_from_home.minind.frag
18 | 110 frag tests/out/real/oscars_chair.minind.frag
19 | 110 frag tests/out/real/the_real_party_is_in_your_pocket.minind.frag
20 | # illegal input (bad preprocessing?) - 110 frag tests/out/real/ohanami.minind.frag
21 | 430 comp tests/out/real/terrarium.minind.frag
22 | 430 comp tests/out/real/from-the-seas-to-the-stars.minind.frag
23 |
24 | shadertoy frag tests/out/real/ed-209.minind.frag
25 | shadertoy frag tests/out/real/frozen-wasteland.minind.frag
26 | shadertoy frag tests/out/real/controllable-machinery.minind.frag
27 | shadertoy frag tests/out/real/endeavour.minind.frag
28 | shadertoy frag tests/out/real/audio-flight-v2.minind.frag
29 | shadertoy frag tests/out/real/buoy.minind.frag
30 | shadertoy frag tests/out/real/orchard.minind.frag
31 | shadertoy frag tests/out/real/robin.minind.frag
32 |
--------------------------------------------------------------------------------
/tests/compression_results.log:
--------------------------------------------------------------------------------
1 | clod.frag (and others) 8694 => 1481.011
2 | mouton/mouton.vert (and others) 16573 => 2403.350
3 | audio-flight-v2.frag 4466 => 863.455
4 | buoy.frag 3975 => 594.340
5 | controllable-machinery.frag 7671 => 1212.215
6 | ed-209.frag 7389 => 1303.549
7 | elevated.hlsl 3405 => 602.340
8 | endeavour.frag 2567 => 522.812
9 | from-the-seas-to-the-stars.frag 14169 => 2272.104
10 | frozen-wasteland.frag 4455 => 772.630
11 | kinder_painter.frag 2832 => 446.282
12 | leizex.frag 2252 => 502.674
13 | lunaquatic.frag 5222 => 1040.171
14 | mandelbulb.frag 2309 => 530.410
15 | ohanami.frag 3179 => 699.259
16 | orchard.frag 5336 => 981.381
17 | oscars_chair.frag 4650 => 979.902
18 | robin.frag 6183 => 1030.289
19 | slisesix.frag 4431 => 882.862
20 | terrarium.frag 3565 => 743.327
21 | the_real_party_is_in_your_pocket.frag 11964 => 1744.283
22 | valley_ball.glsl 4306 => 877.540
23 | yx_long_way_from_home.frag 2885 => 581.527
24 | Total: 132478 => 23067.712
25 |
--------------------------------------------------------------------------------
/tests/real/README.md:
--------------------------------------------------------------------------------
1 | This is a third-party directory. Files in this directory do not have the same
2 | license as the main repository. These files are used only for testing purposes.
3 | Do not use them in any other way without their author first.
4 |
5 | ## How we use the files
6 |
7 | 1. Parser coverage. We need to ensure that Shader Minifier can parse a variety
8 | of shader files. These files help us improve the coverage and be more
9 | confident when we make changes to the parser.
10 |
11 | 2. AST transformation coverage. When we implement AST transformations, we run
12 | them on the test shaders. We call a shader compiler to ensure the output
13 | still compiles. Additionally, we manually review the changes to the minified
14 | shaders to spot potential issues.
15 |
16 | 3. Compression tests. We use these tests to check that Shader Minifier output
17 | stays small and compresses well. We need a variety of test files that are
18 | "realistic" (synthetic files wouldn't have the same compression profile).
19 |
20 | 4. Performance tests. We check the performance of Shader Minifier on real
21 | shaders and make sure it remains fast enough.
22 |
23 |
24 | ## Updating the files
25 |
26 | - `.expected` files are generated by Shader Minifier. They are updated when we
27 | run the tests.
28 | - If you own any of these files, you can reach out to update the file, clarify
29 | the attribution, or have it deleted.
30 | - If you want to contribute new files, you can send a pull request. We prefer
31 | files that increase the code coverage or are representative of the modern
32 | demoscene.
33 |
34 | Note: When the project started, it was not open-source and shaders were
35 | collected from various sources. They are not always well attributed; sorry about
36 | that, we're more careful from now on. We add files that have a compatible
37 | license and add attribution in the file header.
38 |
--------------------------------------------------------------------------------
/tests/real/chocolux.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef CHOCOLUX_EXPECTED_
3 | # define CHOCOLUX_EXPECTED_
4 | # define VAR_resolution "k"
5 | # define VAR_time "v"
6 |
7 | const char *chocolux_frag =
8 | "uniform vec2 k;"
9 | "uniform float v;"
10 | "float s(vec3 d)"
11 | "{"
12 | "return length(d-vec3(cos(v)+sin(v*.2),.3,2.+cos(v*.5)*.5))*length(d-vec3(-cos(v*.7),.3,2.+sin(v*.5)))*length(d-vec3(-sin(v*.2)*.5,sin(v),2))*(cos(d.y)*cos(d.x)-.1-cos(d.z*7.+v*7.)*cos(d.x*3.)*cos(d.y*4.)*.1);"
13 | "}"
14 | "void main()"
15 | "{"
16 | "vec2 d=-1.+2.*gl_FragCoord.xy/k.xy;"
17 | "vec3 c=vec3(d.x,d.y*1.25-.3,0),y=vec3(d.x+cos(v)*.3,d.y,1)/64.;"
18 | "vec4 f=vec4(0);"
19 | "float x=0.;"
20 | "for(int v=0;v<75;v++)"
21 | "{"
22 | "if(s(c+y*x)<.4)"
23 | "{"
24 | "x-=5.;"
25 | "for(int f=0;f<5;f++)"
26 | "{"
27 | "if(s(c+y*x)<.4)"
28 | "break;"
29 | "x+=1.;"
30 | "}"
31 | "vec3 d=vec3(.01,0,0),v=vec3(0);"
32 | "v.x=s(c+y*x)-s(vec3(c+y*x+d.xyy));"
33 | "v.y=s(c+y*x)-s(vec3(c+y*x+d.yxy));"
34 | "v.z=s(c+y*x)-s(vec3(c+y*x+d.yyx));"
35 | "v=normalize(v);"
36 | "f+=max(dot(vec3(0,0,-.5),v),0.)+max(dot(vec3(0,-.5,.5),v),0.)*.5;"
37 | "break;"
38 | "}"
39 | "x+=5.;"
40 | "}"
41 | "gl_FragColor=f+x*.025*vec4(.1,.2,.5,1);"
42 | "}";
43 |
44 | #endif // CHOCOLUX_EXPECTED_
45 |
--------------------------------------------------------------------------------
/tests/real/chocolux.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 |
4 | float h(vec3 q)
5 | {
6 | float f=1.*distance(q,vec3(cos(time)+sin(time*.2),.3,2.+cos(time*.5)*.5));
7 | f*=distance(q,vec3(-cos(time*.7),.3,2.+sin(time*.5)));
8 | f*=distance(q,vec3(-sin(time*.2)*.5,sin(time),2.));
9 | f*=cos(q.y)*cos(q.x)-.1-cos(q.z*7.+time*7.)*cos(q.x*3.)*cos(q.y*4.)*.1;
10 | return f;
11 | }
12 |
13 | void main()
14 | {
15 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
16 | vec3 o=vec3(p.x,p.y*1.25-0.3,0.);
17 | vec3 d=vec3(p.x+cos(time)*0.3,p.y,1.)/64.;
18 | vec4 c=vec4(0.);
19 | float t=0.;
20 | for(int i=0;i<75;i++)
21 | {
22 | if(h(o+d*t)<.4)
23 | {
24 | t-=5.;
25 | for(int j=0;j<5;j++)
26 | {
27 | if(h(o+d*t)<.4)
28 | break;
29 | t+=1.;
30 | }
31 | vec3 e=vec3(.01,.0,.0);
32 | vec3 n=vec3(.0);
33 | n.x=h(o+d*t)-h(vec3(o+d*t+e.xyy));
34 | n.y=h(o+d*t)-h(vec3(o+d*t+e.yxy));
35 | n.z=h(o+d*t)-h(vec3(o+d*t+e.yyx));
36 | n=normalize(n);
37 | c+=max(dot(vec3(.0,.0,-.5),n),.0)+max(dot(vec3(.0,-.5,.5),n),.0)*.5;
38 | break;
39 | }
40 | t+=5.;
41 | }
42 | gl_FragColor=c+vec4(.1,.2,.5,1.)*(t*.025);
43 | }
44 |
--------------------------------------------------------------------------------
/tests/real/clod.expected:
--------------------------------------------------------------------------------
1 | uniform vec2 v;uniform float s;uniform sampler2D y,c,C,D;float n(vec3 v){float s=(sin(v.x)+v.y*.25)*.35;v=vec3(cos(s)*v.x-sin(s)*v.y,sin(s)*v.x+cos(s)*v.y,v.z);return dot(cos(v)*cos(v),vec3(1))-1.2;}vec3 m(vec3 v){vec3 m=vec3(sin(s*1.5)*.5,cos(s)*.5,s);float y=0.,c,f;for(int s=0;s<75;s++){if(n(m+v*y)<0.){c=y-.125;f=y;for(int s=0;s<10;s++){y=(c+f)*.5;if(n(m+v*y)<0.)f=y;else c=y;}vec3 s=vec3(.1,0,0),i=m+v*y;s=-normalize(vec3(n(i+s),n(i+s.yxy),n(i+s.yyx))+vec3(sin(i*75.))*.01);return vec3(mix((max(-dot(s,vec3(.577)),0.)+.125*max(-dot(s,vec3(-.707,-.707,0)),0.))*(mod(length(i.xy)*20.,2.)<1.?vec3(.71,.85,.25):vec3(.79,.93,.4)),vec3(.93,.94,.85),vec3(pow(y/9.,5.))));}y+=.125;}return vec3(.93,.94,.85);}void main(){vec2 s=-1.+2.*gl_FragCoord.xy/v.xy;gl_FragColor=vec4(m(normalize(vec3(s.xy,1))),1);}
2 |
--------------------------------------------------------------------------------
/tests/real/clod.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | float f(vec3 o)
9 | {
10 | float a=(sin(o.x)+o.y*.25)*.35;
11 | o=vec3(cos(a)*o.x-sin(a)*o.y,sin(a)*o.x+cos(a)*o.y,o.z);
12 | return dot(cos(o)*cos(o),vec3(1))-1.2;
13 | }
14 | vec3 s(vec3 o,vec3 d)
15 | {
16 | float t=0.,a,b;
17 | for(int i=0;i<75;i++)
18 | {
19 | if(f(o+d*t)<0.0)
20 | {
21 | a=t-.125;b=t;
22 | for(int i=0; i<10;i++)
23 | {
24 | t=(a+b)*.5;
25 | if(f(o+d*t)<0.0)
26 | b=t;
27 | else
28 | a=t;
29 | }
30 | vec3 e=vec3(.1,0.0,0.0);
31 | vec3 p=o+d*t;
32 | vec3 n=-normalize(vec3(f(p+e),f(p+e.yxy),f(p+e.yyx))+vec3((sin(p*75.)))*.01);
33 |
34 | return vec3( mix( ((max(-dot(n,vec3(.577)),0.) + 0.125*max(-dot(n,vec3(-.707,-.707,0)),0.)))*(mod(length(p.xy)*20.,2.)<1.0?vec3(.71,.85,.25):vec3(.79,.93,.4))
35 | ,vec3(.93,.94,.85), vec3(pow(t/9.,5.)) ) );
36 | }
37 | t+=.125;
38 | }
39 | return vec3(.93,.94,.85);
40 | }
41 | void main()
42 | {
43 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
44 | gl_FragColor=vec4(s(vec3(sin(time*1.5)*.5,cos(time)*.5,time), normalize(vec3(p.xy,1.0))),1.0);
45 | }
46 |
--------------------------------------------------------------------------------
/tests/real/deform.frag:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform vec2 resolution;
3 | uniform vec4 mouse;
4 | uniform sampler2D tex0;
5 | uniform sampler2D tex1;
6 | uniform sampler2D tex2;
7 | uniform sampler2D tex3;
8 |
9 | void main(void)
10 | {
11 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
12 | vec2 m = -1.0 + 2.0 * mouse.xy / resolution.xy;
13 |
14 | float a1 = atan(p.y-m.y,p.x-m.x);
15 | float r1 = sqrt(dot(p-m,p-m));
16 | float a2 = atan(p.y+m.y,p.x+m.x);
17 | float r2 = sqrt(dot(p+m,p+m));
18 |
19 | vec2 uv;
20 | uv.x = 0.2*time + (r1-r2)*0.25;
21 | uv.y = sin(2.0*(a1-a2));
22 |
23 | float w = r1*r2*0.8;
24 | vec3 col = texture2D(tex0,uv).xyz;
25 |
26 | gl_FragColor = vec4(col/(.1+w),1.0);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/real/disco.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | var var_RESOLUTION = "s"
3 | var var_TEX0 = "f"
4 | var var_TEX1 = "C"
5 | var var_TEX2 = "D"
6 | var var_TEX3 = "y"
7 | var var_TIME = "v"
8 |
9 | var disco_frag = `uniform vec2 s;uniform float v;uniform sampler2D f,C,D,y;vec4 n(vec2 s,float f){float c=v*sign(f),a=s.x*320.*.0065*f,i=s.y*240.*.006*f,y=sqrt(a*a+i*i);if(y>1.)return vec4(0);{float r=-.4*sign(f)+sin(c*.05),n=sqrt(1.-a*a-i*i),u=i*sin(r)-n*cos(r);i=i*cos(r)+n*sin(r);n=acos(i);r=acos(a/sin(n))/6.283*120.*sign(u)-c;n=n*60./3.1415;u=cos(floor(n/3.1415));y=pow(abs(cos(r)*sin(n)),.2)*.1/(u+sin(float(int((r+1.57075)/3.1415))+c*.6+cos(u*25.)))*pow(1.-y,.9);return y<0.?vec4(-y/2.*abs(cos(c*.1)),0,-y*2.*abs(sin(c*.04)),1):vec4(y,y*2.,y*2.,1);}}void main(){vec2 f=-1.+2.*gl_FragCoord.xy/s.xy;vec4 r=vec4(0);for(int i=80;i>0;i--)r+=n(f,1.-float(i)/80.)*(.008-float(i)*5e-5);vec4 i=n(f,1.);gl_FragColor=(i.w==0.?n(f,-.2)*.02:i)+sqrt(r);}`
10 |
--------------------------------------------------------------------------------
/tests/real/disco.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | vec4 s(vec2 px,float z)
9 | {
10 | float l=3.1415;
11 | float k=time*sign(z);
12 | float x = px.x*320.0*.0065*z;
13 | float y = px.y*240.0*.0060*z;
14 | float c=sqrt(x*x+y*y);
15 | if(c>1.0)
16 | {
17 | return vec4(0.0);
18 | }
19 | else
20 | {
21 | float u=-.4*sign(z)+sin(k*.05);
22 | float v=sqrt(1.0-x*x-y*y);
23 | float q=y*sin(u)-v*cos(u);
24 | y=y*cos(u)+v*sin(u);
25 | v=acos(y);
26 | u=acos(x/sin(v))/(2.0*l)*120.0*sign(q)-k;
27 | v=v*60.0/l;
28 | q=cos(floor(v/l));
29 | c=pow(abs(cos(u)*sin(v)),.2)*.1/(q+sin(float(int((u+l/2.0)/l))+k*.6+cos(q*25.0)))*pow(1.0-c,.9);
30 |
31 | vec4 res;
32 | if(c<0.0)
33 | res = vec4(-c/2.0*abs(cos(k*.1)),0.0,-c*2.0*abs(sin(k*.04)),1.0);
34 | else
35 | res = vec4(c,c*2.0,c*2.0,1.0);
36 | return res;
37 | }
38 | }
39 |
40 | void main(void)
41 | {
42 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
43 | vec4 c = vec4(0.0);
44 | for(int i=80;i>0;i--)
45 | c+=s(p,1.0-float(i)/80.0)*(.008-float(i)*.00005);
46 | vec4 d=s(p,1.0);
47 | gl_FragColor = (d.a==0.0?s(p,-.2)*.02:d)+sqrt(c);
48 | }
49 |
--------------------------------------------------------------------------------
/tests/real/elevated.hlsl:
--------------------------------------------------------------------------------
1 | sampler t0,t1,t2;float4 q[16];float4x4 v:register(c16);float3 no(float2 p){float2 f=p-floor(p);float2 u=f*f*f*(f*(f*6-15)+10);float a=tex2Dlod(t0,float4((floor(p)+float2(0,0))/256,0,0));float b=tex2Dlod(t0,float4((floor(p)+float2(1,0))/256,0,0));float c=tex2Dlod(t0,float4((floor(p)+float2(0,1))/256,0,0));float d=tex2Dlod(t0,float4((floor(p)+float2(1,1))/256,0,0));return float3(a+(b-a)*u.x+(c-a)*u.y+(a-b-c+d)*u.x*u.y,30*f*f*(f*(f-2)+1)*(float2(b-a,c-a)+(a-b-c+d)*u.yx));}float f(float2 p,float o){float2 d=0;float a=0;float b=3;for(float i=0;i.5){float t=length(d.xyz-q[4].xyz);float w=q[1].w-d.y;if(w<0){float3 n=cn(d.xz,.001*t,12-log2(t));float h=f(3*d.xz,3);float r=no(666*d.xz);c=(.1+.75*q[2].x)*(.8+.2*r);c=lerp(c,lerp(float3(.8,.85,.9),float3(.45,.45,.2)*(.8+.2*r),q[2].x),smoothstep(.5-.8*n.y,1-1.1*n.y,h*.15));c=lerp(c,lerp(float3(.37,.23,.08),float3(.42,.4,.2),q[2].x)*(.5+.5*r),smoothstep(0,1,50*(n.y-1)+(h+q[2].x)/.4));c*=b(d,n,cn(d.xz,.001*t,5));}else{t=(q[1].w-q[4].y)/e.y;d=q[4]+e.xyzz*t;float3 n=normalize(cn(float2(512,32)*d.xz+saturate(w*60)*float2(q[3].w,0),.001*t,4)*float3(1,6,1));c=.12*(float3(.4,1,1)-float3(.2,.6,.4)*saturate(w*16));c*=.3+.7*q[2].x;c+=pow(1-mul(-e,n),4)*(pow(mul(q[3],reflect(-e,n)),32)*float3(.32,.31,.3)+.1);c=lerp(c,b(d,n,n),smoothstep(1,0,q[2].x+w*60-f(666*d.xz+saturate(w*60)*float2(q[3].w,0)*2,5))*.5);}c*=.7+.3*smoothstep(0,1,256*abs(w));c*=exp(-.042*t);c+=(1-exp(-.1*t))*(float3(.52,.59,.65)+pow(saturate(mul(e,q[3])),8)*float3(.6,.4,.1));}return float4(c,0);}float4 m4(float2 x:texcoord):color{float2 o=x+.5/1280;float4 d=tex2D(t1,o);float3 c=tex2D(t2,o);if(d.w>.5){d=mul(v,float4(d.xyz,1));d.y*=-1;c=0;for(float i=0;i<16;i++){c.x+=tex2D(t2,o+i*(.5+.5*d.xy/d.w-o)/16+float2(2,0)/1280).x;c.y+=tex2D(t2,o+i*(.5+.5*d.xy/d.w-o)/16+float2(0,0)/1280).y;c.z+=tex2D(t2,o+i*(.5+.5*d.xy/d.w-o)/16+float2(-2,0)/1280).z;}c/=16;}c=pow(c,.45)*q[2].z+q[2].y;c*=.4+9.6*o.x*o.y*(1-o.x)*(1-o.y);c.xz*=.98;float w=tex2D(t0,q[3].w*.1);o+=w;c-=.005*w;c.x+=.01*tex2D(t0,o+=.1);c.y+=.01*tex2D(t0,o+=.1);c.z+=.01*tex2D(t0,o+=.1);return float4(c,0);}
2 |
--------------------------------------------------------------------------------
/tests/real/endeavour.frag.expected:
--------------------------------------------------------------------------------
1 | const float pi=acos(-1.);
2 | const vec3 c=vec3(1,0,-1);
3 | float a=1.;
4 | void rand(vec2 x,out float num)
5 | {
6 | x+=4e2;
7 | num=fract(sin(dot(sign(x)*abs(x),vec2(12.9898,78.233)))*43758.5453);
8 | }
9 | void lfnoise(vec2 t,out float num)
10 | {
11 | vec2 i=floor(t);
12 | t=smoothstep(c.yy,c.xx,fract(t));
13 | vec2 v1,v2;
14 | rand(i,v1.x);
15 | rand(i+c.xy,v1.y);
16 | rand(i+c.yx,v2.x);
17 | rand(i+c.xx,v2.y);
18 | v1=c.zz+2.*mix(v1,v2,t.y);
19 | num=mix(v1.x,v1.y,t.x);
20 | }
21 | void mfnoise(vec2 x,float fmin,float fmax,float alpha,out float num)
22 | {
23 | num=0.;
24 | float a=1.,nf=0.,buf;
25 | for(float f=fmin;f-.05)
60 | {
61 | float n2;
62 | mfnoise(x.xy,30.,5e2,.47,n2);
63 | vec2 sda=vec2(x.z+.05+.01*n2,1);
64 | add(sdf,sda,sdf);
65 | }
66 | float R=.07+.1*sdf.x,dis;
67 | lfnoise(.5*x.y*c.xx,dis);
68 | vec2 sdb,ya=abs(x.xz-.4*dis*c.xy)+.045*c.yx-.065*c.xy;
69 | zextrude(x.y,-length(ya)+R,sdb.x);
70 | stroke(sdb.x,.003,R);
71 | sdb.y=2.;
72 | vec2 ind;
73 | dhexagonpattern(vec2(56,12)*vec2(x.y,atan(ya.y,ya.x)),dis,ind);
74 | stroke(dis,.2,dis);
75 | stroke(sdb.x,.003*step(dis,0.),sdb.x);
76 | sdf.x=max(sdf.x,-R);
77 | add(sdf,sdb,sdf);
78 | sdf.x=min(sdf.x,abs(-length(max(abs(mod(x,.1)-.05)-vec3(.05*c.xx,.6),0.)))+.01);
79 | }
80 | void normal(vec3 x,out vec3 n)
81 | {
82 | vec2 s,na;
83 | scene(x,s);
84 | scene(x+5e-4*c.xyy,na);
85 | n.x=na.x;
86 | scene(x+5e-4*c.yxy,na);
87 | n.y=na.x;
88 | scene(x+5e-4*c.yyx,na);
89 | n.z=na.x;
90 | n=normalize(n-s.x);
91 | }
92 | void planet_texture(vec2 x,out vec3 col)
93 | {
94 | float d;
95 | mfnoise(x,1.,4e2,.65,d);
96 | col=mix(vec3(.19,.02,0),vec3(.91,.45,.02),.5+.5*d);
97 | stroke(d,.01,d);
98 | col=mix(mix(mix(.8*vec3(.99,.49,.02),c.yyy,d*clamp(.2-.5*x.y/12.,0.,1.)),col,smoothstep(-.05,.05,d)),vec3(.15,.05,0),clamp(.2-.5*x.y/12.,0.,1.));
99 | }
100 | void mainImage(out vec4 fragColor,vec2 fragCoord)
101 | {
102 | a=iResolution.x/iResolution.y;
103 | vec2 uv=fragCoord/iResolution.yy-.5*vec2(a,1),s;
104 | vec3 col=c.yyy,o=.5*c.yyx+.3*iTime*c.yxy,t=vec3(uv,0)+.3*iTime*c.yxy+c.yxy,dir=normalize(t-o);
105 | float d=(.04-o.z)/dir.z;
106 | int i;
107 | for(i=0;i<450;++i)
108 | {
109 | t=o+d*dir;
110 | scene(t,s);
111 | if(s.x<1e-4)
112 | break;
113 | d+=s.x;
114 | }
115 | if(i<450)
116 | {
117 | vec3 n,l=normalize(t+c.yyx);
118 | normal(t,n);
119 | vec3 c1=vec3(.99,.64,.02);
120 | if(s.y==1.)
121 | {
122 | planet_texture(t.xy,c1);
123 | col=.3*c1+.3*c1*abs(dot(l,n))+(1.3*c1+.1*c.xyy)*pow(abs(dot(reflect(-l,n),dir)),3.);
124 | if(t.z<0.)
125 | {
126 | float dis;
127 | lfnoise(.5*t.y*c.xx,dis);
128 | dis=abs(t.x-.4*dis)-.15;
129 | col=mix(col,.3*col,smoothstep(-.01,.01,-dis));
130 | }
131 | }
132 | else if(s.y==2.)
133 | planet_texture(t.xy,c1),col=.3*c1+.3*c1*abs(dot(l,n))+(1.3*c1+.1*c.xyy)*pow(abs(dot(reflect(-l,n),dir)),3.),col=mix(col,.4*length(col)*c.xyy,.7);
134 | }
135 | col=clamp(col,0.,1.);
136 | fragColor=vec4(col,1);
137 | }
138 |
--------------------------------------------------------------------------------
/tests/real/heart.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | pub const VAR_MOUSE: &'static [u8] = b"f\0";
3 | pub const VAR_RESOLUTION: &'static [u8] = b"y\0";
4 | pub const VAR_TIME: &'static [u8] = b"v\0";
5 |
6 | pub const HEART_FRAG: &'static [u8] = b"\
7 | uniform float v;\
8 | uniform vec2 y;\
9 | uniform vec4 f;\
10 | void main()\
11 | {\
12 | vec2 f=(2.*gl_FragCoord.xy-y)/y.y;\
13 | float g=mod(v,2.)/2.,a=pow(g,.2)*.5+.5;\
14 | a-=a*.2*sin(g*6.2831*5.)*exp(-g*6.);\
15 | f*=vec2(.5,1.5)+a*vec2(.5,-.5);\
16 | g=atan(f.x,f.y)/3.141593;\
17 | a=length(f);\
18 | g=abs(g);\
19 | g=(13.*g-22.*g*g+10.*g*g*g)/(6.-5.*g);\
20 | gl_FragColor=vec4(step(a,g)*pow(1.-a/g,.25),0,0,1);\
21 | }\0";
22 |
--------------------------------------------------------------------------------
/tests/real/heart.frag:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform vec2 resolution;
3 | uniform vec4 mouse;
4 |
5 | void main(void)
6 | {
7 | vec2 p = (2.0*gl_FragCoord.xy-resolution)/resolution.y;
8 |
9 | // animate
10 | float tt = mod(time,2.0)/2.0;
11 | float ss = pow(tt,.2)*0.5 + 0.5;
12 | ss -= ss*0.2*sin(tt*6.2831*5.0)*exp(-tt*6.0);
13 | p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);
14 |
15 |
16 | float a = atan(p.x,p.y)/3.141593;
17 | float r = length(p);
18 |
19 | // shape
20 | float h = abs(a);
21 | float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);
22 |
23 | // color
24 | float f = step(r,d)*pow(1.0-r/d,0.25);
25 |
26 | gl_FragColor = vec4(f,0.0,0.0,1.0);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/real/heart.frag.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef HEART_FRAG_EXPECTED_
3 | # define HEART_FRAG_EXPECTED_
4 | # define VAR_mouse "f"
5 | # define VAR_resolution "y"
6 | # define VAR_time "v"
7 |
8 | const char *heart_frag =
9 | "uniform float v;"
10 | "uniform vec2 y;"
11 | "uniform vec4 f;"
12 | "void main()"
13 | "{"
14 | "vec2 f=(2.*gl_FragCoord.xy-y)/y.y;"
15 | "float g=mod(v,2.)/2.,a=pow(g,.2)*.5+.5;"
16 | "a-=a*.2*sin(g*6.2831*5.)*exp(-g*6.);"
17 | "f*=vec2(.5,1.5)+a*vec2(.5,-.5);"
18 | "g=atan(f.x,f.y)/3.141593;"
19 | "a=length(f);"
20 | "g=abs(g);"
21 | "g=(13.*g-22.*g*g+10.*g*g*g)/(6.-5.*g);"
22 | "gl_FragColor=vec4(step(a,g)*pow(1.-a/g,.25),0,0,1);"
23 | "}";
24 |
25 | #endif // HEART_FRAG_EXPECTED_
26 |
--------------------------------------------------------------------------------
/tests/real/heart2.expected:
--------------------------------------------------------------------------------
1 | {"mappings":{"mouse":"f","resolution":"y","time":"v"},"shaders":{"tests/real/heart2.frag":"uniform float v;uniform vec2 y;uniform vec4 f;void main(){vec2 f=(2.*gl_FragCoord.xy-y)/y.y;float g=mod(v,2.)/2.,a=pow(g,.2)*.5+.5;a-=a*.2*sin(g*6.2831*5.)*exp(-g*6.);f*=vec2(.5,1.5)+a*vec2(.5,-.5);g=atan(f.x,f.y)/3.141593;a=length(f);g=abs(g);g=(13.*g-22.*g*g+10.*g*g*g)/(6.-5.*g);gl_FragColor=vec4(step(a,g)*pow(1.-a/g,.25),0,0,1);}"}}
2 |
--------------------------------------------------------------------------------
/tests/real/heart2.frag:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform vec2 resolution;
3 | uniform vec4 mouse;
4 |
5 | void main(void)
6 | {
7 | vec2 p = (2.0*gl_FragCoord.xy-resolution)/resolution.y;
8 |
9 | // animate
10 | float tt = mod(time,2.0)/2.0;
11 | float ss = pow(tt,.2)*0.5 + 0.5;
12 | ss -= ss*0.2*sin(tt*6.2831*5.0)*exp(-tt*6.0);
13 | p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);
14 |
15 |
16 | float a = atan(p.x,p.y)/3.141593;
17 | float r = length(p);
18 |
19 | // shape
20 | float h = abs(a);
21 | float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);
22 |
23 | // color
24 | float f = step(r,d)*pow(1.0-r/d,0.25);
25 |
26 | gl_FragColor = vec4(f,0.0,0.0,1.0);
27 | }
28 |
--------------------------------------------------------------------------------
/tests/real/julia.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | void main(void)
9 | {
10 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
11 | vec2 cc = vec2( cos(.25*time), sin(.25*time*1.423) );
12 |
13 | float dmin = 1000.0;
14 | vec2 z = p*vec2(1.33,1.0);
15 | for( int i=0; i<64; i++ )
16 | {
17 | z = cc + vec2( z.x*z.x - z.y*z.y, 2.0*z.x*z.y );
18 | float m2 = dot(z,z);
19 | if( m2>100.0 ) break;
20 | dmin=min(dmin,m2);
21 | }
22 |
23 | float color = sqrt(sqrt(dmin))*0.7;
24 | gl_FragColor = vec4(color,color,color,1.0);
25 | }
26 |
--------------------------------------------------------------------------------
/tests/real/kaleidoscope.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | void main(void)
9 | {
10 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
11 | vec2 uv;
12 |
13 | float a = atan(p.y,p.x);
14 | float r = sqrt(dot(p,p));
15 |
16 | uv.x = 7.0*a/3.1416;
17 | uv.y = -time+ sin(7.0*r+time) + .7*cos(time+7.0*a);
18 |
19 | float w = .5+.5*(sin(time+7.0*r)+ .7*cos(time+7.0*a));
20 |
21 | vec3 col = texture2D(tex0,uv*.5).xyz;
22 |
23 | gl_FragColor = vec4(col*w,1.0);
24 | }
25 |
--------------------------------------------------------------------------------
/tests/real/leizex.expected:
--------------------------------------------------------------------------------
1 | ; Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | _var_RESOLUTION: db 'n', 0
3 | _var_TEX0: db 'f', 0
4 | _var_TEX1: db 'm', 0
5 | _var_TEX2: db 'o', 0
6 | _var_TEX3: db 'y', 0
7 | _var_TIME: db 'v', 0
8 |
9 | _leizex_frag:
10 | db '#extension GL_EXT_gpu_shader4:enable', 10, ''
11 | db 'uniform vec2 n;'
12 | db 'uniform float v;'
13 | db 'uniform sampler2D f,m,o,y;'
14 | db 'float t(int v)'
15 | db '{'
16 | db 'v^=v<<13;'
17 | db 'v=v*(v*v*15731+789221)+1376312589&2147483647;'
18 | db 'return float(v);'
19 | db '}'
20 | db 'float t(vec3 v,int f)'
21 | db '{'
22 | db 'ivec3 n=ivec3(floor(v));'
23 | db 'vec3 c=fract(v);'
24 | db 'c=c*c*(3.-2.*c);'
25 | db 'f+=n.x+n.y*57+113*n.z;'
26 | db 'float y=mix(mix(mix(t(f),t(f+1),c.x),mix(t(f+57),t(f+58),c.x),c.y),mix(mix(t(f+113),t(f+114),c.x),mix(t(f+170),t(f+171),c.x),c.y),c.z);'
27 | db 'return 1.-y*(1./1073741824.);'
28 | db '}'
29 | db 'vec2 t(vec3 v)'
30 | db '{'
31 | db 'ivec3 c=ivec3(floor(v));'
32 | db 'vec3 f=fract(v);'
33 | db 'vec2 n=vec2(1);'
34 | db 'for(int v=-1;v<=1;v++)'
35 | db 'for(int x=-1;x<=1;x++)'
36 | db 'for(int y=-1;y<=1;y++)'
37 | db '{'
38 | db 'int i=c.x+y+57*(c.y+x)+113*(c.z+v);'
39 | db 'vec3 m=vec3(float(y),float(x),float(v))-f+vec3(t(i),t(i+1217),t(i+2513))/2147483647.;'
40 | db 'float s=dot(m,m);'
41 | db 'if(s1024.0 ) break;
29 | co += 1.0;
30 | }
31 | co = co + 1.0 - log2(.5*log2(m2));
32 |
33 | co = sqrt(co/256.0);
34 | gl_FragColor = vec4( .5+.5*cos(6.2831*co+0.0),
35 | .5+.5*cos(6.2831*co+0.4),
36 | .5+.5*cos(6.2831*co+0.7),
37 | 1.0 );
38 | }
39 |
--------------------------------------------------------------------------------
/tests/real/mandelbulb.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef MANDELBULB_EXPECTED_
3 | # define MANDELBULB_EXPECTED_
4 |
5 | const char *mandelbulb_frag =
6 | "uniform vec2 resolution;"
7 | "uniform float time;"
8 | "bool f(vec3 v,vec3 f,out vec2 i)"
9 | "{"
10 | "vec4 t=vec4(0,0,0,1.25);"
11 | "vec3 y=v-t.xyz;"
12 | "float c=dot(y,f),e=c*c-dot(y,y)+t.w*t.w;"
13 | "if(e<0.)"
14 | "return false;"
15 | "e=sqrt(e);"
16 | "i.x=-c-e;"
17 | "i.y=-c+e;"
18 | "return true;"
19 | "}"
20 | "bool f(vec3 v,out float f,out vec4 y)"
21 | "{"
22 | "vec4 e=vec4(100);"
23 | "vec3 i=v;"
24 | "float t=dot(i,i);"
25 | "if(t>1e2)"
26 | "return f=.5*log(t)/pow(8.,0.),y=vec4(1),false;"
27 | "for(int x=1;x<7;x++)"
28 | "{"
29 | "\n#if 0\n"
30 | "float z=sqrt(dot(i,i)),o=acos(i.y/z),c=atan(i.x,i.z);"
31 | "z=pow(z,8.);"
32 | "o*=8.;"
33 | "c*=8.;"
34 | "i=v+z*vec3(sin(o)*sin(c),cos(o),sin(o)*cos(c));"
35 | "\n#else\n"
36 | "float n=i.x,s=n*n,d=s*s,a=i.y,l=a*a,m=i.z,w=m*m,g=w*w,p=s+w,r=inversesqrt(p*p*p*p*p*p*p),C=d+l*l+g-6.*l*w-6.*s*l+2.*w*s,F=s-l+w;"
37 | "i.x=v.x+64.*n*a*m*(s-w)*F*(d-6.*s*w+g)*C*r;"
38 | "i.y=v.y+-16.*l*p*F*F+C*C;"
39 | "i.z=v.z+-8.*a*F*(d*d-28.*d*s*w+70.*d*g-28.*s*w*g+g*g)*C*r;"
40 | "\n#endif\n"
41 | "t=dot(i,i);"
42 | "e=min(e,vec4(i.xyz*i.xyz,t));"
43 | "if(t>1e2)"
44 | "return y=e,f=.5*log(t)/pow(8.,float(x)),false;"
45 | "}"
46 | "y=e;"
47 | "f=0.;"
48 | "return true;"
49 | "}"
50 | "bool f(vec3 v,vec3 s,out float y,out vec3 i,out vec4 t)"
51 | "{"
52 | "vec2 e;"
53 | "if(!f(v,s,e))"
54 | "return false;"
55 | "if(e.y<.001)"
56 | "return false;"
57 | "if(e.x<.001)"
58 | "e.x=.001;"
59 | "if(e.y>1e20)"
60 | "e.y=1e20;"
61 | "float c;"
62 | "vec3 x;"
63 | "vec4 o;"
64 | "float w=1./sqrt(2.);"
65 | "for(float p=e.x;p.001)"
105 | "if(f(i,v,r,C,x))"
106 | "e=.1;"
107 | "s=mix(mix(mix(vec3(1),vec3(.8,.6,.2),sqrt(o.x)*1.25),vec3(.8,.3,.3),sqrt(o.y)*1.25),vec3(.7,.4,.3),sqrt(o.z)*1.25)*((.5+.5*t.y)*vec3(.14,.15,.16)*.8+e*vec3(1,.85,.4)+.5*w*vec3(.08,.1,.14))*vec3(pow(d,.8),d,pow(d,1.1));"
108 | "s=1.5*(s*.15+.85*sqrt(s));"
109 | "}"
110 | "else"
111 | " s=1.3*vec3(1,.98,.9)*(.7+.3*p.y);"
112 | "i=i*.5+.5;"
113 | "s=clamp(s*(.7+4.8*i.x*i.y*(1.-i.x)*(1.-i.y)),0.,1.);"
114 | "gl_FragColor=vec4(s,1);"
115 | "}";
116 |
117 | #endif // MANDELBULB_EXPECTED_
118 |
--------------------------------------------------------------------------------
/tests/real/metatunnel.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 |
4 | float h(vec3 q)
5 | {
6 | float f=1.*distance(q,vec3(cos(time)+sin(time*.2),.3,2.+cos(time*.5)*.5));
7 | f*=distance(q,vec3(-cos(time*.7),.3,2.+sin(time*.5)));
8 | f*=distance(q,vec3(-sin(time*.2)*.5,sin(time),2.));
9 | f*=cos(q.y)*cos(q.x)-.1-cos(q.z*7.+time*7.)*cos(q.x*3.)*cos(q.y*4.)*.1;
10 | return f;
11 | }
12 |
13 | void main()
14 | {
15 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
16 | vec3 o=vec3(p.x,p.y*1.25-0.3,0.);
17 | vec3 d=vec3(p.x+cos(time)*0.3,p.y,1.)/64.;
18 | vec4 c=vec4(0.);
19 | float t=0.;
20 | for(int i=0;i<75;i++)
21 | {
22 | if(h(o+d*t)<.4)
23 | {
24 | t-=5.;
25 | for(int j=0;j<5;j++)
26 | {
27 | if(h(o+d*t)<.4)
28 | break;
29 | t+=1.;
30 | }
31 | vec3 e=vec3(.01,.0,.0);
32 | vec3 n=vec3(.0);
33 | n.x=h(o+d*t)-h(vec3(o+d*t+e.xyy));
34 | n.y=h(o+d*t)-h(vec3(o+d*t+e.yxy));
35 | n.z=h(o+d*t)-h(vec3(o+d*t+e.yyx));
36 | n=normalize(n);
37 | c+=max(dot(vec3(.0,.0,-.5),n),.0)+max(dot(vec3(.0,-.5,.5),n),.0)*.5;
38 | break;
39 | }
40 | t+=5.;
41 | }
42 | gl_FragColor=c+vec4(.1,.2,.5,1.)*(t*.025);
43 | }
44 |
--------------------------------------------------------------------------------
/tests/real/monjori.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | void main(void)
9 | {
10 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
11 | float a = time*40.0;
12 | float d,e,f,g=1.0/40.0,h,i,r,q;
13 | e=400.0*(p.x*0.5+0.5);
14 | f=400.0*(p.y*0.5+0.5);
15 | i=200.0+sin(e*g+a/150.0)*20.0;
16 | d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
17 | r=sqrt(pow(i-e,2.0)+pow(d-f,2.0));
18 | q=f/r;
19 | e=(r*cos(q))-a/2.0;f=(r*sin(q))-a/2.0;
20 | d=sin(e*g)*176.0+sin(e*g)*164.0+r;
21 | h=((f+d)+a/2.0)*g;
22 | i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
23 | h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
24 | h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
25 | i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
26 | i=mod(i/5.6,256.0)/64.0;
27 | if(i<0.0) i+=4.0;
28 | if(i>=2.0) i=4.0-i;
29 | d=r/350.0;
30 | d+=sin(d*d*8.0)*0.52;
31 | f=(sin(a*g)+1.0)/2.0;
32 | gl_FragColor = vec4(f*i/1.6,i/2.0+d/13.0,i,1.0)*d*p.x+vec4(i/1.3+d/8.0,i/2.0+d/18.0,i,1.0)*d*(1.0-p.x);
33 | }
34 |
--------------------------------------------------------------------------------
/tests/real/monjori.frag.expected:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0,tex1,tex2,tex3;
4 | void main()
5 | {
6 | vec2 p=-1.+2.*gl_FragCoord.xy/resolution.xy;
7 | float a=time*40.,d,e,f,h,i,r,q;
8 | e=4e2*(p.x*.5+.5);
9 | f=4e2*(p.y*.5+.5);
10 | i=2e2+sin(e*.025+a/150.)*20.;
11 | d=2e2+cos(f*.025/2.)*18.+cos(e*.025)*7.;
12 | r=sqrt(pow(i-e,2.)+pow(d-f,2.));
13 | q=f/r;
14 | e=r*cos(q)-a/2.;
15 | f=r*sin(q)-a/2.;
16 | d=sin(e*.025)*176.+sin(e*.025)*164.+r;
17 | h=(f+d+a/2.)*.025;
18 | i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*.025*6.)*(r+h/3.);
19 | h=sin(f*.025)*144.-sin(e*.025)*212.*p.x;
20 | h=(h+(f-e)*q+sin(r-(a+h)/7.)*10.+i/4.)*.025;
21 | i=mod((i+cos(h*2.3*sin(a/350.-q))*184.*sin(q-(r*4.3+a/12.)*.025)+tan(r*.025+h)*184.*cos(r*.025+h))/5.6,256.)/64.;
22 | if(i<0.)
23 | i+=4.;
24 | if(i>=2.)
25 | i=4.-i;
26 | d=r/350.;
27 | d+=sin(d*d*8.)*.52;
28 | f=(sin(a*.025)+1.)/2.;
29 | gl_FragColor=vec4(f*i/1.6,i/2.+d/13.,i,1)*d*p.x+vec4(i/1.3+d/8.,i/2.+d/18.,i,1)*d*(1.-p.x);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/real/motion_blur.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | vec3 deform( in vec2 p, float scale )
9 | {
10 | vec2 uv;
11 |
12 | float mtime = scale+time;
13 | float a = atan(p.y,p.x);
14 | float r = sqrt(dot(p,p));
15 | float s = r * (1.0+0.5*cos(mtime*1.7));
16 |
17 | uv.x = .1*mtime +.05*p.y+.05*cos(-mtime+a*3.0)/s;
18 | uv.y = .1*mtime +.05*p.x+.05*sin(-mtime+a*3.0)/s;
19 |
20 | float w = 0.8-0.2*cos(mtime+3.0*a);
21 |
22 | vec3 res = texture2D(tex0,uv).xyz*w;
23 | return res*res;
24 |
25 | }
26 |
27 | void main(void)
28 | {
29 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
30 | vec3 total = vec3(0.0);
31 | float w = 0.0;
32 | for( int i=0; i<20; i++ )
33 | {
34 | vec3 res = deform(p,w);
35 | total += res;
36 | w += 0.02;
37 | }
38 | total /= 20.0;
39 |
40 | gl_FragColor = vec4( 3.0*total,1.0);
41 | }
42 |
--------------------------------------------------------------------------------
/tests/real/mouton/fxaa.frag:
--------------------------------------------------------------------------------
1 | #version 150
2 | out vec4 fragColor;
3 | const vec2 iResolution = vec2(1920.,1080.);
4 |
5 |
6 | uniform sampler2D tex;
7 |
8 | void main(void)
9 | {
10 | vec2 rcpFrame = 1./iResolution;
11 | vec2 texcoord = gl_FragCoord.xy * rcpFrame;
12 | vec4 uv = vec4( texcoord, texcoord - (rcpFrame * 0.5));
13 |
14 | vec3 rgbNW = textureLod(tex, uv.zw, 0.0).xyz;
15 | vec3 rgbNE = textureLod(tex, uv.zw + vec2(1,0)*rcpFrame.xy, 0.0).xyz;
16 | vec3 rgbSW = textureLod(tex, uv.zw + vec2(0,1)*rcpFrame.xy, 0.0).xyz;
17 | vec3 rgbSE = textureLod(tex, uv.zw + vec2(1,1)*rcpFrame.xy, 0.0).xyz;
18 | vec3 rgbM = textureLod(tex, uv.xy, 0.0).xyz;
19 |
20 | vec3 luma = vec3(0.299, 0.587, 0.114);
21 | float lumaNW = dot(rgbNW, luma);
22 | float lumaNE = dot(rgbNE, luma);
23 | float lumaSW = dot(rgbSW, luma);
24 | float lumaSE = dot(rgbSE, luma);
25 | float lumaM = dot(rgbM, luma);
26 |
27 | float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
28 | float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
29 |
30 | vec2 dir = vec2( -((lumaNW + lumaNE) - (lumaSW + lumaSE)), ((lumaNW + lumaSW) - (lumaNE + lumaSE)));
31 | float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + (1./128.));
32 |
33 | dir = min(vec2( 8., 8.),
34 | max(vec2(-8., -8.),
35 | dir * rcpDirMin)) * rcpFrame.xy;
36 |
37 | vec3 rgbA = (1.0/2.0) * (
38 | textureLod(tex, uv.xy + dir * (1.0/3.0 - 0.5), 0.0).xyz +
39 | textureLod(tex, uv.xy + dir * (2.0/3.0 - 0.5), 0.0).xyz);
40 | vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
41 | textureLod(tex, uv.xy + dir * (0.0/3.0 - 0.5), 0.0).xyz +
42 | textureLod(tex, uv.xy + dir * (3.0/3.0 - 0.5), 0.0).xyz);
43 |
44 | float lumaB = dot(rgbB, luma);
45 |
46 | if((lumaB < lumaMin) || (lumaB > lumaMax))
47 | fragColor = vec4(rgbA,1.);
48 | else
49 | fragColor = vec4(rgbB,1.);
50 | }
--------------------------------------------------------------------------------
/tests/real/postprocessing.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | void main(void)
9 | {
10 | vec2 q = gl_FragCoord.xy / resolution.xy;
11 | vec2 uv = 0.5 + (q-0.5)*(0.9 + 0.1*sin(0.2*time));
12 |
13 | vec3 oricol = texture2D(tex0,vec2(q.x,1.0-q.y)).xyz;
14 | vec3 col;
15 |
16 | col.r = texture2D(tex0,vec2(uv.x+0.003,-uv.y)).x;
17 | col.g = texture2D(tex0,vec2(uv.x+0.000,-uv.y)).y;
18 | col.b = texture2D(tex0,vec2(uv.x-0.003,-uv.y)).z;
19 |
20 | col = clamp(col*0.5+0.5*col*col*1.2,0.0,1.0);
21 |
22 | col *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y);
23 |
24 | col *= vec3(0.8,1.0,0.7);
25 |
26 | col *= 0.9+0.1*sin(10.0*time+uv.y*1000.0);
27 |
28 | col *= 0.97+0.03*sin(110.0*time);
29 |
30 | float comp = smoothstep( 0.2, 0.7, sin(time) );
31 | col = mix( col, oricol, clamp(-2.0+2.0*q.x+3.0*comp,0.0,1.0) );
32 |
33 | gl_FragColor = vec4(col,1.0);
34 | }
35 |
--------------------------------------------------------------------------------
/tests/real/quaternion.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | float jinteresct(in vec3 rO, in vec3 rD, in vec4 c, out float ao)
9 | {
10 | float mz2,md2,dist,t;
11 | float res=1000.0;
12 | vec4 z,nz;
13 |
14 | ao = 0.0;
15 | for(t=0.0;t<6.0;t+=dist)
16 | {
17 | ao += 1.0;
18 | vec3 p=rO+t*rD;
19 |
20 | // calc distance
21 | z=vec4(p,(c.y+c.x)*.3);
22 | md2=1.0;
23 | mz2=dot(z,z);
24 |
25 | for(int i=0;i<9;i++)
26 | {
27 | // |dz|^2 -> 4*|dz|^2
28 | md2*=4.0*mz2;
29 | // z -> z2 + c
30 | nz.x=z.x*z.x-dot(z.yzw,z.yzw);
31 | nz.yzw=2.0*z.x*z.yzw;
32 | z=nz+c;
33 |
34 | mz2=dot(z,z);
35 | if(mz2>4.0)
36 | break;
37 | }
38 |
39 | dist=0.25*sqrt(mz2/md2)*log(mz2);
40 |
41 | if(dist<0.0005)
42 | {
43 | res=t;
44 | break;
45 | }
46 |
47 | }
48 |
49 | return res;
50 | }
51 |
52 |
53 | vec3 calcNormal(in vec3 p, in vec4 c)
54 | {
55 | vec4 nz,ndz,dz[4];
56 |
57 | vec4 z=vec4(p,(c.y+c.x)*.3);
58 |
59 | dz[0]=vec4(1.0,0.0,0.0,0.0);
60 | dz[1]=vec4(0.0,1.0,0.0,0.0);
61 | dz[2]=vec4(0.0,0.0,1.0,0.0);
62 | //dz[3]=vec4(0.0,0.0,0.0,1.0);
63 |
64 | for(int i=0;i<9;i++)
65 | {
66 | vec4 mz = vec4(z.x,-z.y,-z.z,-z.w);
67 | // derivative
68 | dz[0]=vec4(dot(mz,dz[0]),z.x*dz[0].yzw+dz[0].x*z.yzw);
69 | dz[1]=vec4(dot(mz,dz[1]),z.x*dz[1].yzw+dz[1].x*z.yzw);
70 | dz[2]=vec4(dot(mz,dz[2]),z.x*dz[2].yzw+dz[2].x*z.yzw);
71 | //dz[3]=vec4(dot(mz,dz[3]),z.x*dz[3].yzw+dz[3].x*z.yzw);
72 |
73 | // z = z2 + c
74 | nz.x=dot(z, mz);
75 | nz.yzw=2.0*z.x*z.yzw;
76 | z=nz+c;
77 |
78 | if(dot(z,z)>4.0)
79 | break;
80 | }
81 |
82 | return normalize(vec3(dot(z,dz[0]),dot(z,dz[1]),dot(z,dz[2])));
83 | }
84 |
85 |
86 | void main(void)
87 | {
88 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
89 | vec3 color = vec3(0.0);
90 | vec4 cccc = vec4( .7*cos(.5*time), .7*sin(.3*time), .7*cos(1.0*time), 0.0 );
91 | vec3 edir = normalize(vec3(p,1.0));
92 | vec3 wori = vec3(0.0,0.0,-2.0);
93 |
94 | float ao;
95 | float t = jinteresct(wori,edir,cccc,ao);
96 | if(t<100.0)
97 | {
98 | vec3 inter = wori + t*edir;
99 | vec3 nor = calcNormal(inter,cccc);
100 |
101 | float dif = .5 + .5*dot( nor, vec3(0.57703) );
102 | ao = max( 1.0-ao*0.005, 0.0 );
103 |
104 | color = vec3(1.0,.9,.5)*dif*ao + .5*vec3(.6,.7,.8)*ao;
105 | }
106 | else
107 | {
108 | color = vec3(0.5,0.51,0.52)+vec3(0.5,0.47,0.45)*p.y;
109 | }
110 |
111 | gl_FragColor = vec4(color,1.0);
112 | }
113 |
--------------------------------------------------------------------------------
/tests/real/radial_blur.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform sampler2D tex0;
4 | uniform sampler2D tex1;
5 | uniform sampler2D tex2;
6 | uniform sampler2D tex3;
7 |
8 | vec3 deform( in vec2 p )
9 | {
10 | vec2 uv;
11 |
12 | vec2 q = vec2( sin(1.1*time+p.x),sin(1.2*time+p.y) );
13 |
14 | float a = atan(q.y,q.x);
15 | float r = sqrt(dot(q,q));
16 |
17 | uv.x = sin(0.0+1.0*time)+p.x*sqrt(r*r+1.0);
18 | uv.y = sin(0.6+1.1*time)+p.y*sqrt(r*r+1.0);
19 |
20 | return texture2D(tex0,uv*.5).xyz;
21 | }
22 |
23 | void main(void)
24 | {
25 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
26 | vec2 s = p;
27 |
28 | vec3 total = vec3(0.0);
29 | vec2 d = (vec2(0.0,0.0)-p)/40.0;
30 | float w = 1.0;
31 | for( int i=0; i<40; i++ )
32 | {
33 | vec3 res = deform(s);
34 | res = smoothstep(0.1,1.0,res*res);
35 | total += w*res;
36 | w *= .99;
37 | s += d;
38 | }
39 | total /= 40.0;
40 | float r = 1.5/(1.0+dot(p,p));
41 | gl_FragColor = vec4( total*r,1.0);
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/tests/real/star.frag:
--------------------------------------------------------------------------------
1 | uniform float time;
2 | uniform vec2 resolution;
3 | uniform vec4 mouse;
4 | uniform sampler2D tex0;
5 | uniform sampler2D tex1;
6 | uniform sampler2D tex2;
7 | uniform sampler2D tex3;
8 |
9 | void main(void)
10 | {
11 | vec2 uv;
12 |
13 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
14 | float a = atan(p.y,p.x);
15 | float r = sqrt(dot(p,p));
16 | float s = r * (1.0+0.8*cos(time*1.0));
17 |
18 | uv.x = .02*p.y+.03*cos(-time+a*3.0)/s;
19 | uv.y = .1*time +.02*p.x+.03*sin(-time+a*3.0)/s;
20 |
21 | float w = .9 + pow(max(1.5-r,0.0),4.0);
22 |
23 | w*=0.6+0.4*cos(time+3.0*a);
24 |
25 | vec3 col = texture2D(tex0,uv).xyz;
26 |
27 | gl_FragColor = vec4(col*w,1.0);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/real/sult.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SULT_EXPECTED_
3 | # define SULT_EXPECTED_
4 | # define VAR_resolution "r"
5 | # define VAR_time "y"
6 |
7 | const char *sult_frag =
8 | "vec3 v=vec3(1),n=vec3(0,0,1),x=vec3(0,0,1.5);"
9 | "uniform vec2 r;"
10 | "uniform float y;"
11 | "vec3 rotatey(vec3 v,float y)"
12 | "{"
13 | "return vec3(v.x*cos(y)+v.z*sin(y),v.y,v.z*cos(y)-v.x*sin(y));"
14 | "}"
15 | "float m=0.;"
16 | "float s(vec3 v)"
17 | "{"
18 | "float x=y,c,k;"
19 | "v+=(sin(v.zxy*1.7+x)+sin(v.yzx+x*3.))*.2;"
20 | "k=length(v.xyz*vec3(1,1,.1)-vec3(0,-.1,x*.15-.3))-.34;"
21 | "v.xy=vec2(atan(v.x,v.y)*1.113,1.6-length(v.xy)-sin(x*2.)*.3);"
22 | "c=max(abs(v.y-.3)-.05,abs(length(fract(v.xz)-.5)-.4)-.03);"
23 | "m=step(k,c);"
24 | "return min(min(c,k),v.y-.2);"
25 | "}"
26 | "vec3 diffdark=vec3(.19,.2,.24),k=vec3(1),z=vec3(.45,.01,0),c=vec3(.17,0,0);"
27 | "void main()"
28 | "{"
29 | "vec2 d=-1.+2.*gl_FragCoord.xy/r.xy;"
30 | "vec3 a=normalize(rotatey(rotatey(vec3(d.y*.9,d.x*.9*1.33,1),0.).yxz,(90.+0.*y)*.035)),f=n+x*y;"
31 | "float u=1.,l=0.,g,w,C=0.,F,p,H,G;"
32 | "vec3 E=vec3(.01,0,0),D=E.yyy,B;"
33 | "for(;u>.1;)"
34 | "{"
35 | "for(g=C,w=1.;g<10.&&w>.005;g+=w)"
36 | "w=s(f+a*g);"
37 | "if(g<10.)"
38 | "f+=a*g,F=s(f),H=m,B=normalize(-vec3(F-s(f+E.xyy),F-s(f+E.yxy),F-s(f+E.yyx))),p=clamp(s(f+B*.05)*4.+s(f+B*.1)*2.+.5,.1,1.),l=H*.3,B=normalize(B+step(4.,5.)*m*sin(f.yzx*40.)*.05),a=reflect(a,B),G=clamp(dot(normalize(v),B),0.,1.),B=mix(mix(diffdark,k,G),z*(G+.2),H)+vec3(.7*pow(clamp(dot(normalize(v),a),0.,1.),12.)),D+=u*mix(B*p,c,g/10.),u*=l*(1.-g/10.),C=.1;"
39 | "else"
40 | " D+=u*c,u=0.;"
41 | "}"
42 | "gl_FragColor.xyz=D;"
43 | "gl_FragColor.w=1.;"
44 | "}";
45 |
46 | #endif // SULT_EXPECTED_
47 |
--------------------------------------------------------------------------------
/tests/real/sult.frag:
--------------------------------------------------------------------------------
1 | // Scene from Sult by Loonies
2 | // Exclusive source release for ShaderToy
3 | // Blame the scene chosen on iq ;)
4 | // Feel free to be inspired, but please mention it (.readme) then :)
5 | // -Psycho/Loonies
6 |
7 | // Actual, ugly, size optimized 4k version with minimal changes for ShaderToy
8 | // but before auto-obfuscation (whitespaces, comments, variable names)
9 |
10 | // Inputs changed into more readable constants:
11 | float shaderparm=5.0, fov=.9, pitch=0.0, heading=90.0, dheading=0.0;
12 | vec3 lightdir=vec3(1,1,1), position=vec3(0,0,1), speed=vec3(0,0,1.5);
13 |
14 | // constants for the other worm tunnel part:
15 | //float shaderparm=8, fov=.8, pitch=0, heading=-90, dheading=0;
16 | //vec3 lightdir=vec3(1,1,1), position=vec3(0,0,0), speed=vec3(0,0,0);
17 |
18 | // shadertoy input
19 | uniform vec2 resolution;
20 | uniform float time;
21 |
22 |
23 | vec3 rotatey(vec3 r, float v)
24 | { return vec3(r.x*cos(v)+r.z*sin(v),r.y,r.z*cos(v)-r.x*sin(v));
25 | }
26 | vec3 rotatex(vec3 r, float v)
27 | { return vec3(r.y*cos(v)+r.z*sin(v),r.x,r.z*cos(v)-r.y*sin(v));
28 | }
29 | float mat=0.0, tmax=10.0;
30 | float eval(vec3 p)
31 | {
32 | ////// this is the (only) part that changes for the scenes in Sult
33 | float t = time,r,c=0.0,g,r2,r3;
34 | vec3 pp;
35 | p += ( sin(p.zxy*1.7+t)+sin(p.yzx+t*3.) )*.2;
36 | if (shaderparm<6.0)
37 | c = length(p.xyz*vec3(1,1,.1)-vec3(0,-.1,t*.15-.3))-.34;
38 | else
39 | c = length(p.xy+vec2(.0,.7))-.3+ (sin(p.z*17.0+t*.6)+sin(p.z*2.0)*6.0)*.01;
40 |
41 | p.xy = vec2( atan(p.x,p.y)*1.113, 1.6-length(p.xy)-sin(t*2.0)*.3);
42 | pp = fract(p.xzz+.5).xyz -.5; pp.y=(p.y-.35)*1.3;
43 | r = max( abs(p.y-.3)-.05, abs(length(fract(p.xz)-.5)-.4)-.03);
44 | mat = step(c,r);
45 | return min(min(r,c),p.y-.2);
46 | }
47 | vec3 diffdark= vec3(.19,.2,.24), difflight=vec3(1),
48 | diffrefl= vec3(.45,.01,0), background=vec3(.17,0,0);
49 | //////////
50 |
51 |
52 | void main(void)
53 | {
54 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
55 | vec3 vdir= normalize(
56 | rotatey(rotatey(vec3(p.y*fov,p.x*fov*1.33,1),
57 | -pitch*.035).yxz,(heading+dheading*time)*.035)),
58 | vpos= position + speed*time;
59 |
60 | float cf=1.0,rf=0.0,t,stp,tmin=0.0,c,r,m,d;
61 | vec3 e=vec3(.01,0,0),cx=e.yyy,n;
62 | while (cf>.1)
63 | {
64 | for (t=tmin,stp=1.0;t.005;t+=stp)
65 | stp = eval(vpos+vdir*t);
66 | if (tob(f))"
42 | "v=mix(v,vec4(cos(time*.3)*.5+.5,cos(time*.2)*.5+.5,sin(time*.3)*.5+.5,1),.3);"
43 | "v=(v+vec4(g)+(1.-min(f.y+1.9,1.))*vec4(1,.8,.7,1))*min(time*.5,1.);"
44 | "gl_FragColor=vec4(v.xyz,1);"
45 | "}";
46 |
47 | #endif // TO_THE_ROAD_OF_RIBBON_EXPECTED_
48 |
--------------------------------------------------------------------------------
/tests/real/to_the_road_of_ribbon.frag:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 |
4 | //Object A (tunnel)
5 | float oa(vec3 q)
6 | {
7 | return cos(q.x)+cos(q.y*1.5)+cos(q.z)+cos(q.y*20.)*.05;
8 | }
9 |
10 | //Object B (ribbon)
11 | float ob(vec3 q)
12 | {
13 | return length(max(abs(q-vec3(cos(q.z*1.5)*.3,-.5+cos(q.z)*.2,.0))-vec3(.125,.02,time+3.),vec3(.0)));
14 | }
15 |
16 | //Scene
17 | float o(vec3 q)
18 | {
19 | return min(oa(q),ob(q));
20 | }
21 |
22 | //Get Normal
23 | vec3 gn(vec3 q)
24 | {
25 | vec3 f=vec3(.01,0,0);
26 | return normalize(vec3(o(q+f.xyy),o(q+f.yxy),o(q+f.yyx)));
27 | }
28 |
29 | //MainLoop
30 | void main(void)
31 | {
32 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
33 | p.x *= resolution.x/resolution.y;
34 |
35 | vec4 c=vec4(1.0);
36 | vec3 org=vec3(sin(time)*.5,cos(time*.5)*.25+.25,time),dir=normalize(vec3(p.x*1.6,p.y,1.0)),q=org,pp;
37 | float d=.0;
38 |
39 | //First raymarching
40 | for(int i=0;i<64;i++)
41 | {
42 | d=o(q);
43 | q+=d*dir;
44 | }
45 | pp=q;
46 | float f=length(q-org)*0.02;
47 |
48 | //Second raymarching (reflection)
49 | dir=reflect(dir,gn(q));
50 | q+=dir;
51 | for(int i=0;i<64;i++)
52 | {
53 | d=o(q);
54 | q+=d*dir;
55 | }
56 | c=max(dot(gn(q),vec3(.1,.1,.0)),.0)+vec4(.3,cos(time*.5)*.5+.5,sin(time*.5)*.5+.5,1.)*min(length(q-org)*.04,1.);
57 |
58 | //Ribbon Color
59 | if(oa(pp)>ob(pp))c=mix(c,vec4(cos(time*.3)*.5+.5,cos(time*.2)*.5+.5,sin(time*.3)*.5+.5,1.),.3);
60 |
61 | //Final Color
62 | vec4 fcolor = ((c+vec4(f))+(1.-min(pp.y+1.9,1.))*vec4(1.,.8,.7,1.))*min(time*.5,1.);
63 | gl_FragColor=vec4(fcolor.xyz,1.0);
64 | }
65 |
--------------------------------------------------------------------------------
/tests/real/z_invert.frag.expected:
--------------------------------------------------------------------------------
1 | /* File generated with Shader Minifier 1.1.6
2 | * http://www.ctrl-alt-test.fr
3 | */
4 | #ifndef Z_INVERT_FRAG_EXPECTED_
5 | # define Z_INVERT_FRAG_EXPECTED_
6 | # define VAR_RESOLUTION "s"
7 | # define VAR_TEX0 "y"
8 | # define VAR_TEX1 "o"
9 | # define VAR_TEX2 "r"
10 | # define VAR_TEX3 "z"
11 | # define VAR_TIME "c"
12 |
13 | const char *z_invert_frag =
14 | "uniform vec2 s;"
15 | "uniform float c;"
16 | "uniform sampler2D y,o,r,z;"
17 | "void main()"
18 | "{"
19 | "vec2 r=-1.+2.*gl_FragCoord.xy/s.xy,z;"
20 | "float x=atan(r.y,r.x),o=sqrt(dot(r,r));"
21 | "z.x=cos(.6+c)+cos(cos(1.2+c)+x)/o;"
22 | "z.y=cos(.3+c)+sin(cos(2.+c)+x)/o;"
23 | "vec3 f=texture2D(y,z*.25).xyz;"
24 | "gl_FragColor=vec4(f*o*o,1.);"
25 | "}";
26 |
27 | #endif // Z_INVERT_FRAG_EXPECTED_
28 |
--------------------------------------------------------------------------------
/tests/shadertoy.h.glsl:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec3 iResolution;
4 | uniform float iTime;
5 | uniform float iTimeDelta;
6 | uniform int iFrame;
7 | uniform float iChannelTime[4];
8 | uniform vec3 iChannelResolution[4];
9 | uniform vec4 iMouse;
10 | uniform vec4 iDate;
11 | uniform float iSampleRate;
12 |
13 | uniform sampler2D iChannel0;
14 | uniform sampler2D iChannel1;
15 | uniform sampler2D iChannel2;
16 | uniform sampler2D iChannel3;
17 |
18 | // hack: make all samplers sampler2D
19 | // ( real shadertoy.com iChanneln declarations depend on channel settings )
20 | #define samplerCube sampler2D
21 | vec4 _shadertoy_h_texture(sampler2D s,vec2 v){return vec4(0);}
22 | vec4 _shadertoy_h_texture(sampler2D s,vec2 v,float b){return vec4(0);}
23 | vec4 _shadertoy_h_texture(sampler2D s,vec3 v){return vec4(0);}
24 | #define texture _shadertoy_h_texture
25 |
26 | void mainImage (out vec4 O, vec2 f);
27 | out vec4 shadertoy_out_color;
28 | void main () {
29 | mainImage(shadertoy_out_color,gl_FragCoord.xy);
30 | }
31 |
--------------------------------------------------------------------------------
/tests/unit/1.simple.frag:
--------------------------------------------------------------------------------
1 | void main()
2 | {
3 | gl_FragColor = vec4(0.2, 0.4, 0.6, 0.);
4 | }
5 |
--------------------------------------------------------------------------------
/tests/unit/2.simple.frag:
--------------------------------------------------------------------------------
1 | void main()
2 | {
3 | gl_FragColor = vec4(0.2, 0.4, 0.6, 0.);
4 | }
5 |
--------------------------------------------------------------------------------
/tests/unit/2.simple.opt.frag:
--------------------------------------------------------------------------------
1 | void main(){gl_FragColor=vec4(.2,.4,.6,0.);}
--------------------------------------------------------------------------------
/tests/unit/arg-inlining.expected:
--------------------------------------------------------------------------------
1 | #version 300 es
2 |
3 | precision highp float;
4 | float noinline_canInlineWhenResolvable()
5 | {
6 | return 11.;
7 | }
8 | float noinline_cannotInlineWhenNotResolvable(float a)
9 | {
10 | return a+11.;
11 | }
12 | float noinline_cannotInlineWhenNotResolvable(vec2 a)
13 | {
14 | return length(a)+11.;
15 | }
16 | float noinline_canInlineWhenInParameter()
17 | {
18 | return 21.;
19 | }
20 | float noinline_cannotInlineWhenOutParameter(out float a)
21 | {
22 | return a+21.;
23 | }
24 | float noinline_cannotInlineWhenInOutParameter(inout float a)
25 | {
26 | return a+22.;
27 | }
28 | float noinline_canInlineWhenArgIsAlwaysTheSame()
29 | {
30 | return 31.;
31 | }
32 | float noinline_cannotInlineWhenArgsAreDifferent(float a)
33 | {
34 | return a+31.;
35 | }
36 | float noinline_canInlineWhenArgIsInlinable1()
37 | {
38 | return 20.;
39 | }
40 | float noinline_canInlineWhenArgIsInlinable2()
41 | {
42 | return float(-18)+40.;
43 | }
44 | float noinline_canInlineWhenArgIsInlinable3()
45 | {
46 | return 496.;
47 | }
48 | float noinline_canInlineWhenArgIsInlinable4()
49 | {
50 | return vec3(9).x;
51 | }
52 | float noinline_canInlineWhenArgIsInlinable5()
53 | {
54 | return acos(-1.)+40.;
55 | }
56 | float noinline_canInlineWhenArgIsInlinable6()
57 | {
58 | return 1./3.+40.;
59 | }
60 | float noinline_cannotInlineWhenArgIsNotInlinable(float a)
61 | {
62 | return a+41.;
63 | }
64 | float f()
65 | {
66 | float s=0.;
67 | s+=s+noinline_canInlineWhenResolvable();
68 | s+=s+noinline_cannotInlineWhenNotResolvable(1.);
69 | s+=s+noinline_canInlineWhenInParameter();
70 | s+=s+noinline_cannotInlineWhenOutParameter(s);
71 | s+=s+noinline_cannotInlineWhenInOutParameter(s);
72 | s+=s+noinline_canInlineWhenArgIsAlwaysTheSame();
73 | s+=s+noinline_cannotInlineWhenArgsAreDifferent(1.);
74 | s+=s+noinline_cannotInlineWhenArgsAreDifferent(2.);
75 | s+=s+noinline_canInlineWhenArgIsInlinable1();
76 | s+=s+noinline_canInlineWhenArgIsInlinable2();
77 | s+=s+noinline_canInlineWhenArgIsInlinable3();
78 | s+=s+noinline_canInlineWhenArgIsInlinable4();
79 | s+=s+noinline_canInlineWhenArgIsInlinable5();
80 | s+=s+noinline_canInlineWhenArgIsInlinable6();
81 | s+=s+noinline_cannotInlineWhenArgIsNotInlinable(s);
82 | return s+s+noinline_cannotInlineWhenArgIsNotInlinable(acos(s));
83 | }
84 | out vec4 fragColor;
85 | uniform sampler2D samp;
86 | vec3 dof()
87 | {
88 | float f=10.;
89 | for(;;)
90 | {
91 | vec3 a=texture(samp,vec2(0)).xyz;
92 | return a.zyx+a.xyz*(f*=f);
93 | }
94 | }
95 | void main()
96 | {
97 | f();
98 | fragColor.xyz=dof();
99 | }
100 |
--------------------------------------------------------------------------------
/tests/unit/arg-inlining.frag:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | // Argument inlining inlines the argument of a function call into the function body.
5 |
6 | float noinline_canInlineWhenResolvable(float a) { return a+10.; }
7 | float noinline_cannotInlineWhenNotResolvable(float a) { return a+11.; }
8 | float noinline_cannotInlineWhenNotResolvable(vec2 a) { return length(a)+11.; }
9 |
10 | float noinline_canInlineWhenInParameter(in float a) { return a+20.; }
11 | float noinline_cannotInlineWhenOutParameter(out float a) { return a+21.; }
12 | float noinline_cannotInlineWhenInOutParameter(inout float a) { return a+22.; }
13 |
14 | float noinline_canInlineWhenArgIsAlwaysTheSame(float a) { return a+30.; }
15 | float noinline_cannotInlineWhenArgsAreDifferent(float a) { return a+31.; }
16 |
17 | float noinline_canInlineWhenArgIsInlinable1(bool a) { return a?20.:40.; }
18 | float noinline_canInlineWhenArgIsInlinable2(int a) { return float(a)+40.; }
19 | float noinline_canInlineWhenArgIsInlinable3(float a) { return a+40.; }
20 | float noinline_canInlineWhenArgIsInlinable4(vec3 a) { return a.x; }
21 | float noinline_canInlineWhenArgIsInlinable5(float a) { return a+40.; }
22 | float noinline_canInlineWhenArgIsInlinable6(float a) { return a+40.; }
23 | float noinline_cannotInlineWhenArgIsNotInlinable(float a) { return a+41.; }
24 |
25 | float f()
26 | {
27 | float s = 0.;
28 |
29 | s += s + noinline_canInlineWhenResolvable(1.);
30 | s += s + noinline_cannotInlineWhenNotResolvable(1.);
31 |
32 | s += s + noinline_canInlineWhenInParameter(1.);
33 | s += s + noinline_cannotInlineWhenOutParameter(s);
34 | s += s + noinline_cannotInlineWhenInOutParameter(s);
35 |
36 | s += s + noinline_canInlineWhenArgIsAlwaysTheSame(1.);
37 | s += s + noinline_cannotInlineWhenArgsAreDifferent(1.);
38 | s += s + noinline_cannotInlineWhenArgsAreDifferent(2.);
39 |
40 | s += s + noinline_canInlineWhenArgIsInlinable1(true);
41 | s += s + noinline_canInlineWhenArgIsInlinable2(-18);
42 | s += s + noinline_canInlineWhenArgIsInlinable3(456.0);
43 | s += s + noinline_canInlineWhenArgIsInlinable4(vec3(9));
44 | s += s + noinline_canInlineWhenArgIsInlinable5(acos(-1.));
45 | s += s + noinline_canInlineWhenArgIsInlinable6(1./3.);
46 | s += s + noinline_cannotInlineWhenArgIsNotInlinable(s);
47 | s += s + noinline_cannotInlineWhenArgIsNotInlinable(acos(s));
48 |
49 | return s;
50 | }
51 |
52 |
53 | // sampler types are immutable and cannot be locals, they must always be inlined (#496)
54 | out vec4 fragColor;
55 | uniform sampler2D samp;
56 | vec3 dof(sampler2D tex, float f) {
57 | for (;;) {
58 | vec3 a = texture(tex,vec2(0)).rgb;
59 | return a.zyx+a.xyz*(f*=f);
60 | }
61 | }
62 |
63 |
64 | void main()
65 | {
66 | f();
67 | fragColor.xyz = dof(samp, 10.0);
68 | }
69 |
--------------------------------------------------------------------------------
/tests/unit/array.frag:
--------------------------------------------------------------------------------
1 | #version 430
2 |
3 | float a[3+2] = float[5](3.4, 4.2, 5.0, 5.2, 1.1);
4 |
5 | const int size = 5;
6 | float b[size] = float[size](3.4, 4.2, 5.0, 5.2, 1.1);
7 |
8 | float c[] = float[](3.4, 4.2, 5.0, 5.2, 1.1);
9 | float d[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1);
10 | float e[] = float[5](3.4, 4.2, 5.0, 5.2, 1.1);
11 |
12 | void arrayTypes() {
13 | vec4 a[3];
14 | vec4[2] b[3];
15 | vec4[3] c;
16 |
17 | int code[] = int[1](123);
18 | }
19 |
20 | float[2]func_bank(in float[2]res)
21 | {
22 | float a = res[0], b = res[1];
23 | res[0] = a < b ? a : b; // min
24 | res[1] = a > b ? a : b; // max
25 | return res;
26 | }
27 |
28 | float f(float x)
29 | {
30 | float[2] test = float[](5., 7.);
31 | return func_bank(test)[0] == 5 && func_bank(test)[1] == 7
32 | ? x : x*x;
33 | }
34 |
35 | out vec4 fragColor;
36 | void main() {
37 | float[4] array = float[](1.,2.,3.,4.);
38 | fragColor = vec4(array.length());
39 | }
40 |
--------------------------------------------------------------------------------
/tests/unit/array.frag.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef ARRAY_FRAG_EXPECTED_
3 | # define ARRAY_FRAG_EXPECTED_
4 |
5 | const char *array_frag =
6 | "#version 430\n"
7 | "float a[5]=float[5](3.4,4.2,5.,5.2,1.1),b[5]=float[5](3.4,4.2,5.,5.2,1.1),c[]=float[](3.4,4.2,5.,5.2,1.1),d[5]=float[](3.4,4.2,5.,5.2,1.1),e[]=float[5](3.4,4.2,5.,5.2,1.1);"
8 | "void arrayTypes()"
9 | "{}"
10 | "float[2] func_bank(float[2] res)"
11 | "{"
12 | "float a=res[0],b=res[1];"
13 | "res[0]=ab?"
17 | "a:"
18 | "b;"
19 | "return res;"
20 | "}"
21 | "float f(float x)"
22 | "{"
23 | "float[2] test=float[](5.,7.);"
24 | "return func_bank(test)[0]==5&&func_bank(test)[1]==7?"
25 | "x:"
26 | "x*x;"
27 | "}"
28 | "out vec4 fragColor;"
29 | "void main()"
30 | "{"
31 | "fragColor=vec4(4);"
32 | "}";
33 |
34 | #endif // ARRAY_FRAG_EXPECTED_
35 |
--------------------------------------------------------------------------------
/tests/unit/augmented.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #extension GL_EXT_gpu_shader4 : enable
4 |
5 | int foo(int x, int y) {
6 | int a=x;
7 | a=a+x;
8 | a=a*y;
9 | a=a>>x;
10 | a=a^y;
11 | a=a|y;
12 | return a;
13 | }
14 |
15 | int outputvar;
16 |
17 | void main() {
18 | outputvar = foo(0, 0);
19 | }
20 |
--------------------------------------------------------------------------------
/tests/unit/augmented.frag.expected:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #extension GL_EXT_gpu_shader4:enable
4 |
5 | int foo(int x,int y)
6 | {
7 | return(x+x)*y>>x^y|y;
8 | }
9 | int outputvar;
10 | void main()
11 | {
12 | outputvar=foo(0,0);
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/blocks.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef BLOCKS_EXPECTED_
3 | # define BLOCKS_EXPECTED_
4 |
5 | const char *blocks_frag =
6 | "float test_if()"
7 | "{"
8 | "int foo=2;"
9 | "float bar;"
10 | "if(foo==2)"
11 | "foo++;"
12 | "return foo<5?"
13 | "foo==3?"
14 | ".2:"
15 | ".3:"
16 | ".4;"
17 | "}"
18 | "int k=5;"
19 | "float test_for()"
20 | "{"
21 | "int foo=2,n=0;"
22 | "for(int i=0;i<4;i++)"
23 | "foo+=i;"
24 | "for(foo++;n<4;n++)"
25 | "{"
26 | "int k=n-1;"
27 | "foo+=k;"
28 | "}"
29 | "return 1./float(k);"
30 | "}"
31 | "int test_block()"
32 | "{"
33 | "for(int i=0;i<2;i++)"
34 | "{"
35 | "if(k==1)"
36 | "return k++,2;"
37 | "break;"
38 | "}"
39 | "}"
40 | "float removeUselessElseAfterReturn1(float f)"
41 | "{"
42 | "if(f<2.)"
43 | "return 1.;"
44 | "f=4.;"
45 | "return 5.;"
46 | "}"
47 | "float removeUselessElseAfterReturn2(float f)"
48 | "{"
49 | "float a=2.;"
50 | "if(f 0.0)
63 | r = sideEffect(1);
64 | else
65 | r = sideEffect(2);
66 | float r2;
67 | if (f > 1.0) {
68 | r2 = sideEffect(1);
69 | } else {
70 | sideEffect(99);
71 | r2 = sideEffect(2);
72 | }
73 | float r3;
74 | if (f > 1.0) {
75 | r3 = sideEffect(1);
76 | } else {
77 | r3 = sideEffect(2);
78 | sideEffect(99);
79 | }
80 | return r+r2+r3;
81 | }
82 |
83 | // Move-declarations bug (#458)
84 | uniform int A;
85 | uniform int B;
86 | vec4 O;
87 | void main() {
88 | O = vec4(0);
89 | float f = 1;
90 | if (B < 2) f = A;
91 | {
92 | float n = A + 1;
93 | if (B < 1) O.y=1;
94 | float f = f * n + n * n;
95 | O.x=f;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/tests/unit/conditionals.frag.expected:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | int noinlinevar;
4 | bool success()
5 | {
6 | noinlinevar++;
7 | return true;
8 | }
9 | bool fail()
10 | {
11 | noinlinevar++;
12 | return false;
13 | }
14 | bool ternary()
15 | {
16 | return success();
17 | }
18 | bool ternary2()
19 | {
20 | return success();
21 | }
22 | bool or()
23 | {
24 | return true;
25 | }
26 | bool or2()
27 | {
28 | return success();
29 | }
30 | bool or3()
31 | {
32 | return success();
33 | }
34 | bool and()
35 | {
36 | return success();
37 | }
38 | bool and2()
39 | {
40 | return false;
41 | }
42 | bool and3()
43 | {
44 | return success();
45 | }
46 | int foo()
47 | {
48 | return 1;
49 | }
50 | int glo;
51 | int sideEffect(int n)
52 | {
53 | return glo+=n;
54 | }
55 | float ifStmtToExpr(float f)
56 | {
57 | float r=f>0.?
58 | sideEffect(1):
59 | sideEffect(2),r2=f>1.?
60 | sideEffect(1):
61 | (sideEffect(99),sideEffect(2)),r3;
62 | if(f>1.)
63 | r3=sideEffect(1);
64 | else
65 | r3=sideEffect(2),sideEffect(99);
66 | return r+r2+r3;
67 | }
68 | uniform int A,B;
69 | vec4 O;
70 | void main()
71 | {
72 | O=vec4(0);
73 | float f=1;
74 | if(B<2)
75 | f=A;
76 | {
77 | float n=A+1;
78 | if(B<1)
79 | O.y=1;
80 | n=f*n+n*n;
81 | O.x=n;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/tests/unit/deadcode.frag:
--------------------------------------------------------------------------------
1 | int f(int x) {
2 | #if FOO
3 | return x;
4 | #else
5 | return x + 2;
6 | #endif
7 | }
8 |
9 | void main() {
10 | int a = 2;
11 | f(a);
12 | return;
13 | f(a + 1);
14 | }
15 |
--------------------------------------------------------------------------------
/tests/unit/deadcode.frag.expected:
--------------------------------------------------------------------------------
1 | int f()
2 | {
3 |
4 | #if FOO
5 |
6 | return 2;
7 |
8 | #else
9 |
10 | return 4;
11 |
12 | #endif
13 |
14 | }
15 | void main()
16 | {
17 | f();
18 | return;
19 | }
20 |
--------------------------------------------------------------------------------
/tests/unit/decimals.frag:
--------------------------------------------------------------------------------
1 | //NOCOMPILE
2 | void test () {
3 | x(3.141592653589793);
4 | x(3.1415927);
5 | //x(1e308);
6 | //x(3e38);
7 | //x(1e37);
8 | x(1e28);
9 | x(125.663704/180.);
10 | x(.6981316889);
11 | x(100000005.);
12 | x(1.24e27);
13 | x(1.20e27);
14 | x(1.00e27);
15 | x(1.24e4);
16 | x(1.20e4);
17 | x(1.00e4);
18 | x(1.24e3);
19 | x(1.20e3);
20 | x(1.00e3);
21 | x(1.24e2);
22 | x(1.20e2);
23 | x(1.00e2);
24 | x(1.24e1);
25 | x(1.20e1);
26 | x(1.00e1);
27 | x(1.24e0);
28 | x(1.20e0);
29 | x(1.00e0);
30 | x(1.24e-1);
31 | x(1.20e-1);
32 | x(1.00e-1);
33 | x(1.24e-2);
34 | x(1.20e-2);
35 | x(1.00e-2);
36 | x(1.24e-3);
37 | x(1.20e-3);
38 | x(1.00e-3);
39 | x(1.24e-4);
40 | x(1.20e-4);
41 | x(1.00e-4);
42 | x(1.24e-27);
43 | x(1.20e-27);
44 | x(1.00e-27);
45 | x(6e-29);
46 | x(8e-46);
47 | //x(3e-324);
48 | }
49 |
--------------------------------------------------------------------------------
/tests/unit/decimals.frag.expected:
--------------------------------------------------------------------------------
1 | void test()
2 | {
3 | x(acos(-1.));
4 | x(3.1415927);
5 | x(1e28);
6 | x(125.663704/180.);
7 | x(.6981316889);
8 | x(100000005.);
9 | x(124e25);
10 | x(12e26);
11 | x(1e27);
12 | x(124e2);
13 | x(12e3);
14 | x(1e4);
15 | x(1240.);
16 | x(12e2);
17 | x(1e3);
18 | x(124.);
19 | x(120.);
20 | x(1e2);
21 | x(12.4);
22 | x(12.);
23 | x(10.);
24 | x(1.24);
25 | x(1.2);
26 | x(1.);
27 | x(.124);
28 | x(.12);
29 | x(.1);
30 | x(.0124);
31 | x(.012);
32 | x(.01);
33 | x(.00124);
34 | x(.0012);
35 | x(.001);
36 | x(124e-6);
37 | x(12e-5);
38 | x(1e-4);
39 | x(0.);
40 | x(0.);
41 | x(0.);
42 | x(0.);
43 | x(0.);
44 | }
45 |
--------------------------------------------------------------------------------
/tests/unit/empty_block.frag:
--------------------------------------------------------------------------------
1 | void more_semicolons(){}
2 |
3 | int f() {
4 | int x = 5;
5 | int y = 7;
6 |
7 | if (x < 3) {
8 | return 2;
9 | } else {;}
10 |
11 | if (x == 5) {
12 | ;
13 | } else {}
14 |
15 | if (y == 1); else;
16 |
17 | more_semicolons();;;
18 | return 3;
19 | }
20 |
--------------------------------------------------------------------------------
/tests/unit/externals.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef EXTERNALS_EXPECTED_
3 | # define EXTERNALS_EXPECTED_
4 | # define VAR_e "I"
5 | # define VAR_i "i"
6 | # define VAR_n "J"
7 |
8 | const char *externals_frag =
9 | "uniform int i,J,I;"
10 | "int H()"
11 | "{"
12 | "return i;"
13 | "}"
14 | "int G()"
15 | "{"
16 | "return J;"
17 | "}"
18 | "int F()"
19 | "{"
20 | "return I;"
21 | "}";
22 |
23 | #endif // EXTERNALS_EXPECTED_
24 |
--------------------------------------------------------------------------------
/tests/unit/externals.frag:
--------------------------------------------------------------------------------
1 | uniform int i, n, e;
2 |
3 | int f() {
4 | int var1, var2, var3, var4, var5;
5 | return i;
6 | }
7 |
8 | int g() {
9 | int var1, var2, var3, var4, var5;
10 | return n;
11 | }
12 |
13 | int h() {
14 | int var1, var2, var3, var4, var5;
15 | return e;
16 | }
17 |
--------------------------------------------------------------------------------
/tests/unit/externals.preserved.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef EXTERNALS_PRESERVED_EXPECTED_
3 | # define EXTERNALS_PRESERVED_EXPECTED_
4 |
5 | const char *externals_frag =
6 | "uniform int i,n,e;"
7 | "int H()"
8 | "{"
9 | "return i;"
10 | "}"
11 | "int G()"
12 | "{"
13 | "return n;"
14 | "}"
15 | "int F()"
16 | "{"
17 | "return e;"
18 | "}";
19 |
20 | #endif // EXTERNALS_PRESERVED_EXPECTED_
21 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag:
--------------------------------------------------------------------------------
1 | // maybe the real test data was the file name we made along the way
2 | void main() { gl_FragColor = vec4(0.33, 0.66, 0.99, 1.); }
3 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag.c-variables.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef FILE_NAME_WITH_WEIRD_CARACT_RES_FRAG_C_VARIABLES_EXPECTED_
3 | # define FILE_NAME_WITH_WEIRD_CARACT_RES_FRAG_C_VARIABLES_EXPECTED_
4 |
5 | const char *file_name_with_weird_caract_res_frag =
6 | "void main()"
7 | "{"
8 | "gl_FragColor=vec4(.33,.66,.99,1);"
9 | "}";
10 |
11 | #endif // FILE_NAME_WITH_WEIRD_CARACT_RES_FRAG_C_VARIABLES_EXPECTED_
12 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag.js.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 |
3 | var file_name_with_weird_caractères_frag = `void main(){gl_FragColor=vec4(.33,.66,.99,1);}`
4 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag.json.expected:
--------------------------------------------------------------------------------
1 | {"mappings":{},"shaders":{"tests/unit/file name with-weird caractères.frag":"void main(){gl_FragColor=vec4(.33,.66,.99,1);}"}}
2 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag.nasm.expected:
--------------------------------------------------------------------------------
1 | ; Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 |
3 | _file_name_with_weird_caract_res_frag:
4 | db 'void main()'
5 | db '{'
6 | db 'gl_FragColor=vec4(.33,.66,.99,1);'
7 | db '}', 0
8 |
--------------------------------------------------------------------------------
/tests/unit/file name with-weird caractères.frag.rust.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 |
3 | pub const FILE_NAME_WITH_WEIRD_CARACTÈRES_FRAG: &'static [u8] = b"\
4 | void main()\
5 | {\
6 | gl_FragColor=vec4(.33,.66,.99,1);\
7 | }\0";
8 |
--------------------------------------------------------------------------------
/tests/unit/float.frag:
--------------------------------------------------------------------------------
1 | float floatPrecision(float x) {
2 | float a = 0.00000012345;
3 | float b = 1.234567891234;
4 | float c = 1234567.891234;
5 | float d = 123456700000000.;
6 | return a*x+b*x+c*x+d*x;
7 | }
8 |
9 | float largeNumbers(float x) {
10 | float a = 4.1e8;
11 | float b = 4.2e10;
12 | float c = 4.3e12;
13 | float d = 4.4e14;
14 | return a*x+b*x+c*x+d*x;
15 | }
16 |
17 | float smallNumbers(float x) {
18 | float a = 4e-1;
19 | float b = 4e-2;
20 | float c = 4e-3;
21 | float d = 4e-4;
22 | float e = 4e-8;
23 | float f = 4e-10;
24 | float g = 4e-12;
25 | float h = 4e-14;
26 | return a*x+b*x+c*x+d*x+e*x+f*x+g*x+h*x;
27 | }
28 |
29 | float zero(float x) {
30 | float a = 0.;
31 | float b = .0;
32 | float c = -.0;
33 | return a*x+b*x+c*x;
34 | }
35 |
36 | float x;
37 |
38 | void main()
39 | {
40 | float f1 = 1.5;
41 | float f2 = .0000003;
42 | float f3 = .42;
43 | float f6 = -2e-3;
44 | float f7 = 2E-9;
45 | float f8 = 2E+6;
46 | float f9 = 2e10;
47 |
48 | gl_FragColor=vec4(f1*x+f2*x+f3*x+f6*x+f7*x+f8*x+f9*x);
49 | }
50 |
--------------------------------------------------------------------------------
/tests/unit/float.frag.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | #endif
6 |
7 | #else // if SHADER_MINIFIER_IMPL
8 |
9 | // tests/unit/float.frag
10 | "float floatPrecision(float x)"
11 | "{"
12 | "float a=12345e-11,b=1.234567891234,c=1234567.891234,d=1234567e8;"
13 | "return a*x+b*x+c*x+d*x;"
14 | "}"
15 | "float largeNumbers(float x)"
16 | "{"
17 | "float a=41e7,b=42e9,c=43e11,d=44e13;"
18 | "return a*x+b*x+c*x+d*x;"
19 | "}"
20 | "float smallNumbers(float x)"
21 | "{"
22 | "float a=.4,b=.04,c=.004,d=4e-4,e=4e-8,f=4e-10,g=4e-12,h=4e-14;"
23 | "return a*x+b*x+c*x+d*x+e*x+f*x+g*x+h*x;"
24 | "}"
25 | "float zero(float x)"
26 | "{"
27 | "float a=0.,b=0.,c=0.;"
28 | "return a*x+b*x+c*x;"
29 | "}"
30 | "float x;"
31 | "void main()"
32 | "{"
33 | "float f1=1.5,f2=3e-7,f3=.42,f6=-.002,f7=2e-9,f8=2e6,f9=2e10;"
34 | "gl_FragColor=vec4(f1*x+f2*x+f3*x+f6*x+f7*x+f8*x+f9*x);"
35 | "}",
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/tests/unit/forbidden.expected:
--------------------------------------------------------------------------------
1 | struct L{float t;};
2 | float K()
3 | {
4 | return 42.;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/unit/forbidden.frag:
--------------------------------------------------------------------------------
1 | struct f {
2 | float f;
3 | };
4 |
5 | float someFun() {
6 | return 42.0;
7 | }
8 |
--------------------------------------------------------------------------------
/tests/unit/forward_declaration.frag:
--------------------------------------------------------------------------------
1 | void a();
2 | void b();
3 | void c();
4 | void d();
5 |
6 | void a() {
7 | b();
8 | }
9 |
10 | void b() {
11 | c();
12 | d();
13 | }
14 |
15 | void e() {
16 | a();
17 | c();
18 | }
19 |
20 | int x;
21 | void c() {x++;}
22 |
23 | void d() {x++;}
24 |
--------------------------------------------------------------------------------
/tests/unit/forward_declaration.frag.expected:
--------------------------------------------------------------------------------
1 | int x;
2 | void c()
3 | {
4 | x++;
5 | }
6 | void d()
7 | {
8 | x++;
9 | }
10 | void b()
11 | {
12 | c();
13 | d();
14 | }
15 | void a()
16 | {
17 | b();
18 | }
19 | void e()
20 | {
21 | a();
22 | c();
23 | }
24 |
--------------------------------------------------------------------------------
/tests/unit/function_comma.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef FUNCTION_COMMA_EXPECTED_
3 | # define FUNCTION_COMMA_EXPECTED_
4 |
5 | const char *function_comma_frag =
6 | "float min(float a,float b)"
7 | "{"
8 | "return a OutputStream )
7 | {
8 | PSSceneIn output = (PSSceneIn)0;
9 | int n = //[3.14159265358979323846264338327950288419716939937510//];
10 | for( uint i=0; i<6; i+=2 )
11 | {
12 | output.Pos = input[i].Pos;
13 | output.Norm = input[i].Norm;
14 | output.Tex = input[i].Tex;
15 |
16 | OutputStream.Append( output );
17 | }
18 |
19 | OutputStream.RestartStrip();
20 | }
21 |
--------------------------------------------------------------------------------
/tests/unit/geometry.hlsl.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef GEOMETRY_HLSL_EXPECTED_
3 | # define GEOMETRY_HLSL_EXPECTED_
4 |
5 | const char *geometry_hlsl =
6 | "[maxvertexcount(3)]\n"
7 | "void GSScene(triangleadj GSSceneIn input[6],inout TriangleStream OutputStream)"
8 | "{"
9 | "PSSceneIn output=(PSSceneIn)0;"
10 | "int n=3.14159265358979323846264338327950288419716939937510;"
11 | "for(uint i=0;i<6;i+=2)"
12 | "output.Pos=input[i].Pos,output.Norm=input[i].Norm,output.Tex=input[i].Tex,OutputStream.Append(output);"
13 | "OutputStream.RestartStrip();"
14 | "}";
15 |
16 | #endif // GEOMETRY_HLSL_EXPECTED_
17 |
--------------------------------------------------------------------------------
/tests/unit/hexa.frag:
--------------------------------------------------------------------------------
1 | void main()
2 | {
3 | float n = float(0xff) / 1000.;
4 | float o = float(-0XFF) / 1000.;
5 | float p = n - o + float(4 * 0x0);
6 | gl_FragColor=vec4(.2,.4,n,0.);
7 | }
8 |
--------------------------------------------------------------------------------
/tests/unit/inline-aggro.aggro.expected:
--------------------------------------------------------------------------------
1 | #version 150
2 |
3 | float inl1()
4 | {
5 | return 126.;
6 | }
7 | float inl2(float x)
8 | {
9 | return x>246913578.?
10 | 1e2:
11 | x>123456789.?
12 | 101.:
13 | 102.;
14 | }
15 | float inl3()
16 | {
17 | return 2.*acos(-1.)*.75;
18 | }
19 | float inl4()
20 | {
21 | return 2.*acos(-1.)*.75;
22 | }
23 | float inl5()
24 | {
25 | return 579.;
26 | }
27 | const float baz=2.*acos(-1.);
28 | float inl6()
29 | {
30 | return 2.*baz;
31 | }
32 | float notevil(float y)
33 | {
34 | return 42.+(y*=y);
35 | }
36 | float inl7(float u)
37 | {
38 | return 101.+notevil(u);
39 | }
40 | int inl8(ivec3 x)
41 | {
42 | x[1]+=1;
43 | return x[1]+1;
44 | }
45 | float noinl1()
46 | {
47 | return 101.;
48 | }
49 | float noinl2()
50 | {
51 | float f=42.;
52 | f++;
53 | return f;
54 | }
55 | float noinl3()
56 | {
57 | float f=42.;
58 | if(acos(-1.)<3.)
59 | f=101.;
60 | return f;
61 | }
62 | float noinl4()
63 | {
64 | float f=42.;
65 | for(f=0.;false;)
66 | ;
67 | return f;
68 | }
69 | float noinl5()
70 | {
71 | float f=42.;
72 | for(;false;f++)
73 | ;
74 | return f;
75 | }
76 | float noinl6(float x)
77 | {
78 | float f=x+1.;
79 | x=1e2;
80 | return f+2.;
81 | }
82 | float noinl7(const float x)
83 | {
84 | return x+1.2;
85 | }
86 | float noinl8()
87 | {
88 | return 3.;
89 | }
90 | float noinl9(float x)
91 | {
92 | float bar=x+1.;
93 | x=1e2;
94 | return bar+2.;
95 | }
96 | void evil(inout float x)
97 | {
98 | x=42.;
99 | }
100 | float noinl10()
101 | {
102 | float f=101.;
103 | evil(f);
104 | return f;
105 | }
106 | int noinl11(ivec3 x)
107 | {
108 | int i=1;
109 | x[i++]+=1;
110 | return x[i]+i;
111 | }
112 | int noinl12()
113 | {
114 | int i=10;
115 | for(;--i>0;)
116 | ;
117 | return 1;
118 | }
119 |
--------------------------------------------------------------------------------
/tests/unit/inline-aggro.expected:
--------------------------------------------------------------------------------
1 | #version 150
2 |
3 | float inl1()
4 | {
5 | return 126.;
6 | }
7 | float inl2(float x)
8 | {
9 | return x>246913578.?
10 | 1e2:
11 | x>123456789.?
12 | 101.:
13 | 102.;
14 | }
15 | float inl3()
16 | {
17 | return 2.*acos(-1.)*.75;
18 | }
19 | float inl4()
20 | {
21 | return 2.*acos(-1.)*.75;
22 | }
23 | float inl5()
24 | {
25 | return 579.;
26 | }
27 | const float bar=acos(-1.),baz=2.*bar;
28 | float inl6()
29 | {
30 | return 2.*baz;
31 | }
32 | float notevil(float y)
33 | {
34 | return 42.+(y*=y);
35 | }
36 | float inl7(float u)
37 | {
38 | return 101.+notevil(u);
39 | }
40 | int inl8(ivec3 x)
41 | {
42 | x[1]+=1;
43 | return x[1]+1;
44 | }
45 | float noinl1()
46 | {
47 | return 101.;
48 | }
49 | float noinl2()
50 | {
51 | float f=42.;
52 | f++;
53 | return f;
54 | }
55 | float noinl3()
56 | {
57 | float f=42.;
58 | if(acos(-1.)<3.)
59 | f=101.;
60 | return f;
61 | }
62 | float noinl4()
63 | {
64 | float f=42.;
65 | for(f=0.;false;)
66 | ;
67 | return f;
68 | }
69 | float noinl5()
70 | {
71 | float f=42.;
72 | for(;false;f++)
73 | ;
74 | return f;
75 | }
76 | float noinl6(float x)
77 | {
78 | float f=x+1.;
79 | x=1e2;
80 | return f+2.;
81 | }
82 | float noinl7(const float x)
83 | {
84 | return x+1.2;
85 | }
86 | float noinl8()
87 | {
88 | return 3.;
89 | }
90 | float noinl9(float x)
91 | {
92 | float bar=x+1.;
93 | x=1e2;
94 | return bar+2.;
95 | }
96 | void evil(inout float x)
97 | {
98 | x=42.;
99 | }
100 | float noinl10()
101 | {
102 | float f=101.;
103 | evil(f);
104 | return f;
105 | }
106 | int noinl11(ivec3 x)
107 | {
108 | int i=1;
109 | x[i++]+=1;
110 | return x[i]+i;
111 | }
112 | int noinl12()
113 | {
114 | int i=10;
115 | for(;--i>0;)
116 | ;
117 | return 1;
118 | }
119 |
--------------------------------------------------------------------------------
/tests/unit/inline-aggro.frag:
--------------------------------------------------------------------------------
1 | #version 150
2 |
3 | // *** Things we should inline
4 |
5 | float inl1() {
6 | float f = 42.0;
7 | float g = 2.0 * f;
8 | return f + g;
9 | }
10 |
11 | float inl2(float x) {
12 | float f = 123456789.0;
13 | if (x > 2.0*f) return 100.0;
14 | if (x > f) return 101.0;
15 | return 102.0;
16 | }
17 |
18 | float inl3() {
19 | const float f = acos(-1.0);
20 | const float g = 2.0*f;
21 | return 0.75*g;
22 | }
23 |
24 | float inl4() {
25 | const float f = acos(-1.0), g = 2.0*f;
26 | return 0.75*g;
27 | }
28 |
29 | const float foo = 123.0;
30 | float inl5() {
31 | float f = 456.0;
32 | return foo + f;
33 | }
34 |
35 | const float bar = acos(-1.0);
36 | const float baz = 2.0*bar;
37 | float inl6() {
38 | return 2.0 * baz;
39 | }
40 |
41 | float notevil(in float x, float y) { x = 42.0; return x + (y *= y); }
42 | float inl7(float u) {
43 | float f = 101.0;
44 | float z = notevil(f, u);
45 | return f + z;
46 | }
47 |
48 | int inl8(in ivec3 x) {
49 | int i = 1;
50 |
51 | // i is not technically in an lvalue position but not smart enough right now to see that.
52 | x[i] += 1;
53 | return x[i] + i;
54 | }
55 |
56 | // *** Things we shouldn't inline
57 |
58 | float noinl1() {
59 | float f = 42.0;
60 | f = 101.0;
61 | return f;
62 | }
63 |
64 | float noinl2() {
65 | float f = 42.0;
66 | f++;
67 | return f;
68 | }
69 |
70 | float noinl3() {
71 | float f = 42.0;
72 | if (acos(-1.0) < 3.0) {
73 | f = 101.0;
74 | }
75 | return f;
76 | }
77 |
78 | float noinl4() {
79 | float f = 42.0;
80 | for (f = 0.0; false;);
81 | return f;
82 | }
83 |
84 | float noinl5() {
85 | float f = 42.0;
86 | for (; false; f++);
87 | return f;
88 | }
89 |
90 | float noinl6(float x) {
91 | float f = x + 1.0;
92 | x = 100.0;
93 | return f + 2.0;
94 | }
95 |
96 | float noinl7(const float x) {
97 | return x + 1.2;
98 | }
99 |
100 | float quux = 1.0;
101 | float noinl8() {
102 | return quux + 2.0;
103 | }
104 |
105 | float noinl9(float x) {
106 | float bar = x + 1.0; // Shadows inlinable const above
107 | x = 100.0;
108 | return bar + 2.0;
109 | }
110 |
111 | void evil(inout float x) { x = 42.0; }
112 | float noinl10() {
113 | float f = 101.0;
114 | evil(f);
115 | return f;
116 | }
117 |
118 | int noinl11(in ivec3 x) {
119 | int i = 1;
120 | x[i++] += 1;
121 | return x[i] + i;
122 | }
123 |
124 | int noinl12() {
125 | int i = 10;
126 | while (--i > 0) {
127 | }
128 | return 1;
129 | }
130 |
--------------------------------------------------------------------------------
/tests/unit/inline-fn-multiple.expected:
--------------------------------------------------------------------------------
1 | uniform vec3 v[42];
2 | vec3 N()
3 | {
4 | return v[4];
5 | }
6 | vec3 N(float N)
7 | {
8 | return v[4]+N;
9 | }
10 |
--------------------------------------------------------------------------------
/tests/unit/inline-fn-multiple.frag:
--------------------------------------------------------------------------------
1 | uniform vec3 params[42];
2 |
3 | vec3 i_getFoo() {
4 | return params[4];
5 | }
6 |
7 | vec3 f1() {
8 | return i_getFoo();
9 | }
10 |
11 | vec3 f2(float a) {
12 | return i_getFoo() + a;
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/inline-fn.aggro.expected:
--------------------------------------------------------------------------------
1 | float a()
2 | {
3 | return 5.;
4 | }
5 | float b(float g)
6 | {
7 | return(g+10.)*20.+30.+((g+10.1)*20.1+30.1);
8 | }
9 | float c()
10 | {
11 | return 154.;
12 | }
13 | float d()
14 | {
15 | return 54.;
16 | }
17 | float e()
18 | {
19 | return 84.;
20 | }
21 | float globalFloat=6.;
22 | float shadowedFunc(inout float notinlinable)
23 | {
24 | notinlinable=1.;
25 | return-1.;
26 | }
27 | float notShadowedFunc(inout float notinlinable)
28 | {
29 | notinlinable=2.;
30 | return-2.;
31 | }
32 | float shadowedVar=0.;
33 | float A1_PRESERVED()
34 | {
35 | return shadowedVar;
36 | }
37 | float A3_PRESERVED()
38 | {
39 | float a=10.;
40 | return shadowedFunc(a);
41 | }
42 | float B1_PRESERVED(float x)
43 | {
44 | return pow(2.,x);
45 | }
46 | float C1_PRESERVED()
47 | {
48 | float x=sin(0.);
49 | x++;
50 | return 3.+x;
51 | }
52 | float D3_PRESERVED(float d,float dd)
53 | {
54 | return d+d;
55 | }
56 | float glob;
57 | float watchout(out float x)
58 | {
59 | return x=9.;
60 | }
61 | float inuit(inout float greenland)
62 | {
63 | return greenland++;
64 | }
65 | float E1_PRESERVED(float bad1,float ok)
66 | {
67 | return bad1++;
68 | }
69 | float E3_PRESERVED(float bad3,float ok)
70 | {
71 | return bad3+=1.;
72 | }
73 | float E4_PRESERVED(float bad4,float ok)
74 | {
75 | return watchout(bad4);
76 | }
77 | float E5_PRESERVED(float bad5,float ok)
78 | {
79 | return inuit(bad5);
80 | }
81 | float F2_PRESERVED(out float ff)
82 | {
83 | return 7.;
84 | }
85 | float F3_PRESERVED(inout float f)
86 | {
87 | return 7.;
88 | }
89 | float PRAGMA_PRESERVED()
90 | {
91 | return 9.;
92 | }
93 | float setup()
94 | {
95 | return shadowedVar++;
96 | }
97 | float f()
98 | {
99 | float shadowedVar=-1.,shadowedFunc=-2.,_A3=A3_PRESERVED(),_A4=notShadowedFunc(globalFloat);
100 | int sep;
101 | sep++;
102 | sep++;
103 | float four=4.,five=5.,_D1=four+four,_D2=four+five,_D3=D3_PRESERVED(four+1.,sin(five));
104 | four++,five++;
105 | sep++;
106 | float six=6.,ten=10.,_E1=E1_PRESERVED(six,ten),_E2=six+watchout(glob)-glob--*(glob*=ten)+inuit(glob),_E3=E3_PRESERVED(six,ten),_E4=E4_PRESERVED(six,ten),_E5=E5_PRESERVED(six,ten);
107 | six++,ten++;
108 | sep++;
109 | float o,_F2=F2_PRESERVED(o);
110 | o=F3_PRESERVED(o);
111 | sep++;
112 | setup();
113 | shadowedVar++;
114 | shadowedFunc++;
115 | return shadowedVar+shadowedFunc+four+five+six+ten+A1_PRESERVED()+1.+_A3+_A4+(B1_PRESERVED(3.)+B1_PRESERVED(4.))+4.+C1_PRESERVED()+(3.+sin(0.))+_D1+_D2+_D3+_E1+_E2+_E3+_E4+_E5+7.+_F2+o+(vec3(9).x+vec3(8).x)+PRAGMA_PRESERVED();
116 | }
117 | float g()
118 | {
119 | return 1.;
120 | }
121 |
--------------------------------------------------------------------------------
/tests/unit/inline-fn.expected:
--------------------------------------------------------------------------------
1 | float a()
2 | {
3 | return 5.;
4 | }
5 | float b(float g)
6 | {
7 | return(g+10.)*20.+30.+((g+10.1)*20.1+30.1);
8 | }
9 | float c()
10 | {
11 | return 154.;
12 | }
13 | float d()
14 | {
15 | return 54.;
16 | }
17 | float e()
18 | {
19 | return 84.;
20 | }
21 | float globalFloat=6.;
22 | float shadowedFunc(inout float notinlinable)
23 | {
24 | notinlinable=1.;
25 | return-1.;
26 | }
27 | float notShadowedFunc(inout float notinlinable)
28 | {
29 | notinlinable=2.;
30 | return-2.;
31 | }
32 | float shadowedVar=0.;
33 | float A1_PRESERVED()
34 | {
35 | return shadowedVar;
36 | }
37 | float A3_PRESERVED()
38 | {
39 | float a=10.;
40 | return shadowedFunc(a);
41 | }
42 | float B1_PRESERVED(float x)
43 | {
44 | return pow(2.,x);
45 | }
46 | float C1_PRESERVED()
47 | {
48 | float x=sin(0.);
49 | x++;
50 | return 3.+x;
51 | }
52 | float D3_PRESERVED(float d,float dd)
53 | {
54 | return d+d;
55 | }
56 | float glob;
57 | float watchout(out float x)
58 | {
59 | return x=9.;
60 | }
61 | float inuit(inout float greenland)
62 | {
63 | return greenland++;
64 | }
65 | float E1_PRESERVED(float bad1,float ok)
66 | {
67 | return bad1++;
68 | }
69 | float E3_PRESERVED(float bad3,float ok)
70 | {
71 | return bad3+=1.;
72 | }
73 | float E4_PRESERVED(float bad4,float ok)
74 | {
75 | return watchout(bad4);
76 | }
77 | float E5_PRESERVED(float bad5,float ok)
78 | {
79 | return inuit(bad5);
80 | }
81 | float F2_PRESERVED(out float ff)
82 | {
83 | return 7.;
84 | }
85 | float F3_PRESERVED(inout float f)
86 | {
87 | return 7.;
88 | }
89 | float PRAGMA_PRESERVED()
90 | {
91 | return 9.;
92 | }
93 | float setup()
94 | {
95 | return shadowedVar++;
96 | }
97 | float f()
98 | {
99 | float shadowedVar=-1.,shadowedFunc=-2.,_A3=A3_PRESERVED(),_A4=notShadowedFunc(globalFloat);
100 | int sep;
101 | sep++;
102 | sep++;
103 | float four=4.,five=5.,_D1=four+four,_D2=four+five,_D3=D3_PRESERVED(four+1.,sin(five));
104 | four++,five++;
105 | sep++;
106 | float six=6.,ten=10.,_E1=E1_PRESERVED(six,ten),_E2=six+watchout(glob)-glob--*(glob*=ten)+inuit(glob),_E3=E3_PRESERVED(six,ten),_E4=E4_PRESERVED(six,ten),_E5=E5_PRESERVED(six,ten);
107 | six++,ten++;
108 | sep++;
109 | float o,_F2=F2_PRESERVED(o);
110 | o=F3_PRESERVED(o);
111 | sep++;
112 | setup();
113 | shadowedVar++;
114 | shadowedFunc++;
115 | return shadowedVar+shadowedFunc+four+five+six+ten+A1_PRESERVED()+1.+_A3+_A4+(B1_PRESERVED(3.)+B1_PRESERVED(4.))+4.+C1_PRESERVED()+(3.+sin(0.))+_D1+_D2+_D3+_E1+_E2+_E3+_E4+_E5+7.+_F2+o+(vec3(9).x+vec3(8).x)+PRAGMA_PRESERVED();
116 | }
117 | float g()
118 | {
119 | return 1.;
120 | }
121 |
--------------------------------------------------------------------------------
/tests/unit/inline.aggro.expected:
--------------------------------------------------------------------------------
1 | #version 420
2 |
3 | float result;
4 | void main()
5 | {
6 | result=.15;
7 | }
8 | int arithmetic()
9 | {
10 | return 40;
11 | }
12 | int vars(int arg,int arg2)
13 | {
14 | return arg*(arg+arg2);
15 | }
16 | int arithmetic2()
17 | {
18 | return 40;
19 | }
20 | int unusedVars()
21 | {
22 | return 30;
23 | }
24 | int unusedVars2()
25 | {
26 | return 18;
27 | }
28 | int multiPass()
29 | {
30 | return 3;
31 | }
32 | float multiPass2()
33 | {
34 | return 9.;
35 | }
36 | layout(binding=0)uniform atomic_uint hydrogen;
37 | uint builtin_with_or_without_side_effects(uint x)
38 | {
39 | uint not_inlined=atomicCounterIncrement(hydrogen);
40 | atomicCounterIncrement(hydrogen);
41 | return x+max(x*x,x+1)+not_inlined;
42 | }
43 | float dmin(float a,float b)
44 | {
45 | return a+b+a*b;
46 | }
47 | float reduce_consecutive_assignments(float x)
48 | {
49 | float dmat=dmin(dmin(dmin(dmin(dmin(34.+x,.2),.2),.3),.4),.2);
50 | dmat+=dmat*dmat;
51 | return dmat+x;
52 | }
53 | int dont_inline_lvalue()
54 | {
55 | return 3;
56 | }
57 | vec4 fragColor247;
58 | void main247()
59 | {
60 | fragColor247=vec4(3);
61 | }
62 | vec4 fragColor248;
63 | void main248()
64 | {
65 | fragColor248=vec4(3);
66 | }
67 | float arr[]=float[](3.4,4.2);
68 | void lvalues()
69 | {
70 | arr[1]=2.;
71 | }
72 | uniform int time;
73 | flat in int sync;
74 | int dependOnConst()
75 | {
76 | return(time+sync)*2*3;
77 | }
78 | float noinl179(float x)
79 | {
80 | float old=x;
81 | x=1e2;
82 | return old+x;
83 | }
84 | float inlineWithShadowing(float x)
85 | {
86 | if(x<0.)
87 | {
88 | float inl=3.4;
89 | inl++;
90 | }
91 | return sin(2.5);
92 | }
93 | float inline_uninitialized()
94 | {
95 | float c;
96 | return c;
97 | }
98 | float glo;
99 | float noinline_readsTheGlobal()
100 | {
101 | return glo;
102 | }
103 | float dontCompressAssigments()
104 | {
105 | glo=10.;
106 | glo=50.+noinline_readsTheGlobal();
107 | return glo*glo;
108 | }
109 | vec3 repro(vec2 fragCoord,float iTime)
110 | {
111 | iTime+=(fragCoord.xy/(fragCoord*2.).xy).x*10.;
112 | vec3 used_many_times=vec3((fragCoord.y+sin(iTime*.5)*.4-fragCoord.x+iTime*.5)*normalize(vec3(0,0,1))),col=used_many_times,sky=col+used_many_times;
113 | vec4 cc=vec4(used_many_times-used_many_times,1);
114 | sky+=pow(max(dot(sky,used_many_times),0.),20.)*.03;
115 | col=vec3(dot(col+mix(sky,cc.xyz,cc.w)+used_many_times,used_many_times));
116 | return col+pow(max(dot(sky,used_many_times),0.),6.)*.2;
117 | }
118 | vec3 g(float x)
119 | {
120 | float y=x*x;
121 | {
122 | float b=23.*x;
123 | y+=b*b+30.;
124 | }
125 | return vec3(10.*x*x)*2.+vec3(y);
126 | }
127 | vec3 vecs(float x)
128 | {
129 | return vec3(0)+vec3(4,3,4)+vec3(3,3,g(8.)*g(9.));
130 | }
131 |
--------------------------------------------------------------------------------
/tests/unit/inline.expected:
--------------------------------------------------------------------------------
1 | #version 420
2 |
3 | float result;
4 | void main()
5 | {
6 | result=.15;
7 | }
8 | int arithmetic()
9 | {
10 | return 40;
11 | }
12 | int vars(int arg,int arg2)
13 | {
14 | return arg*(arg+arg2);
15 | }
16 | int arithmetic2()
17 | {
18 | return 40;
19 | }
20 | int unusedVars()
21 | {
22 | return 30;
23 | }
24 | int unusedVars2()
25 | {
26 | return 18;
27 | }
28 | int multiPass()
29 | {
30 | return 3;
31 | }
32 | float multiPass2()
33 | {
34 | return 9.;
35 | }
36 | layout(binding=0)uniform atomic_uint hydrogen;
37 | uint builtin_with_or_without_side_effects(uint x)
38 | {
39 | uint not_inlined=atomicCounterIncrement(hydrogen);
40 | atomicCounterIncrement(hydrogen);
41 | return x+max(x*x,x+1)+not_inlined;
42 | }
43 | float dmin(float a,float b)
44 | {
45 | return a+b+a*b;
46 | }
47 | float reduce_consecutive_assignments(float x)
48 | {
49 | float dmat=dmin(dmin(dmin(dmin(dmin(34.+x,.2),.2),.3),.4),.2);
50 | dmat+=dmat*dmat;
51 | return dmat+x;
52 | }
53 | int dont_inline_lvalue()
54 | {
55 | return 3;
56 | }
57 | vec4 fragColor247;
58 | void main247()
59 | {
60 | fragColor247=vec4(3);
61 | }
62 | vec4 fragColor248;
63 | void main248()
64 | {
65 | fragColor248=vec4(3);
66 | }
67 | float arr[]=float[](3.4,4.2);
68 | void lvalues()
69 | {
70 | arr[1]=2.;
71 | }
72 | uniform int time;
73 | flat in int sync;
74 | int dependOnConst()
75 | {
76 | return(time+sync)*2*3;
77 | }
78 | float noinl179(float x)
79 | {
80 | float old=x;
81 | x=1e2;
82 | return old+x;
83 | }
84 | float inlineWithShadowing(float x)
85 | {
86 | if(x<0.)
87 | {
88 | float inl=3.4;
89 | inl++;
90 | }
91 | return sin(2.5);
92 | }
93 | float inline_uninitialized()
94 | {
95 | float c;
96 | return c;
97 | }
98 | float glo;
99 | float noinline_readsTheGlobal()
100 | {
101 | return glo;
102 | }
103 | float dontCompressAssigments()
104 | {
105 | glo=10.;
106 | glo=50.+noinline_readsTheGlobal();
107 | return glo*glo;
108 | }
109 | vec3 repro(vec2 fragCoord,float iTime)
110 | {
111 | iTime+=(fragCoord.xy/(fragCoord*2.).xy).x*10.;
112 | vec3 used_many_times=vec3((fragCoord.y+sin(iTime*.5)*.4-fragCoord.x+iTime*.5)*normalize(vec3(0,0,1))),col=used_many_times,sky=col+used_many_times,camera=used_many_times;
113 | vec4 cc=vec4(camera-used_many_times,1);
114 | sky+=pow(max(dot(sky,used_many_times),0.),20.)*.03;
115 | col=vec3(dot(col+mix(sky,cc.xyz,cc.w)+camera,used_many_times));
116 | return col+pow(max(dot(sky,used_many_times),0.),6.)*.2;
117 | }
118 | vec3 g(float x)
119 | {
120 | float y=x*x;
121 | {
122 | float b=23.*x;
123 | y+=b*b+30.;
124 | }
125 | return vec3(10.*x*x)*2.+vec3(y);
126 | }
127 | vec3 vecs(float x)
128 | {
129 | return vec3(0)+vec3(4,3,4)+vec3(3,3,g(8.)*g(9.));
130 | }
131 |
--------------------------------------------------------------------------------
/tests/unit/inline.frag:
--------------------------------------------------------------------------------
1 | #version 420
2 |
3 | float result;
4 |
5 | void main()
6 | {
7 | float x = 0.5;
8 | float i_y = 0.6*x;
9 | float a = x * i_y;
10 | result = a;
11 | }
12 |
13 | int arithmetic()
14 | {
15 | int i_a = 2;
16 | int i_b = 3;
17 | int i_c = i_a + i_b;
18 | return 4 * i_a * i_c;
19 | }
20 |
21 | int vars(int arg, int arg2)
22 | {
23 | int i_a = arg;
24 | int i_b = arg2;
25 | int i_c = i_a + i_b;
26 | return i_a * i_c;
27 | }
28 |
29 | int arithmetic2()
30 | {
31 | int a = 2;
32 | int b = 3;
33 | int c = a + b;
34 | return 4 * a * c;
35 | }
36 |
37 | int unusedVars() {
38 | int a = arithmetic();
39 | int b = 13;
40 | int c = 10;
41 | int d = c * 3;
42 | return d;
43 | }
44 |
45 | int unusedVars2() {
46 | int var1 = 1, var2 = 2, var3 = 3, var4 = 4, var5 = 5, var6 = 6;
47 | int var7 = 7, var8 = 8, var9 = 9, var10 = 10, var11 = 11, var12 = 12;
48 | return var1 + var5 + var12;
49 | }
50 |
51 | int multiPass()
52 | {
53 | int one = 1;
54 | int two = one * 2;
55 | int three = two + 1;
56 | return three;
57 | }
58 |
59 | float multiPass2() {
60 | float i_a = 4.0;
61 | float b = i_a + 5.0;
62 | return b;
63 | }
64 |
65 | layout(binding=0) uniform atomic_uint hydrogen;
66 | uint builtin_with_or_without_side_effects(uint x)
67 | {
68 | uint not_inlined = atomicCounterIncrement(hydrogen);
69 | uint inlined = max(x * x, x + 1);
70 | atomicCounterIncrement(hydrogen);
71 | return x + inlined + not_inlined;
72 | }
73 |
74 | float dmin(float a, float b)
75 | {
76 | return a+b+a*b;
77 | }
78 | float reduce_consecutive_assignments(float x)
79 | {
80 | float dmat=34.+x;
81 | dmat=dmin(dmat,.2);
82 | dmat=dmin(dmat,.2);
83 | dmat=dmin(dmat,.3);
84 | dmat=dmin(dmat,.4);
85 | dmat=dmin(dmat,.2);
86 | dmat=dmat*dmat+dmat;
87 | return dmat+x;
88 | }
89 |
90 | // repro for #176
91 | int dont_inline_lvalue() {
92 | int a = 1;
93 | a = 2;
94 | return 3;
95 | }
96 |
97 | // repro for #247
98 | vec4 fragColor247;
99 | const float t247 = 1.5+(1.+.5);
100 | void main247() {
101 | fragColor247 = vec4(t247);
102 | }
103 |
104 | // repro for #248
105 | vec4 fragColor248;
106 | void main248() {
107 | float t = 1.5+(1.+.5);
108 | fragColor248 = vec4(t);
109 | }
110 |
111 | float arr[] = float[](3.4, 4.2);
112 | void lvalues() {
113 | int a = 1;
114 | arr[a] = 2.;
115 | }
116 |
117 | uniform int time;
118 | flat in int sync;
119 |
120 | int dependOnConst() {
121 | int x = time + sync;
122 | int y = x * 2;
123 | return y*3;
124 | }
125 |
126 | // repro for #179
127 | float noinl179(float x) {
128 | float old = x;
129 | x = 100.0;
130 | return old + x;
131 | }
132 |
133 | // repro for a bug
134 | float inlineWithShadowing(float x) {
135 | float inl = sin(2.5);
136 | if (x < 0.)
137 | {
138 | float inl = 3.4;
139 | inl++;
140 | }
141 | return inl;
142 | }
143 |
144 | // repro for a bug
145 | float inline_uninitialized()
146 | {
147 | // https://github.com/laurentlb/shader-minifier/issues/317
148 | // Error: 'c' : undeclared identifier
149 | float c;
150 | return c;
151 | }
152 |
153 | // repro for a bug
154 | float glo;
155 | float noinline_readsTheGlobal()
156 | {
157 | return glo;
158 | }
159 | float dontCompressAssigments()
160 | {
161 | glo = 10.;
162 | glo = 50. + noinline_readsTheGlobal();
163 | return glo*glo;
164 | }
165 |
166 | // repro for dual-kind-mixing aggressive-inlining bug
167 | vec3 repro(vec2 fragCoord, float iTime)
168 | {
169 | float time = iTime*1.+(fragCoord.xy / (fragCoord*2.).xy).x*10.0;
170 |
171 | vec3 long_and_used_only_once = vec3((fragCoord.y+sin(time*.5)*.4 - fragCoord.x+time*.5)*normalize(vec3(0,0, 1.)));
172 | vec3 used_many_times = long_and_used_only_once;
173 |
174 | vec3 col = used_many_times;
175 | vec3 sky = col + used_many_times;
176 | vec3 camera = used_many_times;
177 | vec4 cc = vec4(camera - used_many_times, 1.);
178 | sky+= pow(max(dot(sky, used_many_times), 0.0), 20.0) * .03;
179 | col = vec3(dot(col + mix(sky, cc.xyz, cc.w) + camera, used_many_times));
180 | return col + pow(max(dot(sky, used_many_times), 0.0), 6.0) * .2;
181 | }
182 |
183 | vec3 g(float x)
184 | {
185 | float y = x * x;
186 | vec3 b = vec3(10.0 * x * x); // b should be inlined (used only once)
187 | vec3 c = vec3(10.0, 20.0, 30.0);
188 | {
189 | float b = 23.0 * x; // even though there is another b in a sub block
190 | y += b * b + c.z;
191 | }
192 | return b * 2.0 + vec3(y);
193 | }
194 |
195 | vec3 vecs(float x)
196 | {
197 | return vec4(0.,0.,0.,1.25).xyz
198 | + vec2(3,4).yxy
199 | + vec4(1,2,3,g(8.)*g(9.)).zzw;
200 | }
201 |
--------------------------------------------------------------------------------
/tests/unit/inline.no.expected:
--------------------------------------------------------------------------------
1 | #version 420
2 |
3 | float result;
4 | void main()
5 | {
6 | float x=.5;
7 | x*=.6*x;
8 | result=x;
9 | }
10 | int arithmetic()
11 | {
12 | return 40;
13 | }
14 | int vars(int arg,int arg2)
15 | {
16 | return arg*(arg+arg2);
17 | }
18 | int arithmetic2()
19 | {
20 | int a=2,b=3;
21 | b+=a;
22 | return 4*a*b;
23 | }
24 | int unusedVars()
25 | {
26 | int a=arithmetic(),b=13;
27 | a=10;
28 | return a*3;
29 | }
30 | int unusedVars2()
31 | {
32 | int var1=1,var2=2,var3=3,var4=4,var5=5,var6=6,var7=7;
33 | var7=8;
34 | var6=9;
35 | var4=10;
36 | var3=11;
37 | var2=12;
38 | return var1+var5+var2;
39 | }
40 | int multiPass()
41 | {
42 | int one=2;
43 | return one+1;
44 | }
45 | float multiPass2()
46 | {
47 | return 9.;
48 | }
49 | layout(binding=0)uniform atomic_uint hydrogen;
50 | uint builtin_with_or_without_side_effects(uint x)
51 | {
52 | uint not_inlined=atomicCounterIncrement(hydrogen),inlined=max(x*x,x+1);
53 | atomicCounterIncrement(hydrogen);
54 | return x+inlined+not_inlined;
55 | }
56 | float dmin(float a,float b)
57 | {
58 | return a+b+a*b;
59 | }
60 | float reduce_consecutive_assignments(float x)
61 | {
62 | float dmat=dmin(dmin(dmin(dmin(dmin(34.+x,.2),.2),.3),.4),.2);
63 | dmat+=dmat*dmat;
64 | return dmat+x;
65 | }
66 | int dont_inline_lvalue()
67 | {
68 | int a=2;
69 | return 3;
70 | }
71 | vec4 fragColor247;
72 | const float t247=3.;
73 | void main247()
74 | {
75 | fragColor247=vec4(t247);
76 | }
77 | vec4 fragColor248;
78 | void main248()
79 | {
80 | float t=3.;
81 | fragColor248=vec4(t);
82 | }
83 | float arr[]=float[](3.4,4.2);
84 | void lvalues()
85 | {
86 | int a=1;
87 | arr[a]=2.;
88 | }
89 | uniform int time;
90 | flat in int sync;
91 | int dependOnConst()
92 | {
93 | int x=(time+sync)*2;
94 | return x*3;
95 | }
96 | float noinl179(float x)
97 | {
98 | float old=x;
99 | x=1e2;
100 | return old+x;
101 | }
102 | float inlineWithShadowing(float x)
103 | {
104 | float inl=sin(2.5);
105 | if(x<0.)
106 | {
107 | float inl=3.4;
108 | inl++;
109 | }
110 | return inl;
111 | }
112 | float inline_uninitialized()
113 | {
114 | float c;
115 | return c;
116 | }
117 | float glo;
118 | float noinline_readsTheGlobal()
119 | {
120 | return glo;
121 | }
122 | float dontCompressAssigments()
123 | {
124 | glo=10.;
125 | glo=50.+noinline_readsTheGlobal();
126 | return glo*glo;
127 | }
128 | vec3 repro(vec2 fragCoord,float iTime)
129 | {
130 | iTime+=(fragCoord.xy/(fragCoord*2.).xy).x*10.;
131 | vec3 long_and_used_only_once=vec3((fragCoord.y+sin(iTime*.5)*.4-fragCoord.x+iTime*.5)*normalize(vec3(0,0,1))),used_many_times=long_and_used_only_once,col=used_many_times,sky=col+used_many_times;
132 | long_and_used_only_once=used_many_times;
133 | vec4 cc=vec4(long_and_used_only_once-used_many_times,1);
134 | sky+=pow(max(dot(sky,used_many_times),0.),20.)*.03;
135 | col=vec3(dot(col+mix(sky,cc.xyz,cc.w)+long_and_used_only_once,used_many_times));
136 | return col+pow(max(dot(sky,used_many_times),0.),6.)*.2;
137 | }
138 | vec3 g(float x)
139 | {
140 | float y=x*x;
141 | vec3 b=vec3(10.*x*x),c=vec3(10,20,30);
142 | {
143 | float b=23.*x;
144 | y+=b*b+c.z;
145 | }
146 | return b*2.+vec3(y);
147 | }
148 | vec3 vecs(float x)
149 | {
150 | return vec3(0)+vec3(4,3,4)+vec3(3,3,g(8.)*g(9.));
151 | }
152 |
--------------------------------------------------------------------------------
/tests/unit/inout.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | # define VAR_ambientLight "f"
6 | # define VAR_diffuseColor "p"
7 | # define VAR_emissiveColor "z"
8 | # define VAR_fragmentColor "r"
9 | # define VAR_mediumDensity "c"
10 | # define VAR_normal "m"
11 | # define VAR_specularColor "C"
12 | # define VAR_texture0 "v"
13 | # define VAR_viewVec "d"
14 | #endif
15 |
16 | #else // if SHADER_MINIFIER_IMPL
17 |
18 | // tests/unit/inout.frag
19 | "#version 330\n"
20 | "uniform samplerCube v;"
21 | "in vec3 m,d;"
22 | "out vec4 r;"
23 | "void main()"
24 | "{"
25 | "vec3 c=normalize(d),t=normalize(m);"
26 | "r=vec4(mix(vec3(.1,.2,.3)*texture(v,refract(-c,t,1./1.5)).xyz,texture(v,reflect(-c,t)).xyz,.1),1);"
27 | "}"
28 | "vec3 t(vec3 v,vec3 m,vec3 t)"
29 | "{"
30 | "float r=1.-clamp(dot(m,t),0.,1.);"
31 | "return r*r*r*r*r*(1.-v)+v;"
32 | "}"
33 | "vec3 t(vec3 v,vec3 m,vec3 r,vec3 c,vec3 d,float f)"
34 | "{"
35 | "m=normalize(v+m);"
36 | "f=1.+2048.*(1.-f)*(1.-f);"
37 | "return mix(c,vec3(pow(clamp(dot(m,r),0.,1.),f)*(f+4.)/8.),t(d,v,m));"
38 | "}",
39 |
40 | // tests/unit/inout2.frag
41 | "#version 330\n"
42 | "uniform samplerCube v;"
43 | "uniform float c;"
44 | "uniform vec3 f,p,z,C;"
45 | "in vec3 m,d;"
46 | "out vec4 r;"
47 | "vec3 t(vec3 v,vec3 m,vec3 t)"
48 | "{"
49 | "float r=1.-clamp(dot(m,t),0.,1.);"
50 | "return r*r*r*r*r*(1.-v)+v;"
51 | "}"
52 | "void main()"
53 | "{"
54 | "r=vec4(z+mix(p*f,f,.5),1);"
55 | "}"
56 | "vec3 t(vec3 v,vec3 m,vec3 f,vec3 c,vec3 d,float r)"
57 | "{"
58 | "m=normalize(v+m);"
59 | "r=1.+2048.*(1.-r)*(1.-r);"
60 | "return mix(c,vec3(pow(clamp(dot(m,f),0.,1.),r)*(r+4.)/8.),t(d,v,m));"
61 | "}",
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/tests/unit/inout.frag:
--------------------------------------------------------------------------------
1 | // Multifile test, part 1
2 |
3 | // The test is to ensure that exported variables are renamed in the same way
4 | // across multiple files.
5 |
6 | #version 330
7 |
8 | // These 4 variables should have the same name as in the other file.
9 | uniform samplerCube texture0;
10 |
11 | in vec3 normal;
12 | in vec3 viewVec;
13 |
14 | out vec4 fragmentColor;
15 |
16 | void main()
17 | {
18 | vec3 E = normalize(viewVec);
19 | vec3 N = normalize(normal);
20 | vec3 albedo = vec3(0.1, 0.2, 0.3);
21 | vec3 f0 = vec3(0.5, 0.5, 0.5);
22 |
23 | float IoR = 1.5;
24 | vec3 reflection = texture(texture0, reflect(-E, N)).rgb;
25 | vec3 refraction = texture(texture0, refract(-E, N, 1./IoR)).rgb;
26 |
27 | vec3 color = mix(albedo * refraction, reflection, 0.1);
28 | fragmentColor = vec4(color, 1.);
29 | }
30 |
31 | // These functions are same as in the other file. Ideally (for better compression),
32 | // the local variables and arguments should remain the same.
33 | vec3 Schlick(vec3 f0, vec3 E, vec3 H)
34 | {
35 | float x = 1. - clamp(dot(E, H), 0., 1.);
36 | return x*x*x*x*x * (1. - f0) + f0;
37 | }
38 |
39 | vec3 BlinnPhong(vec3 E, vec3 L, vec3 N, vec3 albedo, vec3 f0, float roughness)
40 | {
41 | vec3 H = normalize(E + L);
42 | float alpha = 1. + 2048. * (1. - roughness)*(1. - roughness);
43 |
44 | vec3 diffuse = albedo;
45 | vec3 specular = vec3(pow(clamp(dot(H, N), 0., 1.), alpha) * (alpha + 4.) / 8.);
46 | vec3 fresnel = Schlick(f0, E, H);
47 |
48 | return mix(diffuse, specular, fresnel);
49 | }
50 |
--------------------------------------------------------------------------------
/tests/unit/inout2.frag:
--------------------------------------------------------------------------------
1 | // Multifile test, part 2
2 |
3 | #version 330
4 |
5 | uniform samplerCube texture0;
6 |
7 | uniform float mediumDensity;
8 | uniform vec3 ambientLight;
9 | uniform vec3 diffuseColor;
10 | uniform vec3 emissiveColor;
11 | uniform vec3 specularColor;
12 |
13 | in vec3 normal;
14 | in vec3 viewVec;
15 |
16 | out vec4 fragmentColor;
17 |
18 | vec3 Schlick(vec3 f0, vec3 E, vec3 H)
19 | {
20 | float x = 1. - clamp(dot(E, H), 0., 1.);
21 | return x*x*x*x*x * (1. - f0) + f0;
22 | }
23 |
24 | void main()
25 | {
26 | vec3 E = normalize(viewVec);
27 | vec3 N = normalize(normal);
28 | vec3 albedo = diffuseColor;
29 | vec3 f0 = specularColor;
30 | float schlick = 0.5;
31 |
32 | vec3 color = emissiveColor + mix(albedo * ambientLight, ambientLight, schlick);
33 | fragmentColor = vec4(color, 1.);
34 | }
35 |
36 | vec3 BlinnPhong(vec3 E, vec3 L, vec3 N, vec3 albedo, vec3 f0, float roughness)
37 | {
38 | vec3 H = normalize(E + L);
39 | float alpha = 1. + 2048. * (1. - roughness)*(1. - roughness);
40 |
41 | vec3 diffuse = albedo;
42 | vec3 specular = vec3(pow(clamp(dot(H, N), 0., 1.), alpha) * (alpha + 4.) / 8.);
43 | vec3 fresnel = Schlick(f0, E, H);
44 |
45 | return mix(diffuse, specular, fresnel);
46 | }
47 |
--------------------------------------------------------------------------------
/tests/unit/interface-block-renaming.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | # define VAR_field "U"
6 | #endif
7 |
8 | #else // if SHADER_MINIFIER_IMPL
9 |
10 | // tests/unit/interface-block-renaming1.frag
11 | "#version 460\n"
12 | "uniform Uniform1{vec4 U;};",
13 |
14 | // tests/unit/interface-block-renaming2.frag
15 | "#version 460\n"
16 | "uniform Uniform1{vec4 U;};",
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/tests/unit/interface-block-renaming1.frag:
--------------------------------------------------------------------------------
1 | #version 460
2 | // https://github.com/laurentlb/shader-minifier/issues/430
3 | uniform Uniform1 { vec4 field; };
4 | //uniform Uniform2 { vec4 field; } instance; // TODO
5 |
--------------------------------------------------------------------------------
/tests/unit/interface-block-renaming2.frag:
--------------------------------------------------------------------------------
1 | #version 460
2 | // https://github.com/laurentlb/shader-minifier/issues/430
3 | uniform Uniform1 { vec4 field; };
4 | //uniform Uniform2 { vec4 field; } instance; // TODO
5 |
--------------------------------------------------------------------------------
/tests/unit/interface_block.frag:
--------------------------------------------------------------------------------
1 | #version 140
2 |
3 | uniform MyBlock
4 | {
5 | vec3 color; // treated as a global variable
6 | float alpha;
7 | };
8 |
9 | void mainImage(out vec4 fragColor, in vec2 fragCoord)
10 | {
11 | fragColor = vec4(color, alpha);
12 | }
13 |
--------------------------------------------------------------------------------
/tests/unit/interface_block.frag.expected:
--------------------------------------------------------------------------------
1 | #version 140
2 |
3 | uniform MyBlock{vec3 M;float v;};
4 | void mainImage(out vec4 m,vec2 B)
5 | {
6 | m=vec4(M,v);
7 | }
8 |
--------------------------------------------------------------------------------
/tests/unit/keyword_prefix.frag:
--------------------------------------------------------------------------------
1 | void do_something() {}
2 |
3 | void f() {
4 | do_something();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/unit/keyword_prefix.frag.expected:
--------------------------------------------------------------------------------
1 | /* File generated with Shader Minifier 1.1.6
2 | * http://www.ctrl-alt-test.fr
3 | */
4 | #ifndef KEYWORD_PREFIX_FRAG_EXPECTED_
5 | # define KEYWORD_PREFIX_FRAG_EXPECTED_
6 |
7 | const char *keyword_prefix_frag =
8 | "void d()"
9 | "{}"
10 | "void i()"
11 | "{"
12 | "d();"
13 | "}";
14 |
15 | #endif // KEYWORD_PREFIX_FRAG_EXPECTED_
16 |
--------------------------------------------------------------------------------
/tests/unit/layout.comp:
--------------------------------------------------------------------------------
1 | #version 430
2 |
3 | layout(local_size_x = 32) in; // #22
4 |
--------------------------------------------------------------------------------
/tests/unit/layout.frag:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | // #486
4 | layout( location = 1 ) out vec4 f_color2;
5 |
6 | // #17
7 | layout(location=0) out vec4 f_color;
8 | //subroutine float functionType(int i);
9 | //layout(location = 0) subroutine uniform functionType tbl[2];
10 | //layout(index = 1) subroutine (functionType) float func1(int i) { return i * 1.0/255.0; }
11 | //layout(index = 2) subroutine (functionType) float func2(int i) { return 1.0 - i * 1.0/255.0; }
12 |
--------------------------------------------------------------------------------
/tests/unit/layout.frag.expected:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | layout(location=1)out vec4 f_color2;
4 | layout(location=0)out vec4 f_color;
5 |
--------------------------------------------------------------------------------
/tests/unit/layout.geom:
--------------------------------------------------------------------------------
1 | #version 150
2 |
3 | layout(triangles) in; // #29
4 | layout(triangle_strip, max_vertices = 3) out; // #29
5 |
--------------------------------------------------------------------------------
/tests/unit/loop.frag:
--------------------------------------------------------------------------------
1 | float f(inout float noinlinevar){return 0.;}
2 |
3 | float a;
4 | void main()
5 | {
6 | float c;
7 | for (float d=0.; d<50.; ++d)
8 | {
9 | c+=cos(d);
10 | }
11 | float b;
12 | for (b=0.; b<50.; ++b)
13 | {
14 | c+=cos(c);
15 | }
16 | b = a;
17 | while (b<50.)
18 | {
19 | c+=cos(c);
20 | b++;
21 | }
22 | b = a;
23 | while (b<50.)
24 | {
25 | b++;
26 | }
27 | b = a;
28 | while (b<50.)
29 | {
30 | c+=cos(c);
31 | float arg; float d=f(arg); // d prevents moving b+=d to a for
32 | b+=d;
33 | }
34 | b = a;
35 | while (b<50.)
36 | {
37 | if (a < b) continue; // continue prevents moving b++ to a for
38 | b++;
39 | }
40 | b = a;
41 | while (b<50.)
42 | {
43 | if (a < b) a=b; else continue; // continue prevents moving b++ to a for
44 | b++;
45 | }
46 | b = a;
47 | while (b<50.)
48 | {
49 | a += b;
50 | {
51 | float a = b-a;
52 | if (a < b) a=b; else continue; // continue prevents moving b++ to a for
53 | }
54 | b++;
55 | }
56 | for (; b<50.; ++b)
57 | {
58 | c+=cos(b);
59 | }
60 | do
61 | b++;
62 | while (b<100.);
63 | do {
64 | if (a>10.)b++;
65 | b+=a;
66 | } while (b<100.);
67 | }
68 |
--------------------------------------------------------------------------------
/tests/unit/loop.frag.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef LOOP_FRAG_EXPECTED_
3 | # define LOOP_FRAG_EXPECTED_
4 |
5 | const char *loop_frag =
6 | "float f(inout float noinlinevar)"
7 | "{"
8 | "return 0.;"
9 | "}"
10 | "float a;"
11 | "void main()"
12 | "{"
13 | "float c;"
14 | "for(float d=0.;d<50.;++d)"
15 | "c+=cos(d);"
16 | "float b;"
17 | "for(b=0.;b<50.;++b)"
18 | "c+=cos(c);"
19 | "for(b=a;b<50.;b++)"
20 | "c+=cos(c);"
21 | "for(b=a;b<50.;b++)"
22 | ";"
23 | "for(b=a;b<50.;)"
24 | "{"
25 | "c+=cos(c);"
26 | "float arg;"
27 | "arg=f(arg);"
28 | "b+=arg;"
29 | "}"
30 | "for(b=a;b<50.;)"
31 | "{"
32 | "if(a10.)"
64 | "b++;"
65 | "b+=a;"
66 | "}"
67 | "while(b<1e2);"
68 | "}";
69 |
70 | #endif // LOOP_FRAG_EXPECTED_
71 |
--------------------------------------------------------------------------------
/tests/unit/macros.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef MACROS_EXPECTED_
3 | # define MACROS_EXPECTED_
4 |
5 | const char *macros_frag =
6 | "#define a $\n"
7 | "#define b ($+)\n"
8 | "#define c $+\n"
9 | "#define d abc def+ghi()\n"
10 | "#define e $\n"
11 | "#define f $\n"
12 | "#define g $\n"
13 | "#define h $\n"
14 | "#define i $\n"
15 | "#define j $\n"
16 | "#define k $\n"
17 | "#define l $\n"
18 | "#define m $\n"
19 | "#define n $\n"
20 | "#define o $\n"
21 | "#define p $\n"
22 | "int E()"
23 | "{"
24 | "int E=1,r=2,C=3,B=4,A=5,D=6,F=7;"
25 | "F=8;"
26 | "D=9;"
27 | "B=10;"
28 | "C=11;"
29 | "r=12;"
30 | "return E+A+r;"
31 | "}";
32 |
33 | #endif // MACROS_EXPECTED_
34 |
--------------------------------------------------------------------------------
/tests/unit/macros.frag:
--------------------------------------------------------------------------------
1 | // Define a bunch of macros. Make sure Shader Minifier doesn't use
2 | // these names when renaming variables.
3 | // Also, test that the spaces are stripped.
4 | #define a $
5 | #define b ( $+)
6 | #define c $ +
7 | #define d abc def + ghi ()
8 | #define e $
9 | #define f $
10 | #define g $
11 | #define h $
12 | #define i $
13 | #define j $
14 | #define k $
15 | #define l $
16 | #define m $
17 | #define n $
18 | #define o $
19 | #define p $
20 |
21 | int foo() {
22 | int var1 = 1, var2 = 2, var3 = 3, var4 = 4, var5 = 5, var6 = 6;
23 | int var7 = 7, var8 = 8, var9 = 9, var10 = 10, var11 = 11, var12 = 12;
24 | return var1 + var5 + var12;
25 | }
26 |
--------------------------------------------------------------------------------
/tests/unit/many_variables.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | #endif
6 |
7 | #else // if SHADER_MINIFIER_IMPL
8 |
9 | // tests/unit/many_variables.frag
10 | "int L(float i,float L,float J,float I,float H,float G,float F,float E,float D,float C,float B,float A)"
11 | "{"
12 | "i=G;"
13 | "int t=1,f=2,r=3,K=4;"
14 | "K=5;"
15 | "r=6;"
16 | "f=7;"
17 | "t=8;"
18 | "i=A;"
19 | "f=4;"
20 | "f=5;"
21 | "int M=6,N=7,O=8;"
22 | "float P=0.;"
23 | "int Q=1,R=2,S=3,T=4,U=5,V=6,W=7,X=8;"
24 | "float Y=0.;"
25 | "int Z=1,_=2,a=3,b=4,c=5,d=6,e=7,g=8;"
26 | "return t+O+X+g;"
27 | "}",
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/tests/unit/many_variables.frag:
--------------------------------------------------------------------------------
1 | // Lots of identifiers to force Shader Minifier to use 2-char idents.
2 |
3 | int fct(float a, float b, float c, float d, float e, float f,
4 | float g, float h, float i, float j, float k, float l) {
5 | float m = a, n = b, o = c, p = d, q = e, r = f;
6 | int v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5, v6 = 6, v7 = 7, v8 = 8;
7 | float s = g, t = h, u = i, v = j, w = k, x = l;
8 | int a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8;
9 | float y = 0.;
10 | int b1 = 1, b2 = 2, b3 = 3, b4 = 4, b5 = 5, b6 = 6, b7 = 7, b8 = 8;
11 | float z = 0.;
12 | int c1 = 1, c2 = 2, c3 = 3, c4 = 4, c5 = 5, c6 = 6, c7 = 7, c8 = 8;
13 | return v8 + a8 + b8 + c8;
14 | }
15 |
--------------------------------------------------------------------------------
/tests/unit/minus-zero.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | #endif
6 |
7 | #else // if SHADER_MINIFIER_IMPL
8 |
9 | // tests/unit/minus-zero.frag
10 | "void main()"
11 | "{"
12 | "float a=0.;"
13 | "}",
14 |
15 | #endif
16 |
--------------------------------------------------------------------------------
/tests/unit/minus-zero.frag:
--------------------------------------------------------------------------------
1 | void main()
2 | {
3 | float a = -0.0;
4 | }
5 |
--------------------------------------------------------------------------------
/tests/unit/nested_if.frag:
--------------------------------------------------------------------------------
1 | float getNum(float a) {
2 | // else statement, so curly braces are required
3 | if (a > 0.0) {
4 | if (a > 1.0) return 1.0;
5 | }
6 | else return 0.0;
7 | return a;
8 | }
9 |
10 | int nested(bool x, bool y) {
11 | if (x) {
12 | // no else statement, so curly braces can be removed
13 | if (y) {
14 | return 0;
15 | }
16 | }
17 | return 2;
18 | }
19 |
20 | int no_braces1(int x) {
21 | if (x < 0) {
22 | for (;;)
23 | if (x > 0) {
24 | return 0;
25 | } else {
26 | return 1;
27 | }
28 | } else {
29 | return 2;
30 | }
31 | }
32 |
33 | int dangling_else(int x) {
34 | if (x < 0) {
35 | for (;;)
36 | if (x > 0) {
37 | return 0;
38 | } else {
39 | if (x == 0) return 1; // dangling
40 | }
41 | } else {
42 | return 2;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/unit/nested_if.frag.expected:
--------------------------------------------------------------------------------
1 | float getNum(float a)
2 | {
3 | if(a>0.)
4 | {
5 | if(a>1.)
6 | return 1.;
7 | }
8 | else
9 | return 0.;
10 | return a;
11 | }
12 | int nested(bool x,bool y)
13 | {
14 | if(x)
15 | if(y)
16 | return 0;
17 | return 2;
18 | }
19 | int no_braces1(int x)
20 | {
21 | if(x<0)
22 | for(;;)
23 | if(x>0)
24 | return 0;
25 | else
26 | return 1;
27 | else
28 | return 2;
29 | }
30 | int dangling_else(int x)
31 | {
32 | if(x<0)
33 | {
34 | for(;;)
35 | if(x>0)
36 | return 0;
37 | else if(x==0)
38 | return 1;
39 | }
40 | else
41 | return 2;
42 | }
43 |
--------------------------------------------------------------------------------
/tests/unit/numbers.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | uint large() { return 3812015801U; }
4 |
5 | vec4 f()
6 | {
7 | float oct = float(042) / 1000.;
8 | float oct2 = float(-071) / 1000.;
9 | int dec = 65535;
10 | int dec2 = -65536;
11 | float n = oct - oct2 + float(4 * 0x0) + float(dec + dec2) / 20.;
12 | return vec4(n,n,n,0.);
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/numbers.frag.expected:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | uint large()
4 | {
5 | return 3812015801U;
6 | }
7 | vec4 f()
8 | {
9 | float n=float(34)/1e3-float(-57)/1e3+float(0)+float(-1)/20.;
10 | return vec4(n,n,n,0);
11 | }
12 |
--------------------------------------------------------------------------------
/tests/unit/operators.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | #endif
6 |
7 | #else // if SHADER_MINIFIER_IMPL
8 |
9 | // tests/unit/operators.frag
10 | "#version 330\n"
11 | "float notmain()"
12 | "{"
13 | "int a=11,b=7,c=2;"
14 | "float f=1.4/3.,g=mod(8.,3.),z=122121;"
15 | "return a+b+c+f+g+z;"
16 | "}"
17 | "int no_parens(int a,int b,int c)"
18 | "{"
19 | "return a+b+c+a+b*c;"
20 | "}"
21 | "int no_parens2(int a,int b,int c)"
22 | "{"
23 | "int d=b*c*a;"
24 | "return a-b+1-d+c;"
25 | "}"
26 | "int other(int a,int b,int c,int d)"
27 | "{"
28 | "return a*b*(c*d)*(a*b);"
29 | "}"
30 | "float f(float x)"
31 | "{"
32 | "x=(x+=1.,length(vec3(x)));"
33 | "return x*x*sin((x*=x,x));"
34 | "}"
35 | "float desugar_compound_assignment_for_ternary(float x)"
36 | "{"
37 | "x+=x*x;"
38 | "x=x==sqrt(x)?"
39 | "x+cos(x):"
40 | "x*sin(x);"
41 | "return x*x;"
42 | "}"
43 | "float cool_ops(float g)"
44 | "{"
45 | "g=0.;"
46 | "g+=g+++ ++g;"
47 | "g/=-g+g;"
48 | "g-=-g--- --g;"
49 | "g*=g+g;"
50 | "return g+--g-++g;"
51 | "}"
52 | "float swap_op_order(float g)"
53 | "{"
54 | "float a=g*(g--*g--),b=g*((g+2.)*(g+3.));"
55 | "return a*b*g;"
56 | "}"
57 | "mat2 dont_swap_op_order(float g)"
58 | "{"
59 | "return mat3x2(g)*(mat4x3(g)*mat2x4(g));"
60 | "}",
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/tests/unit/operators.frag:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | float notmain()
4 | {
5 | int a = 1 + 2 * 3 + 4;
6 | int b = 14 / 2;
7 | int c = 8 % 3;
8 |
9 | float f = 1.23456 * 2.1234;
10 | f = 1.4 / 2.;
11 | f = 1.4 / 3.;
12 | float g = mod(8., 3.);
13 |
14 | float z =
15 | (1. < 2. ? 1 : 2) +
16 | (1. > 2. ? 1 : 2) * 10 +
17 | (1. <= 2. ? 1 : 2) * 100 +
18 | (1. >= 2. ? 1 : 2) * 1000 +
19 | (1. == 2. ? 1 : 2) * 10000 +
20 | (1. != 2. ? 1 : 2) * 100000;
21 |
22 | return a+b+c+f+g+z;
23 | }
24 |
25 | int no_parens(int a, int b, int c) {
26 | return a + (b + c) + a + (b * c);
27 | }
28 |
29 | int no_parens2(int a, int b, int c) {
30 | int d = a*(b*c);
31 | return a - (b - 1) - (d - c);
32 | }
33 |
34 | int other(int a, int b, int c, int d) {
35 | return (a*b)*(c*d)*(a*b);
36 | }
37 |
38 | float f(float x)
39 | {
40 | float a = (x += 1.0, length(vec3(x)));
41 | return a*a*sin((a*=a, a));
42 | }
43 |
44 | float desugar_compound_assignment_for_ternary(float x)
45 | {
46 | x += x * x;
47 | if (x == sqrt(x))
48 | x += cos(x);
49 | else
50 | x *= sin(x);
51 | return x * x;
52 | }
53 |
54 | float cool_ops(float g)
55 | {
56 | float f = 0.0;
57 | f += +f++ + ++f;
58 | f /= -f - -f;
59 | f -= -f-- - --f;
60 | f *= +f + +f;
61 | f += --f + (- +(++f));
62 | return f;
63 | }
64 |
65 | float swap_op_order(float g)
66 | {
67 | float a = g*((g--)*(g--));
68 | float b = g*((g+2.)*(g+3.));
69 | return a*b*g;
70 | }
71 |
72 | mat2 dont_swap_op_order(float g)
73 | {
74 | return mat3x2(g) * (mat4x3(g) * mat2x4(g));
75 | }
76 |
--------------------------------------------------------------------------------
/tests/unit/overload.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef OVERLOAD_EXPECTED_
3 | # define OVERLOAD_EXPECTED_
4 | # define VAR_ZH "t"
5 | # define VAR__V "x"
6 | # define VAR_a_ "i"
7 | # define VAR_outputvar "f"
8 | # define VAR_stopinlining "v"
9 |
10 | const char *overload_frag =
11 | "#version 330\n"
12 | "uniform sampler2D x;"
13 | "uniform vec2 i;"
14 | "in vec2 t;"
15 | "out float v;"
16 | "out vec4 f;"
17 | "float h()"
18 | "{"
19 | "return v+.1;"
20 | "}"
21 | "float m()"
22 | "{"
23 | "return v+.2;"
24 | "}"
25 | "float h(int t)"
26 | "{"
27 | "return v+.3;"
28 | "}"
29 | "float m(float t)"
30 | "{"
31 | "return v+.4;"
32 | "}"
33 | "float h(bool t)"
34 | "{"
35 | "return v+.5;"
36 | "}"
37 | "float h(int t,int m)"
38 | "{"
39 | "return v+.6;"
40 | "}"
41 | "float h(int t,int m,int x,int f)"
42 | "{"
43 | "return v+.7;"
44 | "}"
45 | "float h(sampler2D t,float v)"
46 | "{"
47 | "return texelFetch(t,ivec2(255.*v)%256,0).x;"
48 | "}"
49 | "float h(sampler2D t,vec2 v)"
50 | "{"
51 | "return texelFetch(t,ivec2(255.*v)%256,0).x;"
52 | "}"
53 | "float h(sampler2D t,vec3 v)"
54 | "{"
55 | "float m=texelFetch(t,ivec2(255.*v.yz)%256,0).x;"
56 | "return texelFetch(t,ivec2(255.*v.x,255.*m)%256,0).x;"
57 | "}"
58 | "void main()"
59 | "{"
60 | "float v=0.,D=h(true)+h(0,1)-h(0,1,2,3),F=h(x,i*t);"
61 | "f=vec4(h()+2.*h(0),2.*m(1.2)-m(),D,F+v++);"
62 | "}";
63 |
64 | #endif // OVERLOAD_EXPECTED_
65 |
--------------------------------------------------------------------------------
/tests/unit/overload.frag:
--------------------------------------------------------------------------------
1 | #version 330
2 | uniform sampler2D _V;
3 | uniform vec2 a_;
4 | in vec2 ZH;
5 | out float stopinlining;
6 | out vec4 outputvar;
7 |
8 | float f1() { return stopinlining+0.1; }
9 | float f2(void) { return stopinlining+0.2; }
10 | float f1(int x) { return stopinlining+0.3; }
11 | float f2(float y) { return stopinlining+0.4; }
12 | float f3(bool b) { return stopinlining+0.5; }
13 | float f3(int a, int b) { return stopinlining+0.6; }
14 | float f3(int a, int b, int c, int d) { return stopinlining+0.7; }
15 |
16 | float hashTex(sampler2D _V, float p)
17 | {
18 | return texelFetch(_V, ivec2(255. * p) % 256, 0).r;
19 | }
20 | float hashTex(sampler2D _V, vec2 p)
21 | {
22 | return texelFetch(_V, ivec2(255. * p) % 256, 0).r;
23 | }
24 | float hashTex(sampler2D _V, vec3 p)
25 | {
26 | float h = texelFetch(_V, ivec2(255. * p.yz) % 256, 0).r;
27 | return texelFetch(_V, ivec2(255. * p.x, 255. * h) % 256, 0).r;
28 | }
29 |
30 | void main()
31 | {
32 | float stopinlining = 0.;
33 | float a = f1() + 2. * f1(0);
34 | float b = 2. * f2(1.2) - f2();
35 | float c = f3(true) + f3(0, 1) - f3(0, 1, 2, 3);
36 | float d = hashTex(_V, a_ * ZH);
37 | outputvar=vec4(a,b,c,d+stopinlining++);
38 | }
39 |
--------------------------------------------------------------------------------
/tests/unit/pi.frag:
--------------------------------------------------------------------------------
1 | #version 400
2 |
3 | out vec4 fragColor;
4 |
5 | void main() {
6 | double pi = 3.141592653589793;
7 | double minus_pi = -3.141592653589793;
8 | double tau = 6.283185307179586;
9 | double minus_tau = -6.283185307179586;
10 | double half_pi = 1.5707963267948966;
11 | double minus_half_pi = -1.5707963267948966;
12 | double precise_pi = 3.14159265358979323846264338327950288419716939937510;
13 | fragColor = vec4(pi+minus_pi+tau+minus_tau+half_pi+minus_half_pi+precise_pi);
14 | }
15 |
--------------------------------------------------------------------------------
/tests/unit/pi.frag.expected:
--------------------------------------------------------------------------------
1 | #version 400
2 |
3 | out vec4 fragColor;
4 | void main()
5 | {
6 | double pi=acos(-1.),minus_pi=-acos(-1.),tau=2.*acos(-1.),minus_tau=-2.*acos(-1.),half_pi=acos(0.),minus_half_pi=-acos(0.),precise_pi=acos(-1.);
7 | fragColor=vec4(pi+minus_pi+tau+minus_tau+half_pi+minus_half_pi+precise_pi);
8 | }
9 |
--------------------------------------------------------------------------------
/tests/unit/precedence.frag:
--------------------------------------------------------------------------------
1 | float foo(bool a, bool b, bool c) {
2 | return (a?b:c)?.1:.2;
3 | }
4 |
5 | void main()
6 | {
7 | float f1 = 2. * 3. / 4. - 5. / 6.;
8 | float f2 = (true ? false ? 1. : 2. : 3. * 4.) * 5.;
9 | float f3 = 4. * (false ? (true ? 1. : 2.) : 3.);
10 | float f4 = float((2+3) * (4+5*6) - (7-8));
11 | float f5 = (2.+f1) * (4.+f2*6.) - (7.-f3);
12 |
13 | float n = 1. / (f1 + f2 + f3);
14 | float o = 1. / (f4 * f5);
15 |
16 | gl_FragColor=vec4(n,o,n,0.);
17 | }
18 |
--------------------------------------------------------------------------------
/tests/unit/precedence.frag.expected:
--------------------------------------------------------------------------------
1 | float foo(bool a,bool b,bool c)
2 | {
3 | return(a?
4 | b:
5 | c)?
6 | .1:
7 | .2;
8 | }
9 | void main()
10 | {
11 | float f1=1.5-5./6.,n=1./(f1+10.+12.);
12 | gl_FragColor=vec4(n,1./(float(171)*((2.+f1)*64.-7.+12.)),n,0);
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/precision.frag:
--------------------------------------------------------------------------------
1 | #version 300 es
2 |
3 | precision highp float;
4 | precision mediump int;
5 | precision lowp sampler2D;
6 | precision lowp samplerCube;
7 |
8 | lowp float foo(lowp float bar) {
9 | return 1.0;
10 | }
11 |
--------------------------------------------------------------------------------
/tests/unit/precision.frag.expected:
--------------------------------------------------------------------------------
1 | #version 300 es
2 |
3 | precision highp float;
4 | precision mediump int;
5 | precision lowp sampler2D;
6 | precision lowp samplerCube;
7 | lowp float f(lowp float f)
8 | {
9 | return 1.;
10 | }
11 |
--------------------------------------------------------------------------------
/tests/unit/preprocess.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #define DEF bar
4 | #define foo() bar
5 | #
6 |
7 | #ifdef DEF
8 | void keep_ifdef() {}
9 | #endif
10 |
11 | #ifdef UNKNOWN
12 | void remove_ifdef() {}
13 | #endif
14 |
15 | #ifdef DEF
16 | # ifdef DEF // nested
17 | # ifdef UNKNOWN
18 | # ifdef DEF
19 | int remove_this_line;
20 | # endif
21 | int remove_this_line_too;
22 | # endif
23 | void keep_nested() {}
24 | # endif
25 | void keep_outernest() {}
26 | #endif
27 |
28 | #ifdef UNKNOWN
29 | int this_is_removed;
30 | #else
31 | void keep_else() {}
32 | #endif
33 |
34 | #undef DEF
35 | #ifdef DEF
36 | int removed_undefd() {}
37 | #endif
38 |
39 | void end() {}
40 |
--------------------------------------------------------------------------------
/tests/unit/preprocess.frag.expected:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #define DEF bar
4 |
5 | #define foo()bar
6 |
7 | void keep_ifdef()
8 | {}
9 | void keep_nested()
10 | {}
11 | void keep_outernest()
12 | {}
13 | void keep_else()
14 | {}
15 |
16 | #undef DEF
17 |
18 | void end()
19 | {}
20 |
--------------------------------------------------------------------------------
/tests/unit/preprocess_if.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #define DEF 1
4 |
5 | #if 1
6 | void keep_if() {}
7 | #endif
8 |
9 | #if 0
10 | void remove_if() {}
11 | #endif
12 |
13 | #if DEF
14 | # if 0
15 | int remove_this_line;
16 | # elif 1
17 | void keep_nested() {}
18 | # endif
19 | void also_keep() {}
20 | # endif
21 |
22 | void end() {}
23 |
--------------------------------------------------------------------------------
/tests/unit/preprocess_if.frag.expected:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | #define DEF 1
4 |
5 | void keep_if()
6 | {}
7 |
8 | #if DEF
9 |
10 | void keep_nested()
11 | {}
12 | void also_keep()
13 | {}
14 |
15 | #endif
16 |
17 | void end()
18 | {}
19 |
--------------------------------------------------------------------------------
/tests/unit/qualifiers.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef QUALIFIERS_EXPECTED_
3 | # define QUALIFIERS_EXPECTED_
4 | # define VAR_foo "f"
5 |
6 | const char *qualifiers_frag =
7 | "#version 130\n"
8 | "in vec3 f;"
9 | "float v(float f)"
10 | "{"
11 | "return f;"
12 | "}"
13 | "float M(const float f)"
14 | "{"
15 | "return f;"
16 | "}"
17 | "float L(inout float f)"
18 | "{"
19 | "return f;"
20 | "}";
21 |
22 | #endif // QUALIFIERS_EXPECTED_
23 |
--------------------------------------------------------------------------------
/tests/unit/qualifiers.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | in vec3 foo;
4 |
5 | float f(in float a) {
6 | return a;
7 | }
8 |
9 | float g(const in float a) {
10 | return a;
11 | }
12 |
13 | float h(inout float a) {
14 | return a;
15 | }
16 |
--------------------------------------------------------------------------------
/tests/unit/rename_conflict.frag:
--------------------------------------------------------------------------------
1 | // test with --no-renaming-list i
2 |
3 | int foo(int a, int d)
4 | {
5 | return a + 1;
6 | }
7 |
8 | int i()
9 | {
10 | foo(0, 3);
11 | return 1;
12 | }
13 |
14 | int bar(int b, int c, int d)
15 | {
16 | return b + i();
17 | }
18 |
--------------------------------------------------------------------------------
/tests/unit/reuse-var.frag:
--------------------------------------------------------------------------------
1 | float simple_var_decl_reuse(float x)
2 | {
3 | float a = 1.+x;
4 | int b = 3+int(x);
5 | vec3 sep = vec3(0.); // prevents squeezeConsecutiveDeclarations
6 | int b2 = 5+int(a);
7 | float c = a;
8 | sep += vec3(0.); // prevents squeezeConsecutiveDeclarations
9 | float c2 = 9.+a;
10 | int d = 3+b+b2;
11 | sep += vec3(0.); // prevents squeezeConsecutiveDeclarations
12 | int d2 = d+b2-b;
13 | float e = c*c2;
14 | sep += vec3(0.); // prevents squeezeConsecutiveDeclarations
15 | float e2 = 4.-c-c2;
16 | int f = 3*d*d2;
17 | sep += vec3(0.); // prevents squeezeConsecutiveDeclarations
18 | int f2 = 4/d2-d;
19 | float g = e-float(f)+e2;
20 | int g2 = int(4.-g+e2+e);
21 | int h = 3*f-f2;
22 | sep += vec3(0.); // prevents squeezeConsecutiveDeclarations
23 | int h2 = 7*f2-f;
24 | return length(sep)+float(h*h2)*g*float(g2)*x + float(g2/h2-h);
25 | }
26 | float multidecl_var_decl_reuse(float x)
27 | {
28 | float a = 1.+x;
29 | int b = 3+int(x), b2 = 5+int(a);
30 | float c = a, c2 = 9.+a;
31 | int d = 3+b+b2, d2 = d+b2-b;
32 | float e = c*c2, e2 = 4.-c-c2;
33 | int f = 3*d*d2, f2 = 4/d2-d;
34 | float g = e-float(f)+e2, g2 = 4.-g+e2+e;
35 | int h = 3*f-f2, h2 = 7*f2-f;
36 | return float(h*h2)*g*g2*x + g2/float(h2-h);
37 | }
38 | vec2 map (in vec3 p)
39 | {
40 | vec2 tun = p.xy;
41 | tun.x++;
42 | vec3 q = vec3(tun,p.z);
43 | vec3 fs = p - vec3(2.85,0,0);
44 | vec2 center = floor(fs.xz) + .5;
45 | float height = .0465;
46 | height = smoothstep(.001,1.,height);
47 | float me = dot(fs-vec3(0,0,center.y), vec3(.05,.150+height,.25));
48 | float next = dot(fs-vec3(0,0,center.y), vec3(.05,.001+height,.25));
49 | float dlt = min(me, next);
50 | return vec2(dlt*dlt);
51 | }
52 |
--------------------------------------------------------------------------------
/tests/unit/reuse-var.frag.expected:
--------------------------------------------------------------------------------
1 | float simple_var_decl_reuse(float x)
2 | {
3 | float a=1.+x;
4 | int b=3+int(x);
5 | vec3 sep=vec3(0);
6 | int b2=5+int(a);
7 | float c=a;
8 | sep+=vec3(0);
9 | a+=9.;
10 | int d=3+b+b2;
11 | sep+=vec3(0);
12 | b2=d+b2-b;
13 | float e=c*a;
14 | sep+=vec3(0);
15 | c=4.-c-a;
16 | b=3*d*b2;
17 | sep+=vec3(0);
18 | d=4/b2-d;
19 | a=e-float(b)+c;
20 | b2=int(4.-a+c+e);
21 | int h=3*b-d;
22 | sep+=vec3(0);
23 | d=7*d-b;
24 | return length(sep)+float(h*d)*a*float(b2)*x+float(b2/d-h);
25 | }
26 | float multidecl_var_decl_reuse(float x)
27 | {
28 | float a=1.+x;
29 | int b=3+int(x),b2=5+int(a);
30 | float c=a;
31 | a+=9.;
32 | int d=3+b+b2;
33 | b=d+b2-b;
34 | float e=c*a;
35 | c=4.-c-a;
36 | b2=3*d*b;
37 | d=4/b-d;
38 | a=e-float(b2)+c;
39 | e+=4.-a+c;
40 | b=3*b2-d;
41 | d=7*d-b2;
42 | return float(b*d)*a*e*x+e/float(d-b);
43 | }
44 | vec2 map(vec3 p)
45 | {
46 | vec2 tun=p.xy;
47 | tun.x++;
48 | vec3 fs=p-vec3(2.85,0,0);
49 | tun=floor(fs.xz)+.5;
50 | float height=smoothstep(.001,1.,.0465);
51 | height=min(dot(fs-vec3(0,0,tun.y),vec3(.05,.15+height,.25)),dot(fs-vec3(0,0,tun.y),vec3(.05,.001+height,.25)));
52 | return vec2(height*height);
53 | }
54 |
--------------------------------------------------------------------------------
/tests/unit/shadowing.frag:
--------------------------------------------------------------------------------
1 | float f(float g)
2 | {
3 | float f = 0.0;
4 | f += f++ + ++f;
5 | return f;
6 | }
7 | float glob;
8 | float g(float f)
9 | {
10 | {
11 | f++;
12 | float f = f + 1.0, g = 9.0;
13 | glob+=f+=g;
14 | }
15 | return f;
16 | }
17 |
18 | #define noinline_random 4
19 |
20 | int m1()
21 | {
22 | int x = 1;
23 | if (noinline_random > 3)
24 | {
25 | int x = 2, y = x; // y is initialized to 2
26 | return y;
27 | }
28 | }
29 |
30 | struct S{ int x; };
31 |
32 | S m2()
33 | {
34 | S S = S(0); // 'S' is only visible as a struct and constructor
35 | return S; // 'S' is now visible as a variable
36 | }
37 |
38 | int m4(int k)
39 | {
40 | //int k = k + 3; // redeclaration error of the name k
41 | {
42 | int k = k + 3; // 2nd k is parameter, initializing nested first k
43 | int m = k; // use of new k, which is hiding the parameter
44 | }
45 | return k;
46 |
47 | //int x = x; // Error if x has not been previously defined.
48 | // If the previous definition of x was in this
49 | // same scope, this causes a redeclaration error.
50 | }
51 |
52 | float m5(float k)
53 | {
54 | float m = 9.;
55 | m = 14.;
56 | {
57 | float k = k + 3.; // 2nd k is parameter, initializing nested first k
58 | m = k; // use of new k, which is hiding the parameter
59 | }
60 | return k + 2. * m;
61 | }
62 |
63 | float glo;
64 | void m6()
65 | {
66 | glo += m5(55.);
67 | }
68 |
--------------------------------------------------------------------------------
/tests/unit/shadowing.frag.expected:
--------------------------------------------------------------------------------
1 | float f(float g)
2 | {
3 | g=0.;
4 | return g+g+++ ++g;
5 | }
6 | float glob;
7 | float g(float f)
8 | {
9 | {
10 | f++;
11 | float f=f+1.;
12 | glob+=f+=9.;
13 | }
14 | return f;
15 | }
16 |
17 | #define noinline_random 4
18 |
19 | int m1()
20 | {
21 | if(noinline_random>3)
22 | return 2;
23 | }
24 | struct S{int x;};
25 | S m2()
26 | {
27 | return S(0);
28 | }
29 | int m4(int k)
30 | {
31 | return k;
32 | }
33 | float glo;
34 | void m6()
35 | {
36 | glo+=171.;
37 | }
38 |
--------------------------------------------------------------------------------
/tests/unit/simple.frag:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | void main()
4 | {
5 | gl_FragColor = vec4(0.2, 0.4, 0.6, 0.);
6 | }
7 |
--------------------------------------------------------------------------------
/tests/unit/simplify.expected:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | int i;
4 | float bar(float x)
5 | {
6 | float a=6.+x,b=34.+x,arr[2]=float[2](5.,float(float[2](7.,8.).length()));
7 | x=(a*=10,a*=20,a*=30,b++,arr[1]+arr[i++]);
8 | return a+b+x;
9 | }
10 | float baz(float a)
11 | {
12 | a=a+4.+sin(a);
13 | a=a+5.+sin(a);
14 | return a-a-a;
15 | }
16 | out vec3 outputvar;
17 | void notMain(float x)
18 | {
19 | outputvar.xyz=vec3(92)+vec3(bar(x)+baz(x));
20 | }
21 | int foo442(float x)
22 | {
23 | return x>=1.&&x<=8.?
24 | 1:
25 | 2;
26 | }
27 | in vec3 camPos;
28 | float len()
29 | {
30 | return length(camPos);
31 | }
32 | float main450()
33 | {
34 | return len()+len();
35 | }
36 |
--------------------------------------------------------------------------------
/tests/unit/simplify.frag:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | int i;
4 |
5 | float bar(float x)
6 | {
7 | float a = x;
8 | a = 6.;
9 | a = a + x;
10 |
11 | float b = x;
12 | b = b + x;
13 | b = 34.;
14 | b = b + x;
15 |
16 | float arr[2] = float[2](7.,8.);
17 | arr = float[2](5.,float(arr.length()));
18 |
19 | float m = 14.+length(vec3(sin(a *= 10), sin(a *= 20), sin(a *= 30)))+b++;
20 | m = arr[1] + arr[i++];
21 |
22 | return a + b + m;
23 | }
24 | float baz(float a)
25 | {
26 | float b = a + 4.;
27 | b += sin(a);
28 | float c = b + 5.;
29 | c += sin(b);
30 | return c + (-(c - -c));
31 | }
32 |
33 | int n = 2;
34 | float y = 47.;
35 | out vec3 outputvar;
36 |
37 | float foo(float a) { if (n == 1) return 0.; if (n == 2) return a; return 1.; }
38 | float foo(float a, float b) { if (y > a) return 0.; if (y < b) return a; return 1.; }
39 |
40 | void notMain(float x) {
41 | vec3 v = vec3(foo(42.) + foo(50., 70.));
42 | outputvar.rgb = v + vec3(bar(x) + baz(x));
43 | }
44 |
45 | // #442: function inlining when a parameter is read more than once, but the argument expr is pure and trivial, like a variable that's read (but not written)
46 | bool IsMoto(float mid) {
47 | return mid>=1.&&mid<=8.;
48 | }
49 | int foo442(float x) {
50 | if (IsMoto(x)) return 1;
51 | return 2;
52 | }
53 |
54 | // #450: argument inlining of read-only globals
55 | in vec3 camPos;
56 | float len(vec3 pos) {
57 | return length(pos);
58 | }
59 | float main450() {
60 | float a = len(camPos);
61 | float b = len(camPos);
62 | return a + b;
63 | }
64 |
--------------------------------------------------------------------------------
/tests/unit/smoothstep.frag:
--------------------------------------------------------------------------------
1 | vec2 resolution = vec2(1., 1.);
2 |
3 | void main()
4 | {
5 | vec2 ref = vec2(1.2, 3.4);
6 | vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
7 | float s = sqrt( dot(p,p) );
8 |
9 | s = smoothstep(0.0,1.0,s);
10 |
11 | float ao = smoothstep(0.0,0.4,s) - 1.0 * smoothstep(0.4,0.7,s);
12 |
13 | float dom = 1.0 * smoothstep( (-0.1), (0.1), ref.y); // https://github.com/laurentlb/Shader_Minifier/issues/7
14 | }
15 |
--------------------------------------------------------------------------------
/tests/unit/struct.frag:
--------------------------------------------------------------------------------
1 | #version 460
2 | // struct declaration in TypeDecl
3 | struct MarchData { // newName
4 | float dist;
5 | vec3 col;
6 | float spec;
7 | };
8 | // struct in TLDecl
9 | MarchData m;
10 | uniform MyInterfaceBlock
11 | {
12 | // struct in interface block field
13 | MarchData march;
14 | /* Not allowed, at least on shadertoy.
15 | // anonymous struct declaration in interface block field
16 | struct {
17 | // struct identifier use in field in interface block
18 | MarchData abc;
19 | } struc;
20 | */
21 | };
22 | // struct identifier use in FunctionType.retType
23 | MarchData struct_as_ret()
24 | {
25 | return m;
26 | }
27 | // struct identifier use in FunctionType.args
28 | int struct_as_arg(MarchData m)
29 | {
30 | return 1;
31 | }
32 | int struct_uses() {
33 | // struct identifier use in Stmt.Decl
34 | MarchData m;
35 | // struct field access
36 | m.dist = 1.;
37 | m.spec = m.dist / 2.;
38 | // struct identifier use in constructor
39 | m = MarchData(1., vec3(1), m.spec);
40 | // anonymous struct declaration in Stmt.Decl
41 | struct {
42 | // struct identifier use in field in local
43 | MarchData abc;
44 | } s;
45 | // struct identifier use in Stmt.Decl
46 | for (MarchData m2; true; ) break;
47 | // anonymous struct declaration in Stmt.ForD
48 | for (struct {
49 | // struct identifier use in field in local
50 | MarchData abc;
51 | } s; true; ) break;
52 | return int(m.col.x + s.abc.dist + march.spec);
53 | }
54 |
55 | // anonymous struct declaration at top level
56 | struct {
57 | // struct identifier use in field in global struct
58 | MarchData abc;
59 | } s2;
60 |
61 | // bug test
62 | float v(vec4 w)
63 | {
64 | float MarchData = w.x-4.0; // reuse type name as var
65 | return w.w + MarchData*MarchData; // don't rename field `.w`
66 | }
67 |
68 | struct Foo {int A; int B;};
69 | struct Bar {int A; int C; int B;};
70 |
71 | Foo foo;
72 | Bar bar;
73 |
74 | void main() {
75 | foo.A = 1;
76 | foo.B = 2;
77 | bar.A = 3;
78 | bar.C = 4;
79 | bar.B = 5;
80 | }
81 |
82 | struct Baz {int A; int B;} baz;
83 | struct {int A; int B;}; // why is this even legal
84 |
--------------------------------------------------------------------------------
/tests/unit/struct.frag.expected:
--------------------------------------------------------------------------------
1 | #version 460
2 |
3 | struct r{float t;vec3 r;float n;};
4 | r e;
5 | uniform MyInterfaceBlock{r k;};
6 | r M()
7 | {
8 | return e;
9 | }
10 | int M(r M)
11 | {
12 | return 1;
13 | }
14 | int i()
15 | {
16 | r s;
17 | s.t=1.;
18 | s.n=s.t/2.;
19 | s=r(1.,vec3(1),s.n);
20 | struct{r u;} e;
21 | for(r e;true;)
22 | break;
23 | for(struct{r u;} e;true;)
24 | break;
25 | return int(s.r.x+e.u.t+k.n);
26 | }
27 | struct{r u;} m;
28 | float M(vec4 s)
29 | {
30 | float e=s.x-4.;
31 | return s.w+e*e;
32 | }
33 | struct B{int i;int e;};
34 | struct I{int i;int c;int e;};
35 | B f;
36 | I s;
37 | void main()
38 | {
39 | f.i=1;
40 | f.e=2;
41 | s.i=3;
42 | s.c=4;
43 | s.e=5;
44 | }
45 | struct O{int i;int e;} N;
46 |
--------------------------------------------------------------------------------
/tests/unit/struct2.frag:
--------------------------------------------------------------------------------
1 |
2 | float stretch, gunsUp, gunsForward, edWalk, edTwist, edDown, edShoot, doorOpen, glow;
3 |
4 | struct MarchData {
5 | // initially this looked like `float A,Z,e,R,T,Y,u,i,o,P,m,l,k,j,h,G,f,S,d,Q,W,X,c,v,B,n,_;`
6 | // but glslang has a bug and can't parse it: https://github.com/KhronosGroup/glslang/issues/3931
7 | vec3 mat;
8 | float specPower;
9 | float A;
10 | int Z;
11 | float e;
12 | int R;
13 | float T;
14 | int Y;
15 | float u;
16 | int i;
17 | float o;
18 | int P;
19 | float m;
20 | int l;
21 | float k;
22 | int j;
23 | float h;
24 | int G;
25 | float f;
26 | int S;
27 | float d;
28 | int Q;
29 | float W;
30 | int X;
31 | float c;
32 | int v;
33 | float B;
34 | int n;
35 | float _;
36 | int __;
37 | float a1;
38 | int a2;
39 | float a3;
40 | int a4;
41 | float a5;
42 | int a6;
43 | float a7;
44 | int a8;
45 | float a9;
46 | int a10;
47 | vec2 a11;
48 | float a12;
49 | int a13;
50 | float a14;
51 | int a15;
52 | float a16;
53 | int a17;
54 | float a18;
55 | int a19;
56 | float a20;
57 | int a21;
58 | float a22;
59 | int a23;
60 | float a24;
61 | int a25;
62 | float a26;
63 | int a27;
64 | float a28;
65 | int a29;
66 | float a30;
67 | };
68 |
69 | struct AprilData {
70 | vec3 mat;
71 | float specPower;
72 | float A;
73 | float Z;
74 | int e;
75 | float R;
76 | int T;
77 | float Y;
78 | int u;
79 | float i;
80 | int o;
81 | float P;
82 | int m;
83 | float l;
84 | int k;
85 | float j;
86 | int h;
87 | float G;
88 | int f;
89 | float S;
90 | int d;
91 | float Q;
92 | int W;
93 | float X;
94 | int c;
95 | float v;
96 | int B;
97 | float a1;
98 | int n;
99 | float a2;
100 | int a3;
101 | float a4;
102 | int a5;
103 | float a6;
104 | int a7;
105 | float a8;
106 | int a9;
107 | float a10;
108 | vec2 a11;
109 | float a12;
110 | int a13;
111 | float a14;
112 | int a15;
113 | float a16;
114 | int a17;
115 | float a18;
116 | int a19;
117 | float a20;
118 | vec2 a21;
119 | vec3 a22;
120 | int a23;
121 | float a24;
122 | int a25;
123 | float a26;
124 | int a27;
125 | float a28;
126 | int a29;
127 | float a30;
128 | };
129 |
130 | void set(inout MarchData mat, AprilData a) {
131 | mat.mat = vec3(0.36, 0.45, 0.5);
132 | mat.specPower = 30.0;
133 | mat.d = 1.0;
134 | a.a11 = vec2(a.a1, a.a2);
135 | a.a21 = a.a22.yx;
136 | }
137 |
138 | void mainImage(out vec4 fragColor, in vec2 fragCoord) { fragColor = vec4(1.0); }
139 |
--------------------------------------------------------------------------------
/tests/unit/struct2.frag.expected:
--------------------------------------------------------------------------------
1 | float m,v,I,R,Q,P,O,N,x;
2 | struct L{vec3 t;float o;float a;int l;float f;int i;float n;int v;float c;int e;float u;int s;float r;int m;float d;int I;float y;int x;float g;int _;float Z;int Y;float X;int W;float V;int U;float T;int S;float R;int Q;float P;int O;float N;int M;float L;int K;float J;int H;float G;int F;vec2 E;float D;int C;float B;int A;float z;int w;float q;int p;float k;int j;float h;int b;float aa;int ab;float ac;int ad;float ae;int af;float ag;};
3 | struct K{vec3 t;float o;float a;float l;int f;float i;int n;float v;int c;float e;int u;float s;int r;float m;int d;float I;int y;float x;int g;float _;int Z;float Y;int X;float W;int V;float U;int T;float P;int S;float O;int N;float M;int L;float K;int J;float H;int G;float F;vec2 E;float D;int C;float B;int A;float z;int w;float q;int p;float k;vec2 j;vec3 h;int b;float aa;int ab;float ac;int ad;float ae;int af;float ag;};
4 | void e(inout L f,K i)
5 | {
6 | f.t=vec3(.36,.45,.5);
7 | f.o=30.;
8 | f.Z=1.;
9 | i.E=vec2(i.P,i.O);
10 | i.j=i.h.yx;
11 | }
12 | void mainImage(out vec4 v,vec2 i)
13 | {
14 | v=vec4(1);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/unit/struct_inheritance.hlsl:
--------------------------------------------------------------------------------
1 | template
2 | struct bool_literal {
3 | static const bool value = Value;
4 | };
5 |
6 | struct true_type : bool_literal {};
7 | struct false_type : bool_literal {};
8 |
9 | struct is_floating_point : false_type {};
10 | template <> struct is_floating_point : true_type {};
11 | template <> struct is_floating_point : true_type {};
12 |
--------------------------------------------------------------------------------
/tests/unit/struct_inheritance.hlsl.expected:
--------------------------------------------------------------------------------
1 | template
2 | struct bool_literal{static const bool value=Value;};
3 | struct true_type:bool_literal{};
4 | struct false_type:bool_literal{};
5 | struct is_floating_point:false_type{};
6 | template<>
7 | struct is_floating_point:true_type{};
8 | template<>
9 | struct is_floating_point:true_type{};
10 |
11 |
--------------------------------------------------------------------------------
/tests/unit/suffix.frag:
--------------------------------------------------------------------------------
1 | #version 400
2 |
3 | void main()
4 | {
5 | uint n1 = 41u;
6 | uint n2 = 42U;
7 | double f1 = 1.20LF;
8 | float f2 = 3.F;
9 | double f3 = .0003lf;
10 | float f7 = 2E-9f;
11 |
12 | float foo = - (- 2.f);
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/switch.expected:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | void h()
4 | {
5 | switch(42){
6 | case 42:
7 | break;
8 | }
9 | }
10 |
11 | #define GOOD 42
12 |
13 | void G()
14 | {
15 | switch(42){
16 | case GOOD:
17 | break;
18 | }
19 | }
20 | void G(int G)
21 | {
22 | switch(G){
23 | case 0:
24 | break;
25 | }
26 | }
27 | void h(int G)
28 | {
29 | switch(G+42){
30 | case 0:
31 | break;
32 | }
33 | }
34 | float D()
35 | {
36 | switch(42){
37 | case 42:
38 |
39 |
40 | return 6.6;
41 | case 43:
42 |
43 | return 7.7;
44 | default:
45 | return 0.;
46 | }
47 | }
48 | void b()
49 | {}
50 | int D(int G)
51 | {
52 | switch(G){
53 | case 1:
54 | b();
55 | case 2:
56 | b();
57 | case 3:
58 | break;
59 | case 4:
60 | b();
61 | b();
62 | break;
63 | case 5:
64 | b();
65 | b();
66 | return 18;
67 | }
68 | return 1;
69 | }
70 |
--------------------------------------------------------------------------------
/tests/unit/switch.frag:
--------------------------------------------------------------------------------
1 | #version 130
2 |
3 | void switchConst() {
4 | switch (42) {
5 | case 42:
6 | break;
7 | }
8 | }
9 |
10 | #define GOOD 42
11 | void switchDefine() {
12 | switch (42) {
13 | case GOOD:
14 | break;
15 | }
16 | }
17 |
18 | void switchArg(in int someArg) {
19 | switch (someArg) {
20 | case 0:
21 | break;
22 | }
23 | }
24 |
25 | void switchExpr(in int someArg) {
26 | switch (someArg + 42) {
27 | case 0:
28 | break;
29 | }
30 | }
31 |
32 | float switchMultiple() {
33 | switch (42) {
34 | case 42:
35 | float someVar = 4.2;
36 | float otherVar = 2.4;
37 | return someVar + otherVar;
38 | case 43:
39 | float anotherVar = 4.3;
40 | return anotherVar + 3.4;
41 | default:
42 | return 0.0;
43 | }
44 | }
45 |
46 | const int LBL1 = 1, LBL2 = 2, LBL3 = 3, LBL4 = 4, LBL5 = 5;
47 | void foo() {}
48 |
49 | int switchStringLabels(int value)
50 | {
51 | switch (value)
52 | {
53 | case LBL1: foo();
54 | case LBL2: foo();
55 | case LBL3: { foo(); break; }
56 | case LBL4: foo(); foo(); break;
57 | case LBL5: foo(); foo(); return 18;
58 | }
59 | return 1;
60 | }
61 |
--------------------------------------------------------------------------------
/tests/unit/symbols.frag:
--------------------------------------------------------------------------------
1 | # extension GL_EXT_gpu_shader4 : enable
2 | # define TEST
3 | # ifndef A
4 | # endif
5 |
6 | vec3 color; // TLDecl
7 |
8 | struct s { // TypeDecl
9 | vec4 n, f;
10 | bool ok;
11 | };
12 |
13 | float sdf(vec3 p) { // Function
14 | color = vec3(1.);
15 | return length(p) - 1.;
16 | }
17 |
18 | void main() {
19 | int ijk = 32;
20 | ijk += ijk;
21 | }
--------------------------------------------------------------------------------
/tests/unit/symbols.frag.expected:
--------------------------------------------------------------------------------
1 | #extension GL_EXT_gpu_shader4:enable
2 | #define TEST
3 | #ifndef A
4 | #endif
5 | vec3 color;struct s{vec4 n,f;bool ok;};float sdf(vec3 p){color=vec3(1);return length(p)-1.;}void main(){int ijk=32;ijk+=ijk;}
--------------------------------------------------------------------------------
/tests/unit/symbols.frag.sym:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laurentlb/shader-minifier/686983819d150b5fd30bb6fbf6d1e60652f2e52d/tests/unit/symbols.frag.sym
--------------------------------------------------------------------------------
/tests/unit/templates.hlsl:
--------------------------------------------------------------------------------
1 | template
2 | struct literal {
3 | T value;
4 | };
5 |
6 | template
7 | literal DoSomething(T arg, literal b) {
8 | T a = arg;
9 | literal c = b;
10 | return c;
11 | }
12 |
--------------------------------------------------------------------------------
/tests/unit/templates.hlsl.expected:
--------------------------------------------------------------------------------
1 | template
2 | struct literal{T value;};
3 | template
4 | literal DoSomething(T arg,literal b)
5 | {
6 | return b;
7 | }
8 |
--------------------------------------------------------------------------------
/tests/unit/ternary.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | // https://github.com/laurentlb/Shader_Minifier/issues/320
4 | float f0() {
5 | float a = 1., b = 1.;
6 | a == 1. ? b = 2. : b = 3.;
7 | return b; // 2
8 | }
9 |
10 | float f1() {
11 | float a = 1., b = 1.;
12 | a = true ? b = 2. : b = 3.;
13 | return a;
14 | }
15 |
16 | // Fix for #385
17 |
18 | out vec4 O;
19 | int k;
20 | void main() {
21 | int d=0,e=0;
22 | k==0 ? (sin(O.x),d=1) : (cos(O.x),e=2) ;
23 | O.x=float(d);
24 | O.y=float(e);
25 | }
26 | int f2() {
27 | k++ == 0 ? 1 : 2 ;
28 | return k;
29 | }
30 |
--------------------------------------------------------------------------------
/tests/unit/ternary.frag.expected:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | float f0()
4 | {
5 | return 2.;
6 | }
7 | float f1()
8 | {
9 | float b=1.;
10 | return b=2.;
11 | }
12 | out vec4 O;
13 | int k;
14 | void main()
15 | {
16 | int d=0,e=0;
17 | k==0?
18 | sin(O.x),d=1:
19 | (cos(O.x),e=2);
20 | O.x=float(d);
21 | O.y=float(e);
22 | }
23 | int f2()
24 | {
25 | k++;
26 | return k;
27 | }
28 |
--------------------------------------------------------------------------------
/tests/unit/unused_assignments.frag:
--------------------------------------------------------------------------------
1 | #version 330
2 | int gi = 0;
3 | void preventMergingConsecutiveAssignments() { gi++; }
4 |
5 | void shouldRemoveAllAssignments() {
6 | float x = 1.;
7 | preventMergingConsecutiveAssignments();
8 | x = sin(x); // this assignment is eventually unused
9 | preventMergingConsecutiveAssignments();
10 | x = cos(x); // this assignment is unused
11 | }
12 | float shouldNotRemoveAnyAssignment() {
13 | float x = gi;
14 | preventMergingConsecutiveAssignments();
15 | x = sin(x); // this assignment is NOT unused
16 | preventMergingConsecutiveAssignments();
17 | x = cos(x); // this assignment is NOT unused
18 | preventMergingConsecutiveAssignments();
19 | return x;
20 | }
21 |
22 | vec3 bewareThatAssignmentToAFieldIsNotAFullOverwrite(vec3 v) {
23 | v.x = 1.; // this assignment is unused
24 | preventMergingConsecutiveAssignments();
25 | v = vec3(0.3); // this assignment is NOT unused
26 | preventMergingConsecutiveAssignments();
27 | v.y = 0.; // this assignment is NOT unused
28 | preventMergingConsecutiveAssignments();
29 | v.x += 1.; // this assignment is unused
30 | preventMergingConsecutiveAssignments();
31 | vec3 vv = v.yyz; // this assignment is NOT unused
32 | preventMergingConsecutiveAssignments();
33 | vv.x++; // this assignment is unused
34 | preventMergingConsecutiveAssignments();
35 | vv = vec3(0.5); // this assignment is NOT unused
36 | preventMergingConsecutiveAssignments();
37 | return vv;
38 | }
39 |
40 | void dontRemoveAssignmentsToOutParams(in int i, inout int io, out int o) {
41 | i = 4; // this assignment is unused
42 | o = 5; // this assignment is NOT unused
43 | io = 6; // this assignment is NOT unused
44 | }
45 |
46 | void dontRemoveUnusedAssignmentToGlobal() {
47 | gi = 8;
48 | gi = 9;
49 | }
50 |
51 | float removePureDeclInit() {
52 | vec3 i = vec3(0);
53 | preventMergingConsecutiveAssignments();
54 | i = vec3(1);
55 | vec3 j = vec3(gi++);
56 | preventMergingConsecutiveAssignments();
57 | j = vec3(1);
58 | return i.x * j.y;
59 | }
60 |
61 | int onlyRemove99AndAThenReturn15() {
62 | int a=1,b=99;
63 | a*=a+a+a;
64 | {
65 | int a = a;
66 | preventMergingConsecutiveAssignments();
67 | a = 2;
68 | b=a*a;
69 | }
70 | preventMergingConsecutiveAssignments();
71 | return a+a*b;
72 | }
73 |
74 | void main() {
75 | shouldRemoveAllAssignments();
76 | shouldNotRemoveAnyAssignment();
77 | bewareThatAssignmentToAFieldIsNotAFullOverwrite(vec4(1).xyz);
78 | int io = 2, o = 3; // o's assignment is unused!
79 | dontRemoveAssignmentsToOutParams(gi, io, o);
80 | dontRemoveUnusedAssignmentToGlobal();
81 | removePureDeclInit();
82 | onlyRemove99AndAThenReturn15();
83 | }
--------------------------------------------------------------------------------
/tests/unit/unused_assignments.frag.expected:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | int gi=0;
4 | void preventMergingConsecutiveAssignments()
5 | {
6 | gi++;
7 | }
8 | void shouldRemoveAllAssignments()
9 | {
10 | preventMergingConsecutiveAssignments();
11 | preventMergingConsecutiveAssignments();
12 | }
13 | float shouldNotRemoveAnyAssignment()
14 | {
15 | float x=gi;
16 | preventMergingConsecutiveAssignments();
17 | x=sin(x);
18 | preventMergingConsecutiveAssignments();
19 | x=cos(x);
20 | preventMergingConsecutiveAssignments();
21 | return x;
22 | }
23 | vec3 bewareThatAssignmentToAFieldIsNotAFullOverwrite(vec3 v)
24 | {
25 | preventMergingConsecutiveAssignments();
26 | v=vec3(.3);
27 | preventMergingConsecutiveAssignments();
28 | v.y=0.;
29 | preventMergingConsecutiveAssignments();
30 | v.x+=1.;
31 | preventMergingConsecutiveAssignments();
32 | v=v.yyz;
33 | preventMergingConsecutiveAssignments();
34 | v.x++;
35 | preventMergingConsecutiveAssignments();
36 | v=vec3(.5);
37 | preventMergingConsecutiveAssignments();
38 | return v;
39 | }
40 | void dontRemoveAssignmentsToOutParams(int i,inout int io,out int o)
41 | {
42 | o=5;
43 | io=6;
44 | }
45 | void dontRemoveUnusedAssignmentToGlobal()
46 | {
47 | gi=8;
48 | gi=9;
49 | }
50 | float removePureDeclInit()
51 | {
52 | vec3 i;
53 | preventMergingConsecutiveAssignments();
54 | i=vec3(1);
55 | vec3 j=vec3(gi++);
56 | preventMergingConsecutiveAssignments();
57 | j=vec3(1);
58 | return i.x*j.y;
59 | }
60 | int onlyRemove99AndAThenReturn15()
61 | {
62 | int a=1,b;
63 | a*=a+a+a;
64 | {
65 | int a;
66 | preventMergingConsecutiveAssignments();
67 | a=2;
68 | b=a*a;
69 | }
70 | preventMergingConsecutiveAssignments();
71 | return a+a*b;
72 | }
73 | void main()
74 | {
75 | shouldRemoveAllAssignments();
76 | shouldNotRemoveAnyAssignment();
77 | bewareThatAssignmentToAFieldIsNotAFullOverwrite(vec4(1).xyz);
78 | int io=2,o;
79 | dontRemoveAssignmentsToOutParams(gi,io,o);
80 | dontRemoveUnusedAssignmentToGlobal();
81 | removePureDeclInit();
82 | onlyRemove99AndAThenReturn15();
83 | }
84 |
--------------------------------------------------------------------------------
/tests/unit/unused_removal.frag:
--------------------------------------------------------------------------------
1 | float f();
2 |
3 | float actually_unreachable() { return 1.5; }
4 | float noinline_actually_unreachable2() { return 1.5; }
5 |
6 | float f(){
7 | float r = 1.;
8 |
9 | return actually_unreachable();
10 | }
11 |
12 | vec3 g() { return vec3(0.); }
13 |
14 | vec2 pos = vec2(0.5);
15 |
16 | // hidden() is unused and should be removed even if a parameter named 'hidden' is used in another function.
17 | int hidden() {
18 | int noinlinevar = 0;
19 | noinlinevar++;
20 | return noinlinevar;
21 | }
22 |
23 | float foo(float hidden) {
24 | float noinlinevar = 0.;
25 | noinlinevar++;
26 | return hidden+noinlinevar;
27 | }
28 |
29 | float glob;
30 | float side_effect() {
31 | return glob++;
32 | }
33 |
34 | vec4 noinline_test()
35 | {
36 | vec4 bb;
37 | return bb;
38 | }
39 |
40 | void main(){
41 | float unused_var = side_effect();
42 |
43 | if (false) {
44 | noinline_actually_unreachable2();
45 | return;
46 | }
47 | gl_FragColor = vec4(foo(3.), g()) + noinline_test();
48 | }
49 |
--------------------------------------------------------------------------------
/tests/unit/unused_removal.frag.expected:
--------------------------------------------------------------------------------
1 | vec2 pos=vec2(.5);
2 | float glob;
3 | float foo()
4 | {
5 | float noinlinevar=0.;
6 | noinlinevar++;
7 | return 3.+noinlinevar;
8 | }
9 | vec4 noinline_test()
10 | {
11 | vec4 bb;
12 | return bb;
13 | }
14 | void main()
15 | {
16 | float unused_var=glob++;
17 | gl_FragColor=vec4(foo(),vec3(0))+noinline_test();
18 | }
19 |
--------------------------------------------------------------------------------
/tests/unit/vectors.frag:
--------------------------------------------------------------------------------
1 | float swizzles() {
2 | vec2 v1 = vec2(1., 1.);
3 | vec3 v2 = vec3(v1.x, v1.y, v1.x);
4 | vec3 v3 = vec3(v1.x, v2.x, v2.r);
5 | vec4 v4 = vec4(v1.xx, v1.y, v1.x);
6 | vec4 v5 = vec4(1., v2.z, v2.g, 2.);
7 | vec4 v6 = vec4(v1.x, v1.y, v2.r, v2.t);
8 | return v1.x + v2.x + v3.x + v4.x + v5.x + v6.x;
9 | }
10 |
11 | vec4 constructor() {
12 | return vec4(1., 1e2, 2e3, 3e4);
13 | }
14 |
15 | float constructors() {
16 | vec2 v2 = vec2(1e10, 1e10);
17 | vec3 v3 = vec3(v2, v2);
18 | vec4 v4 = vec4(v3, v2);
19 | return v2.x + v3.x + v4.x;
20 | }
21 |
22 | float withExtraComponents() {
23 | vec2 v2 = vec2(1);
24 | vec3 v3 = vec3(1, 2, v2.x);
25 | vec4 v4 = vec4(v2, v3.xy);
26 | vec3 v5 = vec3(1, v3.rg);
27 | return v2.x + v3.x + v4.x + v5.x;
28 | }
29 |
30 | float withExtraComponentsUnsafe(in vec3 a) {
31 | vec3 v1 = vec3(a.x);
32 | vec2 v3 = vec2(1.0, a.y);
33 | vec3 v4 = vec3(1.0, 2.0, a.y);
34 | return v1.x + v3.x + v4.x;
35 | }
36 |
37 | struct S{
38 | vec2 p1;
39 | vec2 cp1;
40 | vec2 cp2;
41 | vec2 p2;
42 | };
43 |
44 | vec2 calc(S points, float t) {
45 | // #282 - not a swizzle
46 | vec4 m1m2 = mix(vec4(points.p1, points.cp1), vec4(points.cp1, points.cp2), t);
47 | return m1m2.xy;
48 | }
49 |
--------------------------------------------------------------------------------
/tests/unit/vectors.frag.expected:
--------------------------------------------------------------------------------
1 | float swizzles()
2 | {
3 | vec2 v1=vec2(1);
4 | vec3 v2=vec3(v1.xyx),v3=vec3(v1.x,v2.xx);
5 | vec4 v4=vec4(v1.xxyx),v5=vec4(1,v2.zy,2),v6=vec4(v1.xy,v2);
6 | return v1.x+v2.x+v3.x+v4.x+v5.x+v6.x;
7 | }
8 | vec4 constructor()
9 | {
10 | return vec4(1,100,2e3,3e4);
11 | }
12 | float constructors()
13 | {
14 | vec2 v2=vec2(1e10);
15 | vec3 v3=vec3(v2,v2);
16 | vec4 v4=vec4(v3,v2);
17 | return v2.x+v3.x+v4.x;
18 | }
19 | float withExtraComponents()
20 | {
21 | vec2 v2=vec2(1);
22 | vec3 v3=vec3(1,2,v2);
23 | vec4 v4=vec4(v2,v3);
24 | vec3 v5=vec3(1,v3);
25 | return v2.x+v3.x+v4.x+v5.x;
26 | }
27 | float withExtraComponentsUnsafe(vec3 a)
28 | {
29 | vec3 v1=vec3(a.x);
30 | vec2 v3=vec2(1,a.y);
31 | vec3 v4=vec3(1,2,a.y);
32 | return v1.x+v3.x+v4.x;
33 | }
34 | struct S{vec2 p1;vec2 cp1;vec2 cp2;vec2 p2;};
35 | vec2 calc(S points,float t)
36 | {
37 | vec4 m1m2=mix(vec4(points.p1,points.cp1),vec4(points.cp1,points.cp2),t);
38 | return m1m2.xy;
39 | }
40 |
--------------------------------------------------------------------------------
/tests/unit/verbatim.frag:
--------------------------------------------------------------------------------
1 | //[
2 | // Test case for https://github.com/laurentlb/Shader_Minifier/issues/168
3 | //]
4 |
5 | //[
6 | int foo(int x) {
7 | return 2;
8 | }
9 | //]
10 |
11 | int my_function() {
12 | int i = 2;
13 | //[
14 | foo(1 + 1 ) ;
15 | //]
16 | return i;
17 | }
18 |
19 | int verbatim_with_newlines() {
20 | //[
21 |
22 |
23 | int x;
24 |
25 |
26 |
27 | int y;
28 |
29 |
30 |
31 | //]
32 | return x + y;
33 | }
34 |
--------------------------------------------------------------------------------
/tests/unit/verbatim.frag.expected:
--------------------------------------------------------------------------------
1 | // Generated with (https://github.com/laurentlb/Shader_Minifier/)
2 | #ifndef SHADER_MINIFIER_IMPL
3 | #ifndef SHADER_MINIFIER_HEADER
4 | # define SHADER_MINIFIER_HEADER
5 | #endif
6 |
7 | #else // if SHADER_MINIFIER_IMPL
8 |
9 | // tests/unit/verbatim.frag
10 | "//Test case for https://github.com/laurentlb/Shader_Minifier/issues/168\n"
11 | "int foo(int x){\nreturn 2;\n}\n"
12 | "int my_function()"
13 | "{"
14 | "int i=2;"
15 | "foo(1+1);\n"
16 | "return i;"
17 | "}"
18 | "int verbatim_with_newlines()"
19 | "{"
20 | "int x;\nint y;\n"
21 | "return x+y;"
22 | "}",
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------