Skip to content

Commit b2e437c

Browse files
committed
Feature: Consecutive assignments of the same vector component can now be combined.
E.g. vec2 v; v.x = 1.0; v.x = v.x + 1.0; ...changes to... vec2 v; v.x = 1.0 + 1.0;
1 parent 7fc25b9 commit b2e437c

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

ShaderShrinker/Shrinker.Parser/Optimizations/CombineConsecutiveAssignmentsExtension.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,23 @@ public static void CombineConsecutiveAssignments(this SyntaxNode rootNode)
3333
// Find consecutive assignment of same variable.
3434
var assignment = braces.Children.OfType<VariableAssignmentSyntaxNode>()
3535
.Where(o => o.HasValue && o.Parent is not VariableDeclarationSyntaxNode)
36-
.Where(o => o.Next is VariableAssignmentSyntaxNode)
37-
.Where(o => o.Name == localVariable.Name &&
38-
o.Next is VariableAssignmentSyntaxNode ass2 &&
39-
ass2.Name == localVariable.Name &&
40-
o.FullName == ass2.FullName)
36+
.Where(o => o.Name.StartsWith(localVariable.Name) &&
37+
o.FullName == (o.Next as VariableAssignmentSyntaxNode)?.FullName)
4138
.FirstOrDefault(o => o.Next.TheTree.OfType<GenericSyntaxNode>().Count(n => n.StartsWithVarName(localVariable.Name)) == 1);
4239

4340
if (assignment == null)
4441
continue;
4542

43+
// If assigning to a component of the variable (E.g. v.x or v[1]), there must be no other references to
44+
// the variable in the second assignment.
45+
if (assignment.FullName.IndexOfAny(new[] { '.', '[' }) > 0)
46+
{
47+
if (((VariableAssignmentSyntaxNode)assignment.Next).TheTree.Any(o => o.HasNodeContent(localVariable.Name)))
48+
continue;
49+
}
50+
4651
// Inline the definition (adding (...) if necessary).
47-
var usage = assignment.Next.TheTree.OfType<GenericSyntaxNode>().Single(o => o.IsVarName(localVariable.Name));
52+
var usage = assignment.Next.TheTree.OfType<GenericSyntaxNode>().Single(o => o.HasNodeContent(assignment.FullName));
4853
var addBrackets = assignment.Children.Any(o => o.Token is SymbolOperatorToken);
4954
if (addBrackets)
5055
usage.ReplaceWith(new RoundBracketSyntaxNode(assignment.Children));

ShaderShrinker/UnitTests/ShrinkerTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,55 @@ public void CheckCombiningAssignmentsRecognizesArrayAccessors()
11061106
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo(Code));
11071107
}
11081108

