Android中的骨骼动画与opengl

时间:2016-03-04 06:26:11

标签: java android opengl-es 3d skeletal-animation

我正在尝试使用opengl es2在android中实现骨架动画。我创建了一个Joint类,它存储Bind姿势的旋转,位置,局部矩阵,世界矩阵和逆绑定姿势矩阵,以及一个JointState类,它包含每个关键帧的数据,包括旋转,位置,局部矩阵,世界矩阵和偏移矩阵。一切看起来都不错,但我的渲染效果出乎意料。我附上了代码。请帮忙

联合课程

public class Joint{

private String name;
private int index;
private Joint parent;
private Vector3 position;
private Quaternion rotation;
private Vector3 rot;
private Vector3 rotTest;
private Matrix4 localMatrix;
private Matrix4 globalMatrix;
private Matrix4 inverseBindPoseMatrix;

public Joint(String name, int index, Joint parent, Vector3 position, Quaternion rotation){
    this.name = name;
    this.index = index;
    this.parent = parent;
    this.position = position.clone();
    this.rotation = rotation.clone();
    this.rot = Quaternion.getRotationFromQuat(rotation.clone());
    this.localMatrix = Matrix4.createFromRotationTranslation(rotation.clone(), position.clone());
    if(this.parent == null){
        this.globalMatrix = this.localMatrix;
    }else{
        this.globalMatrix = (this.parent.globalMatrix.clone()).multiply(this.localMatrix.clone());
    }
    Quaternion q = new Quaternion();
    q.fromMatrix(this.globalMatrix.clone());
    this.rotTest = q.getRotationFromQuat(q);
    this.inverseBindPoseMatrix = this.globalMatrix.clone().inverse();
}

JointState类

public class JointState{

private String name;
private int index;
private JointState parent;
private Vector3 position;
private Quaternion rotation;
private Vector3 rot;
private Vector3 rotTest;
private Matrix4 localMatrix;
private Matrix4 globalMatrix;
private Matrix4 offsetMatrix;

public JointState(Joint joint, JointState parent, Vector3 position, Quaternion rotation) {
    this.name = joint.getName();
    this.index = joint.getIndex();
    this.parent = parent;
    this.position = position.clone();
    this.rotation = rotation.clone();
    this.rot = Quaternion.getRotationFromQuat(rotation.clone());
    this.localMatrix = Matrix4.createFromRotationTranslation(rotation.clone(), position.clone());
    if(this.parent == null){
        this.globalMatrix = this.localMatrix.clone();
    }else{
        this.globalMatrix = this.parent.globalMatrix.clone().multiply(this.localMatrix.clone());
    }
    Quaternion q = new Quaternion();
    q.fromMatrix(this.globalMatrix.clone());
    this.rotTest = q.getRotationFromQuat(q);
    Matrix4 IBPMatrix = joint.getInverseBindPoseMatrix();
    Matrix4 offsetMatrix = this.globalMatrix.clone().multiply(IBPMatrix.clone());
    this.offsetMatrix = offsetMatrix;
}

enter image description here 绑定对象的姿势状态 enter image description here 第20帧的对象

我得到的结果

enter image description here

我正确的默认形状

enter image description here

变形的框架20形状,我想修复。

着色器代码如下

顶点着色器

const int MAX_BONES = 32;
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;   
attribute vec3 aSkinIndex;
attribute vec3 aSkinWeight;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

uniform bool useSkinning;

uniform mat4 uBoneMatrices[MAX_BONES];

varying vec3 vVertex, vNormal;

mat4 boneTransform(){
    mat4 ret;
    float normfac = 1.0/(aSkinWeight.x +aSkinWeight.y + aSkinWeight.z);
    ret = normfac * aSkinWeight.z * uBoneMatrices[int(aSkinIndex.z)]
        + normfac * aSkinWeight.y * uBoneMatrices[int(aSkinIndex.y)]
        + normfac * aSkinWeight.x * uBoneMatrices[int(aSkinIndex.x)];
    return ret;
}

void main()                    
{      
    if(useSkinning && length(aSkinWeight) > 0.5){

        mat4 bt = boneTransform();
        gl_Position = uProjectionMatrix * uModelViewMatrix * bt * vec4(aVertexPosition, 1.0);  
        vNormal = (bt * vec4(aVertexNormal, 0.0)).xyz;
        vVertex = (bt * vec4(aVertexPosition, 1.0)).xyz;  
        gl_PointSize = 10.0;

    }
    else{
        vNormal = aVertexNormal;
        vVertex = aVertexPosition;
        gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);    
        gl_PointSize = 10.0;  
    }        
}          

片段着色器

precision mediump float;                                                        

varying vec3 vVertex, vNormal;
uniform mat4 uNormalMatrix;

void main(void)                         
{     
      vec3 lAmbient = vec3(0.3, 0.3, 1.0);
      vec3 lDiffuse = vec3(0.3, 0.3, 1.0);
      vec3 lSpecular= vec3(1.0, 1.0, 1.0);

      vec3 plPos = vec3(0.0, 8.0, 24.0);
      vec3 plDir = normalize(plPos - vVertex);

      vec3 n = normalize(vec3(uNormalMatrix * vec4(vNormal, 1.0)));
      vec3 l = normalize(vec3(vec4(plDir, 1.0)));
      vec3 v = normalize(-vec3(vec4(vVertex, 1.0)));
      vec3 r = reflect(l, n);

      float lambert = dot(l, n),
            ambientInt = 0.1,
            specularInt = 0.0,
            diffuseInt = 0.9,
            shininess = 1024.0;

      float specular = pow( max( 0.0, dot(r,v) ), shininess );

      gl_FragColor = vec4(lAmbient * ambientInt + lDiffuse * diffuseInt * lambert +
          lSpecular * specularInt * specular , 1.0);                                
}

0 个答案:

没有答案