Skip to content

Commit 5bee96f

Browse files
committed
Feature: Pre-calculate the results of a vector and vector.
E.g. return vec3(4, 5, 6) * vec3(1, 2, 3) => return vec3(4, 10,18)
1 parent 737b2dc commit 5bee96f

File tree

4 files changed

+99
-9
lines changed

4 files changed

+99
-9
lines changed

ShaderShrinker/Shrinker.Parser/Optimizations/PerformArithmeticExtension.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
168168
}
169169
}
170170

171-
// vecN(...) + <float>
171+
// 'vecN(...) + ...' or '... + vecN(...)'
172172
foreach (var vectorNode in rootNode.TheTree
173173
.OfType<GenericSyntaxNode>()
174-
.Where(o => o.Token is TypeToken t && t.Content?.StartsWith("vec") == true))
174+
.Where(o => o.Token is TypeToken t && t.IsVector()))
175175
{
176176
// Find the brackets.
177177
if (vectorNode.Next is not RoundBracketSyntaxNode brackets)
@@ -252,11 +252,55 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
252252
numberNode.Remove();
253253

254254
didChange = true;
255+
continue;
255256
}
256257
}
257258
}
258259
}
259260
}
261+
262+
// vector then vector.
263+
{
264+
// Find the math symbol.
265+
var symbolNode = brackets.Next;
266+
if (symbolNode?.Token is SymbolOperatorToken symbol && symbol.GetMathSymbolType() != TokenExtensions.MathSymbolType.Unknown)
267+
{
268+
// Find the second vector.
269+
var rhsVectorNode = symbolNode.Next;
270+
if (rhsVectorNode?.Token is TypeToken t && t.IsVector())
271+
{
272+
var rhsVectorBrackets = rhsVectorNode.Next as RoundBracketSyntaxNode;
273+
274+
// RHS vector must not be used in a following math operation of a different category.
275+
if (rhsVectorBrackets?.Next?.Token is not SymbolOperatorToken nextMath ||
276+
nextMath.GetMathSymbolType() == symbol.GetMathSymbolType() ||
277+
nextMath.GetMathSymbolType() == TokenExtensions.MathSymbolType.AddSubtract)
278+
{
279+
// Ensure both brackets have the same number of elements.
280+
var lhsCsv = brackets.GetCsv().ToList();
281+
var rhsCsv = rhsVectorBrackets.GetCsv().ToList();
282+
while (lhsCsv.Count < rhsCsv.Count)
283+
lhsCsv.Add(new[] { lhsCsv.First().Single().Clone() });
284+
while (rhsCsv.Count < lhsCsv.Count)
285+
rhsCsv.Add(new[] { rhsCsv.First().Single().Clone() });
286+
287+
// Perform math on each bracketed value.
288+
var newCsv =
289+
lhsCsv
290+
.Select((o, i) => DoNodeMath(o.Single(), symbolNode, rhsCsv[i].Single()))
291+
.Select(o => new GenericSyntaxNode(FloatToken.From(o, MaxDp).AsIntIfPossible()));
292+
293+
// Replace bracket content and sum.
294+
brackets.ReplaceWith(new RoundBracketSyntaxNode(newCsv.ToCsv()));
295+
symbolNode.Remove();
296+
rhsVectorNode.Remove();
297+
rhsVectorBrackets.Remove();
298+
299+
didChange = true;
300+
}
301+
}
302+
}
303+
}
260304
}
261305

262306
// Perform simple arithmetic calculations.

ShaderShrinker/UnitTests/TestFiles/SimplifiedReference/ED209.glsl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Processed by 'GLSL Shader Shrinker' (Shrunk by 926 characters)
1+
// Processed by 'GLSL Shader Shrinker' (Shrunk by 948 characters)
22
// (https://github.com/deanthecoder/GLSLShaderShrinker)
33

44
float stretch, gunsUp, gunsForward, edWalk, edTwist, edDown, edShoot, doorOpen, glow;
@@ -159,14 +159,13 @@ MarchData gunPod(vec3 p) {
159159
}
160160

