Last active
June 14, 2020 20:30
-
-
Save hiroakioishi/fbcf4af43a4f034f70f0f6b6764f7ef0 to your computer and use it in GitHub Desktop.
Quaternionの球面線形補間(HLSL)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Quaternion slerp | |
// https://en.wikipedia.org/wiki/Slerp | |
float4 slerp(float4 q0, float4 q1, float t) | |
{ | |
q0 = normalize(q0); | |
q1 = normalize(q1); | |
float dot_q0q1 = dot(q0, q1); | |
bool dotIsNegative = dot_q0q1 < 0.0; | |
q1 = dotIsNegative ? -q1 : q1; | |
dot_q0q1 = dotIsNegative ? -dot_q0q1 : dot_q0q1; | |
const float DOT_THREDHOLD = 0.9995; | |
bool valuesAreTooClose = dot_q0q1 > 0.9995; | |
if (valuesAreTooClose) | |
{ | |
float4 result = q0 + t * (q1 - q0); | |
result = normalize(result); | |
return result; | |
} | |
// sin dot is in range [0, DOT_THRESHOLD], acos is safe | |
float theta_0 = acos(dot_q0q1); // theta_0 = angle between input vectors | |
float theta = theta_0 * t; // theta = angle between q0 and result | |
float sin_theta = sin(theta); // compute this value only once | |
float sin_theta_0 = sin(theta_0); // compute this value only once | |
float s0 = cos(theta) - dot_q0q1 * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0) | |
float s1 = sin_theta / sin_theta_0; | |
return (s0 * q0) + (s1 * q1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment