Hi Raft,
I've spending few weeks to implemet hardware skinning, but I encountered few problems and I hope you could help me out on this
I've made these code, but the result seems incorrect:
vertex shader: skinPalette is hardcoded to match the bones file I have (im not sure if the number of matrix palettes is fixed).
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;
uniform vec4 additionalColor;
uniform vec4 ambientColor;
uniform float alpha;
uniform float shininess;
uniform bool useColors;
uniform float fogStart;
uniform float fogEnd;
uniform vec3 fogColor;
uniform int lightCount;
uniform mat4 skinPalette[7];
uniform vec3 lightPositions[8];
uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];
uniform float attenuation[8];
attribute vec4 position;
attribute vec3 normal;
attribute vec4 color;
attribute vec2 texture0;
attribute vec2 texture1;
attribute vec2 texture2;
attribute vec2 texture3;
attribute vec4 skinWeights;
attribute vec4 skinJointIndices;
varying vec2 texCoord[4];
varying vec4 vertexColor;
varying vec3 fogVertexColor;
varying float fogWeight;
const vec4 WHITE = vec4(1,1,1,1);
void main() {
texCoord[0] = texture0;
texCoord[1] = (textureMatrix * vec4(texture1, 0, 1)).xy;
texCoord[2] = texture2;
texCoord[3] = texture3;
vec4 myPosition = vec4(position);
vec3 myNormal = vec3(normal);
vec4 vertexTemp;
vec3 normalTemp;
mat4 mat;
for (int i = 0; i < 4; i++) {
mat = skinPalette[int(skinJointIndices[i])];
vertexTemp = mat * position;
vertexTemp *= skinWeights[i];
myPosition += vertexTemp;
normalTemp = normal * mat3(mat);
normalTemp *= skinWeights[i];
myNormal += normalTemp;
}
vec4 vertexPos = modelViewMatrix * myPosition;
vertexColor = ambientColor + additionalColor;
if (lightCount>0) {
// This is correct only if the modelview matrix is orthogonal. In jPCT-AE, it always is...unless you fiddle around with it.
vec3 normalEye = normalize(modelViewMatrix * vec4(myNormal, 0.0)).xyz;
float angle = dot(normalEye, normalize(lightPositions[0] - vertexPos.xyz));
if (angle > 0.0) {
vertexColor += vec4((diffuseColors[0] * angle + specularColors[0] * pow(angle, shininess))*(1.0/(1.0+length(lightPositions[0] - vertexPos.xyz)*attenuation[0])), 1);
}
// Freaky Adreno shader compiler can't handle loops without locking or creating garbage results....this is why the
// loop has been unrolled here. It's faster this way on PowerVR SGX540 too, even if PVRUniSCoEditor says otherwise...
if (lightCount>1) {
angle = dot(normalEye, normalize(lightPositions[1] - vertexPos.xyz));
if (angle > 0.0) {
vertexColor += vec4((diffuseColors[1] * angle + specularColors[1] * pow(angle, shininess))*(1.0/(1.0+length(lightPositions[1] - vertexPos.xyz)*attenuation[1])), 1);
}
}
}
if (fogStart != -1.0) {
fogWeight = clamp((-vertexPos.z - fogStart) / (fogEnd - fogStart), 0.0, 1.0);
fogVertexColor = fogColor * fogWeight;
} else {
fogWeight = -1.0;
}
vertexColor=vec4(min(WHITE, vertexColor).xyz, alpha);
if (useColors) {
vertexColor *= color;
}
gl_Position = modelViewProjectionMatrix * myPosition;
}
This's the code to add vertex attributes to shader. linearizeArray is converting float[][] to float[] and linearizeToFloatArray is short[][] to float[]
float[] f1 = SkinHelper.linearizeArray(skin.weights);
float[] f2 = SkinHelper.linearizeToFloatArray(skin.jointIndices);
skinWeights = new VertexAttributes(
"skinWeights", f1, VertexAttributes.TYPE_FOUR_FLOATS);
skinJointIndices = new VertexAttributes(
"skinJointIndices", f2, VertexAttributes.TYPE_FOUR_FLOATS);
Mesh mesh = getMesh();
mesh.addVertexAttributes(skinWeights);
mesh.addVertexAttributes(skinJointIndices);
This's where I set the uniform for matrix palette (in array form, Egon created a new GLSLShader to pass matrix array).
object3D.setRenderHook(new RenderHookAdapter(){
@Override
public void setCurrentShader(GLSLShader shader) {
super.setCurrentShader(shader);
shader.setUniform("skinPalette", object3D.getSkeletonPose().getPalette());
}
});
I tried to debug glsl and most debugger I tried were not working. Hope you could help me out on this. May be I missed something.