我正在尝试使用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;
}
我正确的默认形状
变形的框架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);
}