OpenGL: Improve accuracy of quaternion interpolation

Current order of operations (rotate then normalize) seems to produce a
lot more distortion than normalizing and then rotating. This makes Citra
results match pretty closesly with hardware, and indicates that hardware
may also be using lerp instead of slerp to interpolate the quaternions.
This commit is contained in:
Yuri Kunde Schlesner 2017-05-26 02:55:42 -07:00
parent bae3799bd5
commit 669ef82aee

View File

@ -536,8 +536,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
} }
// Rotate the surface-local normal by the interpolated normal quaternion to convert it to // Rotate the surface-local normal by the interpolated normal quaternion to convert it to
// eyespace // eyespace.
out += "vec3 normal = normalize(quaternion_rotate(normquat, surface_normal));\n"; out += "vec3 normal = quaternion_rotate(normalize(normquat), surface_normal);\n";
// Gets the index into the specified lookup table for specular lighting // Gets the index into the specified lookup table for specular lighting
auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input, auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input,
@ -1003,7 +1003,9 @@ uniform sampler1D proctex_diff_lut;
// Rotate the vector v by the quaternion q // Rotate the vector v by the quaternion q
vec3 quaternion_rotate(vec4 q, vec3 v) { vec3 quaternion_rotate(vec4 q, vec3 v) {
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
})"; }
)";
if (config.state.proctex.enable) if (config.state.proctex.enable)
AppendProcTexSampler(out, config); AppendProcTexSampler(out, config);