Skip to content

Commit 9bdaf6d

Browse files
committed
Fast inverse square root (slower by 10%)
1 parent 5f8784e commit 9bdaf6d

File tree

7 files changed

+82
-12
lines changed

7 files changed

+82
-12
lines changed

source/Macros.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
#define QRSQRT 0

source/MathHelpers.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "MathHelpers.h"
2+
3+
/**
4+
* \brief https://www.youtube.com/watch?v=p8u_k2LIZyo
5+
*/
6+
float dae::Q_rsqrt(float number)
7+
{
8+
long i;
9+
float x2, y;
10+
const float threehalfs = 1.5F;
11+
12+
x2 = number * 0.5F;
13+
y = number;
14+
i = *reinterpret_cast<long*>(&y); // evil floating point bit level hacking
15+
i = 0x5f3759df - (i >> 1);
16+
y = *reinterpret_cast<float*>(&i);
17+
y = y * (threehalfs - (x2 * y * y)); // 1st iteration
18+
y = y * (threehalfs - (x2 * y * y)); // 2nd iteration, this can be removed
19+
return y;
20+
}

source/MathHelpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace dae
1919
return a * a;
2020
}
2121

22+
float Q_rsqrt(float number);
23+
2224
inline float Lerpf(float a, float b, float factor)
2325
{
2426
return ((1 - factor) * a) + (factor * b);

source/RayTracer.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ xcopy "$(SolutionDir)..\lib\vld\x64\Microsoft.DTfW.DHL.manifest" "$(OutDir)" /y
9797
<ClInclude Include="Camera.h" />
9898
<ClInclude Include="ColorRGB.h" />
9999
<ClInclude Include="DataTypes.h" />
100+
<ClInclude Include="Macros.h" />
100101
<ClInclude Include="Material.h" />
101102
<ClInclude Include="MathHelpers.h" />
102103
<ClInclude Include="Matrix.h" />
@@ -110,6 +111,7 @@ xcopy "$(SolutionDir)..\lib\vld\x64\Microsoft.DTfW.DHL.manifest" "$(OutDir)" /y
110111
</ItemGroup>
111112
<ItemGroup>
112113
<ClCompile Include="Camera.cpp" />
114+
<ClCompile Include="MathHelpers.cpp" />
113115
<ClCompile Include="Matrix.cpp" />
114116
<ClCompile Include="Renderer.cpp" />
115117
<ClCompile Include="Scene.cpp" />

source/RayTracer.vcxproj.filters

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<ClInclude Include="DataTypes.h">
5454
<Filter>Misc</Filter>
5555
</ClInclude>
56+
<ClInclude Include="Macros.h" />
5657
</ItemGroup>
5758
<ItemGroup>
5859
<ClCompile Include="main.cpp" />
@@ -75,5 +76,8 @@
7576
<ClCompile Include="Camera.cpp">
7677
<Filter>Misc</Filter>
7778
</ClCompile>
79+
<ClCompile Include="MathHelpers.cpp">
80+
<Filter>Math</Filter>
81+
</ClCompile>
7882
</ItemGroup>
7983
</Project>

source/Vector3.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "Vector3.h"
22

3-
#include <cassert>
4-
53
#include "Vector4.h"
4+
#include "MathHelpers.h"
5+
#include "Macros.h"
6+
67
#include <cmath>
8+
#include <cassert>
79

810
namespace dae
911
{
@@ -26,7 +28,12 @@ namespace dae
2628

2729
float Vector3::Magnitude() const
2830
{
29-
return sqrtf(x * x + y * y + z * z);
31+
#if QRSQRT
32+
const float magnitudeSq {x * x + y * y + z * z};
33+
return 1.0f / Q_rsqrt(magnitudeSq);
34+
#else
35+
return std::sqrt(x * x + y * y + z * z);
36+
#endif
3037
}
3138

3239
float Vector3::SqrMagnitude() const
@@ -36,18 +43,30 @@ namespace dae
3643

3744
float Vector3::Normalize()
3845
{
39-
const float m = Magnitude();
46+
#if QRSQRT
47+
const float m {Q_rsqrt(x * x + y * y + z * z)};
48+
x *= m;
49+
y *= m;
50+
z *= m;
51+
return m;
52+
#else
53+
const float m{Magnitude()};
4054
x /= m;
4155
y /= m;
4256
z /= m;
43-
4457
return m;
58+
#endif
4559
}
4660

4761
Vector3 Vector3::Normalized() const
4862
{
49-
const float m = Magnitude();
63+
#if QRSQRT
64+
const float m {Q_rsqrt(x * x + y * y + z * z)};
65+
return {x * m, y * m, z * m};
66+
#else
67+
const float m{Magnitude()};
5068
return {x / m, y / m, z / m};
69+
#endif
5170
}
5271

5372
float Vector3::Dot(const Vector3& v1, const Vector3& v2)

source/Vector4.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "Vector4.h"
22

3-
#include <cassert>
4-
53
#include "Vector3.h"
4+
#include "MathHelpers.h"
5+
#include "Macros.h"
6+
67
#include <cmath>
8+
#include <cassert>
79

810
namespace dae
911
{
@@ -17,7 +19,12 @@ namespace dae
1719

1820
float Vector4::Magnitude() const
1921
{
20-
return sqrtf(x * x + y * y + z * z + w * w);
22+
#if QRSQRT
23+
const float magnitudeSq {x * x + y * y + z * z + w * w};
24+
return 1.0f / Q_rsqrt(magnitudeSq);
25+
#else
26+
return std::sqrt(x * x + y * y + z * z + w * w);
27+
#endif
2128
}
2229

2330
float Vector4::SqrMagnitude() const
@@ -27,19 +34,32 @@ namespace dae
2734

2835
float Vector4::Normalize()
2936
{
30-
const float m = Magnitude();
37+
#if QRSQRT
38+
const float m {Q_rsqrt(x * x + y * y + z * z + w * w)};
39+
x *= m;
40+
y *= m;
41+
z *= m;
42+
w *= m;
43+
return m;
44+
#else
45+
const float m{Magnitude()};
3146
x /= m;
3247
y /= m;
3348
z /= m;
3449
w /= m;
35-
3650
return m;
51+
#endif
3752
}
3853

3954
Vector4 Vector4::Normalized() const
4055
{
41-
const float m = Magnitude();
56+
#if QRSQRT
57+
const float m {Q_rsqrt(x * x + y * y + z * z + w * w)};
58+
return {x * m, y * m, z * m, w * m};
59+
#else
60+
const float m{Magnitude()};
4261
return {x / m, y / m, z / m, w / m};
62+
#endif
4363
}
4464

4565
float Vector4::Dot(const Vector4& v1, const Vector4& v2)

0 commit comments

Comments
 (0)