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 に答える