17b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens/* 27b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens If the current vertex is affected by bones then the vertex position and 37b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens normal will be transformed by the bone matrices. Each vertex wil have up 47b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens to 4 bone indices (inBoneIndex) and bone weights (inBoneWeights). 57b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 67b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens The indices are used to index into the array of bone matrices 77b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens (BoneMatrixArray) to get the required bone matrix for transformation. The 87b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens amount of influence a particular bone has on a vertex is determined by the 97b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens weights which should always total 1. So if a vertex is affected by 2 bones 107b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens the vertex position in world space is given by the following equation: 117b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 127b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens position = (BoneMatrixArray[Index0] * inVertex) * Weight0 + 137b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens (BoneMatrixArray[Index1] * inVertex) * Weight1 147b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 157b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens The same proceedure is applied to the normals but the translation part of 167b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens the transformation is ignored. 177b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 187b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens After this the position is multiplied by the view and projection matrices 197b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens only as the bone matrices already contain the model transform for this 207b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens particular mesh. The two-step transformation is required because lighting 217b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens will not work properly in clip space. 227b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens*/ 237b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 247b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute highp vec3 inVertex; 257b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec3 inNormal; 267b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec3 inTangent; 277b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec3 inBiNormal; 287b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec2 inTexCoord; 297b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec4 inBoneIndex; 307b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensattribute mediump vec4 inBoneWeights; 317b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 327b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform highp mat4 ViewProjMatrix; 337b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform mediump vec3 LightPos; 347b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform mediump int BoneCount; 357b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform highp mat4 BoneMatrixArray[8]; 367b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform highp mat3 BoneMatrixArrayIT[8]; 377b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensuniform bool bUseDot3; 387b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 397b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensvarying mediump vec3 Light; 407b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensvarying mediump vec2 TexCoord; 417b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 427b21f276fa91ad62fd2055844688b07829f12205Nicolas Capensvoid main() 437b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens{ 447b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens if(BoneCount > 0) 457b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 467b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // On PowerVR SGX it is possible to index the components of a vector 477b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // with the [] operator. However this can cause trouble with PC 487b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // emulation on some hardware so we "rotate" the vectors instead. 497b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump ivec4 boneIndex = ivec4(inBoneIndex); 507b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump vec4 boneWeights = inBoneWeights; 517b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 527b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens highp mat4 boneMatrix = BoneMatrixArray[boneIndex.x]; 537b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump mat3 normalMatrix = BoneMatrixArrayIT[boneIndex.x]; 547b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 557b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens highp vec4 position = boneMatrix * vec4(inVertex, 1.0) * boneWeights.x; 567b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump vec3 worldNormal = normalMatrix * inNormal * boneWeights.x; 577b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 587b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump vec3 worldTangent; 597b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump vec3 worldBiNormal; 607b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 617b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens if(bUseDot3) 627b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 637b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens worldTangent = normalMatrix * inTangent * boneWeights.x; 647b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens worldBiNormal = normalMatrix * inBiNormal * boneWeights.x; 657b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 667b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 677b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens for (lowp int i = 1; i < 3; ++i) 687b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 697b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens if(i < BoneCount) 707b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 717b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // "rotate" the vector components 727b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens boneIndex = boneIndex.yzwx; 737b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens boneWeights = boneWeights.yzwx; 747b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 757b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens boneMatrix = BoneMatrixArray[boneIndex.x]; 767b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens normalMatrix = BoneMatrixArrayIT[boneIndex.x]; 777b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 787b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens position += boneMatrix * vec4(inVertex, 1.0) * boneWeights.x; 797b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens worldNormal += normalMatrix * inNormal * boneWeights.x; 807b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 817b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens if(bUseDot3) 827b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 837b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens worldTangent += normalMatrix * inTangent * boneWeights.x; 847b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens worldBiNormal += normalMatrix * inBiNormal * boneWeights.x; 857b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 867b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 877b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 887b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens gl_Position = ViewProjMatrix * position; 897b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 907b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // lighting 917b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens mediump vec3 TmpLightDir = normalize(LightPos - position.xyz); 927b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 937b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens if(bUseDot3) 947b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 957b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens Light.x = dot(normalize(worldTangent), TmpLightDir); 967b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens Light.y = dot(normalize(worldBiNormal), TmpLightDir); 977b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens Light.z = dot(normalize(worldNormal), TmpLightDir); 987b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 997b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens else 1007b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens { 1017b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens Light.x = dot(normalize(worldNormal), TmpLightDir); 1027b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 1037b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens } 1047b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 1057b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens 1067b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens // Pass through texcoords 1077b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens TexCoord = inTexCoord; 1087b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens} 1097b21f276fa91ad62fd2055844688b07829f12205Nicolas Capens