diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2017-06-12 16:31:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-12 16:31:55 -0700 |
commit | 791cd14c8d0878aa69c2470f99276e08ea601cd4 (patch) | |
tree | c89318569eb4bdc19be74620087808053cfa83b3 /src | |
parent | 4325a7c82d6dc750b17f257ec33309aca4ddf9db (diff) | |
parent | ba01a8302aacbca44ba4df36ed4f03e7fdfc4f25 (diff) |
Merge pull request #2767 from yuriks/quaternion-flip-comment
OpenGL: Update comment on AreQuaternionsOpposite with new information
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 57d5e8253..e6cccebf6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -182,19 +182,22 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { RasterizerOpenGL::~RasterizerOpenGL() {} /** - * This is a helper function to resolve an issue with opposite quaternions being interpolated by - * OpenGL. See below for a detailed description of this issue (yuriks): + * This is a helper function to resolve an issue when interpolating opposite quaternions. See below + * for a detailed description of this issue (yuriks): * * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you * interpolate two quaternions that are opposite, instead of going from one rotation to another * using the shortest path, you'll go around the longest path. You can test if two quaternions are - * opposite by checking if Dot(Q1, W2) < 0. In that case, you can flip either of them, therefore - * making Dot(-Q1, W2) positive. + * opposite by checking if Dot(Q1, Q2) < 0. In that case, you can flip either of them, therefore + * making Dot(Q1, -Q2) positive. * - * NOTE: This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This - * should be correct for nearly all cases, however a more correct implementation (but less trivial - * and perhaps unnecessary) would be to handle this per-fragment, by interpolating the quaternions - * manually using two Lerps, and doing this correction before each Lerp. + * This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This is + * correct for most cases but can still rotate around the long way sometimes. An implementation + * which did `lerp(lerp(Q1, Q2), Q3)` (with proper weighting), applying the dot product check + * between each step would work for those cases at the cost of being more complex to implement. + * + * Fortunately however, the 3DS hardware happens to also use this exact same logic to work around + * these issues, making this basic implementation actually more accurate to the hardware. */ static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) { Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()}; |