1109+
[Test]
1110+
public void CheckCombiningAssignmentsRecognizesCommonVectorAccessors()
1111+
{
1112+
var lexer = new Lexer();
1113+
lexer.Load("void main() { vec2 v; v.x = 1.0; v.x = v.x + 1.0; }");
1114+
1115+
var options = CustomOptions.None();
1116+
options.CombineConsecutiveAssignments = true;
1117+
var rootNode = new Parser(lexer)
1118+
.Parse()
1119+
.Simplify(options);
1120+
1121+
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo("void main() { vec2 v; v.x = 1.0 + 1.0; }"));
1122+
}
1123+
1124+
[Test]
1125+
public void CheckCombiningAssignmentsIgnoresCommonVectorAccessorsIfWholeVariableIsUsed()
1126+
{
1127+
const string Code = "void main() { vec2 v; v.x = 1.0; v.x = v.x + 1.0 + f(v); }";
1128+
1129+
var lexer = new Lexer();
1130+
lexer.Load(Code);
1131+
1132+
var options = CustomOptions.None();
1133+
options.CombineConsecutiveAssignments = true;
1134+
var rootNode = new Parser(lexer)
1135+
.Parse()
1136+
.Simplify(options);
1137+
1138+
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo(Code));
1139+
}
1140+
1141+
[Test]
1142+
public void CheckCombiningAssignmentsIgnoresDifferentVectorAccessors()
1143+
{
1144+
const string Code = "void main() { vec2 v; v.x = 1.0; v.y = v.x + 1.0; }";
1145+
1146+
var lexer = new Lexer();
1147+
lexer.Load(Code);
1148+
1149+
var options = CustomOptions.None();
1150+
options.CombineConsecutiveAssignments = true;
1151+
var rootNode = new Parser(lexer)
1152+
.Parse()
1153+
.Simplify(options);
1154+
1155+
Assert.That(rootNode.ToCode().ToSimple(), Is.EqualTo(Code));
1156+
}
1157+
11091158
[Test, Sequential]
11101159
public void GivenVectorReferencingAllComponentsCheckSimplifyingToJustVariableName(
11111160
[Values("vec4 a = vec4(1, 2, 3, 4), b = a.rgba;",

ShaderShrinker/UnitTests/TestFiles/SimplifiedReference/ED209.glsl

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

44
float stretch, gunsUp, gunsForward, edWalk, edTwist, edDown, edShoot, doorOpen, glow;
@@ -94,8 +94,7 @@ float headSphere(vec3 p) { return (length(p / vec3(1, .8, 1)) - 1.) * .8; }
9494
MarchData headVisor(vec3 p, float h, float bump) {
9595
bump *= sin(p.x * 150.) * sin(p.y * 150.) * .002;
9696
MarchData result;
97-
result.d = sdBox(p, vec3(1, h, 2));
98-
result.d = max(mix(result.d, headSphere(p), .57), -p.y) - bump;
97+
result.d = max(mix(sdBox(p, vec3(1, h, 2)), headSphere(p), .57), -p.y) - bump;
9998
result.mat = vec3(.05);
10099
result.specPower = 30.;
101100
return result;
@@ -126,8 +125,7 @@ MarchData gunPod(vec3 p) {
126125
p.yz += vec2(.1, .45);
127126
vec3 pp = p;
128127
pp.z = abs(pp.z) - .5;
129-
r.d = sdCappedCone(pp, vec3(0), vec3(0, 0, -.1), .35 - .1, .35);
130-
r.d = min(r.d, sdCappedCylinder(p, .35, .4));
128+
r.d = min(sdCappedCone(pp, vec3(0), vec3(0, 0, -.1), .35 - .1, .35), sdCappedCylinder(p, .35, .4));
131129
pp = vec3(p.x, .28 - p.y, p.z);
132130
r.d = min(r.d, sdTriPrism(pp, vec2(.1, .5)));
133131
pp = p;
@@ -205,8 +203,7 @@ MarchData waist(vec3 p) {
205203
pp.x = abs(pp.x);
206204
pp.yz *= rot(-.58525 + legAngle * sign(p.x));
207205
pp.x -= .98;
208-
r.d = min(r.d, max(sdCappedCylinder(pp.zyx, .4, .24), -pp.y));
209-
r.d = min(r.d, sdBox(pp, vec3(.24, .2, .14 + .2 * pp.y)));
206+
r.d = min(min(r.d, max(sdCappedCylinder(pp.zyx, .4, .24), -pp.y)), sdBox(pp, vec3(.24, .2, .14 + .2 * pp.y)));
210207
p = pp;
211208
pp.xz = abs(pp.xz) - vec2(.12, .25);
212209
r.d = min(r.d, max(min(sdCappedCylinder(pp.xzy, .1, .325), sdCappedCylinder(pp.xzy, .05, .5)), pp.y));
@@ -246,8 +243,7 @@ MarchData legs(vec3 p) {
246243
cp -= vec3(0, -.7, 0);
247244
r.d = sdBox(cp - vec3(0, 0, 1.15), vec3(.17, .17, .07)) - .04;
248245
cp.z++;
249-
r.d = min(r.d, sdChamferedCube(cp.xzy, vec2(.28 - sign(abs(cp.z) - .3) * .01, .5).xyx, .18));
250-
r.d = min(r.d, foot(cp));
246+
r.d = min(min(r.d, sdChamferedCube(cp.xzy, vec2(.28 - sign(abs(cp.z) - .3) * .01, .5).xyx, .18)), foot(cp));
251247
if (silver < r.d) {
252248
r.d = silver;
253249
r.mat = vec3(.8);

0 commit comments

Comments
 (0)