Skip to content

Should use slerp in vertex shader? #1

Description

@edvakf

Not sure if necessary.

diff --git a/src/MMD.VertexShaderSource.coffee b/src/MMD.VertexShaderSource.coffee
index 075b18c..1cdb901 100644
--- a/src/MMD.VertexShaderSource.coffee
+++ b/src/MMD.VertexShaderSource.coffee
@@ -39,6 +39,26 @@ MMD.VertexShaderSource = '''
     return v + 2.0 * cross(cross(v, q.xyz) - q.w*v, q.xyz);
   }

+  vec4 qslerp(vec4 quat, vec4 quat2, float slerp) {
+    float cosHalfTheta = dot(quat, quat2);
+
+    if (abs(cosHalfTheta) >= 1.0) {
+        return quat;
+    }
+
+    float halfTheta = acos(cosHalfTheta);
+    float sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta);
+
+    if (abs(sinHalfTheta) < 0.001) {
+        return (quat + quat2) * 0.5;
+    }
+
+    float ratioA = sin((1.0 - slerp) * halfTheta) / sinHalfTheta;
+    float ratioB = sin(slerp * halfTheta) / sinHalfTheta;
+
+    return quat * ratioA + quat2 * ratioB;
+  }
+
   void main() {
     vec3 position = aVertexPosition;
     vec3 normal = aVertexNormal;
@@ -58,10 +78,11 @@ MMD.VertexShaderSource = '''

       position = mix(r2, r1, aBoneWeight);

-      vec3 n1 = qtransform(q1, normal);
-      vec3 n2 = qtransform(q2, normal);
+      //vec3 n1 = qtransform(q1, normal);
+      //vec3 n2 = qtransform(q2, normal);

-      normal = normalize(mix(n2, n1, aBoneWeight));
+      //normal = normalize(mix(n2, n1, aBoneWeight));
+      normal = qtransform(qslerp(q2, q1, aBoneWeight), normal);
     }

     // return vertex point in projection space

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions