summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-06-10 01:55:17 -0700
committerGravatar Yuri Kunde Schlesner2017-06-10 01:55:17 -0700
commitba01a8302aacbca44ba4df36ed4f03e7fdfc4f25 (patch)
tree3b1b2e1039e1deb02b47b4a9fe257eb6c579d758 /src
parentRemove unused import in break_points.cpp (#2763) (diff)
downloadyuzu-ba01a8302aacbca44ba4df36ed4f03e7fdfc4f25.tar.gz
yuzu-ba01a8302aacbca44ba4df36ed4f03e7fdfc4f25.tar.xz
yuzu-ba01a8302aacbca44ba4df36ed4f03e7fdfc4f25.zip
OpenGL: Update comment on AreQuaternionsOpposite with new information
While debugging the software renderer implementation, it was noticed that this is actually exactly what the hardware does, upgrading the status of this "hack" to being a proper implementation. And there was much rejoicing.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp19
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 aa9b831dd..91fff2a63 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) {
182RasterizerOpenGL::~RasterizerOpenGL() {} 182RasterizerOpenGL::~RasterizerOpenGL() {}
183 183
184/** 184/**
185 * This is a helper function to resolve an issue with opposite quaternions being interpolated by 185 * This is a helper function to resolve an issue when interpolating opposite quaternions. See below
186 * OpenGL. See below for a detailed description of this issue (yuriks): 186 * for a detailed description of this issue (yuriks):
187 * 187 *
188 * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you 188 * For any rotation, there are two quaternions Q, and -Q, that represent the same rotation. If you
189 * interpolate two quaternions that are opposite, instead of going from one rotation to another 189 * interpolate two quaternions that are opposite, instead of going from one rotation to another
190 * using the shortest path, you'll go around the longest path. You can test if two quaternions are 190 * using the shortest path, you'll go around the longest path. You can test if two quaternions are
191 * opposite by checking if Dot(Q1, W2) < 0. In that case, you can flip either of them, therefore 191 * opposite by checking if Dot(Q1, Q2) < 0. In that case, you can flip either of them, therefore
192 * making Dot(-Q1, W2) positive. 192 * making Dot(Q1, -Q2) positive.
193 * 193 *
194 * NOTE: This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This 194 * This solution corrects this issue per-vertex before passing the quaternions to OpenGL. This is
195 * should be correct for nearly all cases, however a more correct implementation (but less trivial 195 * correct for most cases but can still rotate around the long way sometimes. An implementation
196 * and perhaps unnecessary) would be to handle this per-fragment, by interpolating the quaternions 196 * which did `lerp(lerp(Q1, Q2), Q3)` (with proper weighting), applying the dot product check
197 * manually using two Lerps, and doing this correction before each Lerp. 197 * between each step would work for those cases at the cost of being more complex to implement.
198 *
199 * Fortunately however, the 3DS hardware happens to also use this exact same logic to work around
200 * these issues, making this basic implementation actually more accurate to the hardware.
198 */ 201 */
199static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) { 202static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) {
200 Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()}; 203 Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()};