31 lines
1009 B
Plaintext
31 lines
1009 B
Plaintext
|
// Geometric Skinning with Approximate Dual Quaternion Blending, Kavan
|
||
|
// Based on https://github.com/tcoppex/aer-engine/blob/master/demos/aura/data/shaders/Skinning.glsl
|
||
|
uniform vec4 skinBones[skinMaxBones * 3];
|
||
|
|
||
|
void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B, out vec4 S) {
|
||
|
// Retrieve the real and dual part of the dual-quaternions
|
||
|
ivec4 bonei = bone * 3;
|
||
|
mat4 matA = mat4(
|
||
|
skinBones[bonei.x],
|
||
|
skinBones[bonei.y],
|
||
|
skinBones[bonei.z],
|
||
|
skinBones[bonei.w]);
|
||
|
mat4 matB = mat4(
|
||
|
skinBones[bonei.x + 1],
|
||
|
skinBones[bonei.y + 1],
|
||
|
skinBones[bonei.z + 1],
|
||
|
skinBones[bonei.w + 1]);
|
||
|
//Apply scaling first
|
||
|
S = skinBones[bonei.x + 2];
|
||
|
// Handles antipodality by sticking joints in the same neighbourhood
|
||
|
// weight.xyz *= sign(matA[3] * mat3x4(matA)).xyz;
|
||
|
weight.xyz *= sign(matA[3] * matA).xyz;
|
||
|
// Apply weights
|
||
|
A = matA * weight; // Real part
|
||
|
B = matB * weight; // Dual part
|
||
|
// Normalize
|
||
|
float invNormA = 1.0 / length(A);
|
||
|
A *= invNormA;
|
||
|
B *= invNormA;
|
||
|
}
|