161161
MarchData arms(vec3 p) {
162-
const vec3 wrist = vec3(1.5, 0, 0) - vec3(0, 0, .3);
163162
MarchData r;
164163
setBodyMaterial(r);
165164
p.x = abs(p.x);
166165
p.yz += vec2(.24, 0);
167166
p.xy *= rot(.15 * (gunsUp - 1.));
168-
r.d = min(sdCapsule(p, vec3(0), vec3(1.5, 0, 0)), sdCapsule(p, vec3(1.5, 0, 0), wrist));
169-
p -= wrist;
167+
r.d = min(sdCapsule(p, vec3(0), vec3(1.5, 0, 0)), sdCapsule(p, vec3(1.5, 0, 0), vec3(1.5, 0, -.3)));
168+
p -= vec3(1.5, 0, -.3);
170169
p.z -= gunsForward * .15;
171170
return minResult(r, gunPod(p));
172171
}

ShaderShrinker/UnitTests/TestFiles/SimplifiedReference/Temple.glsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Processed by 'GLSL Shader Shrinker' (Shrunk by 396 characters)
1+
// Processed by 'GLSL Shader Shrinker' (Shrunk by 408 characters)
22
// (https://github.com/deanthecoder/GLSLShaderShrinker)
33

44
#define SKYCOL vec3(.6, .8, .9)
@@ -145,7 +145,7 @@ void mainImage(out vec4 fragColor, vec2 fragCoord) {
145145
vec2 hit = vec2(0),
146146
uv = (fragCoord - .5 * iResolution.xy) / iResolution.y;
147147
vec3 p,
148-
forward = normalize(vec3(-13, -4, 0) - vec3(7, 6.5, -25)),
148+
forward = normalize(vec3(-20, -10.5, 25)),
149149
right = normalize(cross(vec3(0, 1, 0), forward)),
150150
rayDir = normalize(forward + uv.x * right + uv.y * cross(forward, right)),
151151
sunPosUnit = normalize(vec3(.5, .8, .7)),

ShaderShrinker/UnitTests/VectorArithmeticTests.cs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,53 @@ public void CheckArithmeticWithVectorAndScalar(
272272
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo(expected));
273273
}
274274

275-
// todo - vec and vec
275+
[Test, Sequential]
276+
public void CheckArithmeticWithVectorAndVector(
277+
[Values("vec2 f = vec2(1.1, 2.2) + vec2(1, 2);",
278+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) + vec2(6, 7);",
279+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) + vec2(5);",
280+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) + 2.0;",
281+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) * vec2(6, 7);",
282+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) * vec2(5);",
283+
"vec2 f = vec2(1.1, 2.2) + vec2(1, 2) * 2.0;",
284+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2);",
285+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) + vec2(6, 7);",
286+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) + vec2(5);",
287+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) + 2.0;",
288+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) * vec2(6, 7);",
289+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) * vec2(5);",
290+
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) * 2.0;",
291+
"vec2 f = vec2(3) + vec2(4);",
292+
"vec2 f = vec2(3, 4) + vec2(5);",
293+
"vec2 f = vec2(3) + vec2(4, 5);")] string code,
294+
[Values("vec2 f = vec2(2.1, 4.2);",
295+
"vec2 f = vec2(8.1, 11.2);",
296+
"vec2 f = vec2(7.1, 9.2);",
297+
"vec2 f = vec2(4.1, 6.2);",
298+
"vec2 f = vec2(7.1, 16.2);",
299+
"vec2 f = vec2(6.1, 12.2);",
300+
"vec2 f = vec2(3.1, 6.2);",
301+
"vec2 f = vec2(1.1, 4.4);",
302+
"vec2 f = vec2(7.1, 11.4);",
303+
"vec2 f = vec2(6.1, 9.4);",
304+
"vec2 f = vec2(3.1, 6.4);",
305+
"vec2 f = vec2(6.6, 30.8);",
306+
"vec2 f = vec2(5.5, 22);",
307+
"vec2 f = vec2(2.2, 8.8);",
308+
"vec2 f = vec2(7);",
309+
"vec2 f = vec2(8, 9);",
310+
"vec2 f = vec2(7, 8);")] string expected)
311+
{
312+
var lexer = new Lexer();
313+
lexer.Load(code);
314+
315+
var options = CustomOptions.None();
316+
options.PerformArithmetic = true;
317+
var rootNode = new Parser(lexer)
318+
.Parse()
319+
.Simplify(options);
320+
321+
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo(expected));
322+
}
276323
}
277324
}

0 commit comments

Comments
 (0)