Skip to content

Commit 5c693ba

Browse files
committed
Feature: pow() with two constant 3D vectors are simplified.
e.g. pow(vec3(0.42, 0.36, 0.3), vec3(2.2)) => vec3(.1483, .10565, .07074)
1 parent 4116781 commit 5c693ba

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

ShaderShrinker/Shrinker.Parser/Optimizations/PerformArithmeticExtension.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,36 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
182182
didChange = true;
183183
}
184184

185-
// dot(vecN(nums), vecN(nums)) => <the result>
186-
foreach (var dotNode in functionCalls
187-
.Where(o => o.Name == "dot" && o.Params.Children.Any(n => (n.Token as TypeToken)?.IsVector() == true))
185+
// <func>(vecN(nums), vecN(nums)) => <the result>
186+
foreach (var functionNode in functionCalls
187+
.Where(o => o.Params.Children.Any(n => (n.Token as TypeToken)?.IsVector() == true))
188188
.ToList())
189189
{
190-
var dotParams = dotNode.Params.GetCsv().ToList();
190+
var dotParams = functionNode.Params.GetCsv().ToList();
191191
var vectors = dotParams.Select(o => o.First()).Where(o => (o.Token as TypeToken)?.IsVector() == true).ToList();
192192
var nums = vectors.Select(GetVectorNumericCsv).ToList();
193193
if (nums.All(o => o == null))
194194
continue; // Neither arg is a simple numeric vector.
195195

196-
if (nums.Count(o => o != null) == 2)
196+
// Are both args vectors and simple numeric?
197+
var isSimpleNumeric = nums.Count(o => o != null) == 2;
198+
if (isSimpleNumeric && functionNode.Name == "pow")
199+
{
200+
// pow(vecN(nums), vecN(nums)) => <the result>
201+
ReplaceNodeWithVector(functionNode, nums[0].Select((_, i) => Math.Pow(nums[0][i], nums[1][i])).ToList());
202+
didChange = true;
203+
continue;
204+
}
205+
206+
// dot(vecN(nums), vecN(nums)) => <the result>
207+
if (functionNode.Name != "dot")
208+
continue;
209+
210+
if (isSimpleNumeric)
197211
{
198212
// Both args are vectors and simple numeric - We can calculate the result.
199-
var sum = nums[0].Select((t, i) => t * nums[1][i]).Sum();
200-
dotNode.ReplaceWith(new GenericSyntaxNode(FloatToken.From(sum, MaxDp)));
213+
var result = nums[0].Select((t, i) => t * nums[1][i]).Sum();
214+
functionNode.ReplaceWith(new GenericSyntaxNode(FloatToken.From(result, MaxDp)));
201215
didChange = true;
202216
continue;
203217
}
@@ -217,7 +231,7 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
217231
// Replace the dot().
218232
var oneIndex = GetVectorNumericCsv(vectorWithAOne).IndexOf(1.0);
219233
var newNode = new GenericSyntaxNode($"{node.Token.Content}.{"xyzw"[oneIndex]}");
220-
dotNode.ReplaceWith(newNode);
234+
functionNode.ReplaceWith(newNode);
221235
didChange = true;
222236
}
223237

ShaderShrinker/Shrinker.Parser/SyntaxNodes/FunctionCallSyntaxNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class FunctionCallSyntaxNode : SyntaxNode, IRenamable
2121
{
2222
public string Name { get; private set; }
2323

24-
public RoundBracketSyntaxNode Params => (RoundBracketSyntaxNode)Children[0];
24+
public RoundBracketSyntaxNode Params => Children.Any() ? (RoundBracketSyntaxNode)Children[0] : new RoundBracketSyntaxNode();
2525

2626
public FunctionCallSyntaxNode(GenericSyntaxNode nameNode, RoundBracketSyntaxNode brackets) : this(nameNode?.Token?.Content)
2727
{

ShaderShrinker/UnitTests/VectorArithmeticTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ public void CheckArithmeticWithPowFunction(
6060
"float f = pow(2.0, pow(2., 2.));",
6161
"float f; f = pow(2.0, pow(2., 2.));",
6262
"float f = pow(-1.5, 2.0);",
63-
"float f = pow(1.5, -2.0);")] string code,
63+
"float f = pow(1.5, -2.0);",
64+
"vec2 v = pow(vec2(2, 3), vec2(4, 5));")] string code,
6465
[Values("float f = 16.;",
6566
"float f = 16.;",
6667
"float f; f = 16.;",
6768
"float f = pow(-1.5, 2.0);",
68-
"float f = pow(1.5, -2.0);")] string expected)
69+
"float f = pow(1.5, -2.0);",
70+
"vec2 v = vec2(16, 243);")] string expected)
6971
{
7072
var lexer = new Lexer();
7173
lexer.Load(code);

0 commit comments

Comments
 (0)