2

我想通过骨骼为网格设置动画。但是,由于我的 android Galaxy s2 仅支持 304 个顶点着色器变量,我想我需要计算缺失的骨骼变换矩阵和 Java 中已经存在的新顶点位置。

无论如何,我怎样才能将它转换为等效的?(我实际上只是想将其排除为错误源)

uniform mat4  u_BoneTransform[128];
in  vec3  in_Position;
in  vec4  in_BoneID;
in  vec4  in_Weights;

vec3 position = (in_Weights[0] * (u_BoneTransform[ int(in_BoneID[0]) ] * vec4(in_Position, 1.0)).xyz)
      + (in_Weights[1] * (u_BoneTransform[ int(in_BoneID[1]) ] * vec4(in_Position, 1.0)).xyz)
      + (in_Weights[2] * (u_BoneTransform[ int(in_BoneID[2]) ] * vec4(in_Position, 1.0)).xyz)
      + (in_Weights[3] * (u_BoneTransform[ int(in_BoneID[3]) ] * vec4(in_Position, 1.0)).xyz); 

这就是我到目前为止所拥有的。自然,它会比让着色器来做这件事要慢,这是一种耻辱。不过,我很乐意提出任何建议。

public void update() {
  // ...
  Vector3 position = marryBonesWithVector(weights, boneTransformations,currentPosition,1.0f);
  // ...
}

/**
 * Marry Bones with Vector
 *
 * @param w weights
 * @param i influences
 * @param m bone transformation matrices
 * @param t target vector (like position or normal)
 * @param f flag for position or directional vector
 */
public static void marryBonesWithVector(float[] w, int[] i, Matrix4[] m, Vector3 t, float f) {

  Vector3 influence1 = getSingleBoneInfluence(m[i[0]],t,f).mulInPlace(w[0]);
  Vector3 influence2 = getSingleBoneInfluence(m[i[1]],t,f).mulInPlace(w[1]);
  Vector3 influence3 = getSingleBoneInfluence(m[i[2]],t,f).mulInPlace(w[2]);
  Vector3 influence4 = getSingleBoneInfluence(m[i[3]],t,f).mulInPlace(w[3]);

  t.addInPlace(influence1).addInPlace(influence2).addInPlace(influence3).addInPlace(influence4);
}

/**
 * computes single bone influence
 *
 * @param m current bone transformation Matrix
 * @param t taret position vector
 * @param f flag: 1 position, 0 direction
 * @return Vector3 single bone influence
 */
private static Vector3 getSingleBoneInfluence(Matrix4 m, Vector3 t, float f) {
  float [] pI = new float[4];
  pI[0] = m.values[0]  * t.x + m.values[1]  * t.y + m.values[2]  * t.z + m.values[3]  * f;
  pI[1] = m.values[4]  * t.x + m.values[5]  * t.y + m.values[6]  * t.z + m.values[7]  * f;
  pI[2] = m.values[8]  * t.x + m.values[9]  * t.y + m.values[10] * t.z + m.values[11] * f;
  //      pI[3] = m.values[12] * t.x + m.values[13] * t.y + m.values[14] * t.z + m.values[15] * f; // not needed
  return Vector3.createNew(pI[0],pI[1],pI[2]);
}
4

1 回答 1

1

原来着色器使用转置矩阵。

所以当我以这种方式计算时,我的代码可以工作:

/**
 * computes single bone influence
 *
 * @param m current bone transformation Matrix
 * @param t position vector
 * @param f flag: 1 position, 0 direction
 * @return Vector3 single bone influence
 */
private static Vector3 getSingleBoneInfluence(Matrix4 m, Vector3 t, float f) {
    float[] pI = new float[4];
    pI[0] = m.values[0]  * t.x + m.values[4]  * t.y + m.values[8]  * t.z + m.values[12]  * f;
    pI[1] = m.values[1]  * t.x + m.values[5]  * t.y + m.values[9]  * t.z + m.values[13]  * f;
    pI[2] = m.values[2]  * t.x + m.values[6]  * t.y + m.values[10] * t.z + m.values[14]  * f;

    return Vector3.createNew(pI[0], pI[1], pI[2]);
}

*编辑:了解着色器 mat4 * vec4 计算

于 2012-12-07T10:59:39.263 回答