SkinnedVertShader.vsh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. If the current vertex is affected by bones then the vertex position and
  3. normal will be transformed by the bone matrices. Each vertex wil have up
  4. to 4 bone indices (inBoneIndex) and bone weights (inBoneWeights).
  5. The indices are used to index into the array of bone matrices
  6. (BoneMatrixArray) to get the required bone matrix for transformation. The
  7. amount of influence a particular bone has on a vertex is determined by the
  8. weights which should always total 1. So if a vertex is affected by 2 bones
  9. the vertex position in world space is given by the following equation:
  10. position = (BoneMatrixArray[Index0] * inVertex) * Weight0 +
  11. (BoneMatrixArray[Index1] * inVertex) * Weight1
  12. The same proceedure is applied to the normals but the translation part of
  13. the transformation is ignored.
  14. After this the position is multiplied by the view and projection matrices
  15. only as the bone matrices already contain the model transform for this
  16. particular mesh. The two-step transformation is required because lighting
  17. will not work properly in clip space.
  18. */
  19. attribute highp vec3 inVertex;
  20. attribute mediump vec3 inNormal;
  21. attribute mediump vec3 inTangent;
  22. attribute mediump vec3 inBiNormal;
  23. attribute mediump vec2 inTexCoord;
  24. attribute mediump vec4 inBoneIndex;
  25. attribute mediump vec4 inBoneWeights;
  26. uniform highp mat4 ViewProjMatrix;
  27. uniform mediump vec3 LightPos;
  28. uniform mediump int BoneCount;
  29. uniform highp mat4 BoneMatrixArray[8];
  30. uniform highp mat3 BoneMatrixArrayIT[8];
  31. uniform bool bUseDot3;
  32. varying mediump vec3 Light;
  33. varying mediump vec2 TexCoord;
  34. void main()
  35. {
  36. if(BoneCount > 0)
  37. {
  38. // On PowerVR SGX it is possible to index the components of a vector
  39. // with the [] operator. However this can cause trouble with PC
  40. // emulation on some hardware so we "rotate" the vectors instead.
  41. mediump ivec4 boneIndex = ivec4(inBoneIndex);
  42. mediump vec4 boneWeights = inBoneWeights;
  43. highp mat4 boneMatrix = BoneMatrixArray[boneIndex.x];
  44. mediump mat3 normalMatrix = BoneMatrixArrayIT[boneIndex.x];
  45. highp vec4 position = boneMatrix * vec4(inVertex, 1.0) * boneWeights.x;
  46. mediump vec3 worldNormal = normalMatrix * inNormal * boneWeights.x;
  47. mediump vec3 worldTangent;
  48. mediump vec3 worldBiNormal;
  49. if(bUseDot3)
  50. {
  51. worldTangent = normalMatrix * inTangent * boneWeights.x;
  52. worldBiNormal = normalMatrix * inBiNormal * boneWeights.x;
  53. }
  54. for (lowp int i = 1; i < 3; ++i)
  55. {
  56. if(i < BoneCount)
  57. {
  58. // "rotate" the vector components
  59. boneIndex = boneIndex.yzwx;
  60. boneWeights = boneWeights.yzwx;
  61. boneMatrix = BoneMatrixArray[boneIndex.x];
  62. normalMatrix = BoneMatrixArrayIT[boneIndex.x];
  63. position += boneMatrix * vec4(inVertex, 1.0) * boneWeights.x;
  64. worldNormal += normalMatrix * inNormal * boneWeights.x;
  65. if(bUseDot3)
  66. {
  67. worldTangent += normalMatrix * inTangent * boneWeights.x;
  68. worldBiNormal += normalMatrix * inBiNormal * boneWeights.x;
  69. }
  70. }
  71. }
  72. gl_Position = ViewProjMatrix * position;
  73. // lighting
  74. mediump vec3 TmpLightDir = normalize(LightPos - position.xyz);
  75. if(bUseDot3)
  76. {
  77. Light.x = dot(normalize(worldTangent), TmpLightDir);
  78. Light.y = dot(normalize(worldBiNormal), TmpLightDir);
  79. Light.z = dot(normalize(worldNormal), TmpLightDir);
  80. }
  81. else
  82. {
  83. Light.x = dot(normalize(worldNormal), TmpLightDir);
  84. }
  85. }
  86. // Pass through texcoords
  87. TexCoord = inTexCoord;
  88. }